1#![allow(unused)]
2
3use crate::architecture::{Architecture, CoreArchitecture};
4use crate::calling_convention::CoreCallingConvention;
5use crate::rc::{Ref, RefCountable};
6use crate::types::Type;
7use binaryninjacore_sys::{
8 BNBoolWithConfidence, BNCallingConventionWithConfidence, BNGetCallingConventionArchitecture,
9 BNOffsetWithConfidence, BNTypeWithConfidence,
10};
11use std::fmt;
12use std::fmt::{Debug, Display, Formatter};
13use std::hash::{Hash, Hasher};
14
15pub const MIN_CONFIDENCE: u8 = u8::MIN;
17
18pub const MAX_CONFIDENCE: u8 = u8::MAX;
20
21pub struct Conf<T> {
23 pub contents: T,
24 pub confidence: u8,
25}
26
27pub trait ConfMergeable<T, O> {
28 type Result;
29 fn merge(self, other: O) -> Self::Result;
32}
33
34impl<T> Conf<T> {
35 pub fn new(contents: T, confidence: u8) -> Self {
36 Self {
37 contents,
38 confidence,
39 }
40 }
41
42 pub fn map<U, F>(self, f: F) -> Conf<U>
43 where
44 F: FnOnce(T) -> U,
45 {
46 Conf::new(f(self.contents), self.confidence)
47 }
48
49 pub fn as_ref<U>(&self) -> Conf<&U>
50 where
51 T: AsRef<U>,
52 {
53 Conf::new(self.contents.as_ref(), self.confidence)
54 }
55}
56
57impl<T> ConfMergeable<T, Conf<T>> for Conf<T> {
61 type Result = Conf<T>;
62 fn merge(self, other: Conf<T>) -> Conf<T> {
63 if other.confidence > self.confidence {
64 other
65 } else {
66 self
67 }
68 }
69}
70
71impl<T> ConfMergeable<T, Option<Conf<T>>> for Conf<T> {
75 type Result = Conf<T>;
76 fn merge(self, other: Option<Conf<T>>) -> Conf<T> {
77 match other {
78 Some(c @ Conf { confidence, .. }) if confidence > self.confidence => c,
79 _ => self,
80 }
81 }
82}
83
84impl<T> ConfMergeable<T, Conf<T>> for Option<Conf<T>> {
88 type Result = Conf<T>;
89 fn merge(self, other: Conf<T>) -> Conf<T> {
90 match self {
91 Some(c @ Conf { confidence, .. }) if confidence >= other.confidence => c,
92 _ => other,
93 }
94 }
95}
96
97impl<T> ConfMergeable<T, Option<Conf<T>>> for Option<Conf<T>> {
101 type Result = Option<Conf<T>>;
102 fn merge(self, other: Option<Conf<T>>) -> Option<Conf<T>> {
103 match (self, other) {
104 (
105 Some(
106 this @ Conf {
107 confidence: this_confidence,
108 ..
109 },
110 ),
111 Some(
112 other @ Conf {
113 confidence: other_confidence,
114 ..
115 },
116 ),
117 ) => {
118 if this_confidence >= other_confidence {
119 Some(this)
120 } else {
121 Some(other)
122 }
123 }
124 (None, Some(c)) => Some(c),
125 (Some(c), None) => Some(c),
126 (None, None) => None,
127 }
128 }
129}
130
131impl<T: Debug> Debug for Conf<T> {
132 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
133 write!(f, "{:?} ({} confidence)", self.contents, self.confidence)
134 }
135}
136
137impl<T: Display> Display for Conf<T> {
138 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
139 write!(f, "{} ({} confidence)", self.contents, self.confidence)
140 }
141}
142
143impl<T: PartialEq> PartialEq for Conf<T> {
144 fn eq(&self, other: &Self) -> bool {
145 self.contents.eq(&other.contents)
146 }
147}
148
149impl<T: Eq> Eq for Conf<T> {}
150
151impl<T: Hash> Hash for Conf<T> {
152 fn hash<H: Hasher>(&self, state: &mut H) {
153 self.contents.hash(state);
154 }
155}
156
157impl<'a, T> From<&'a Conf<T>> for Conf<&'a T> {
158 fn from(c: &'a Conf<T>) -> Self {
159 Conf::new(&c.contents, c.confidence)
160 }
161}
162
163impl<'a, T: RefCountable> From<&'a Conf<Ref<T>>> for Conf<&'a T> {
164 fn from(c: &'a Conf<Ref<T>>) -> Self {
165 Conf::new(c.contents.as_ref(), c.confidence)
166 }
167}
168
169impl<'a, T: RefCountable> From<&'a Ref<T>> for Conf<&'a T> {
170 fn from(r: &'a Ref<T>) -> Self {
171 r.as_ref().into()
172 }
173}
174
175impl<T: Clone> Clone for Conf<T> {
176 fn clone(&self) -> Self {
177 Self {
178 contents: self.contents.clone(),
179 confidence: self.confidence,
180 }
181 }
182}
183
184impl<T: Copy> Copy for Conf<T> {}
185
186impl<T> From<T> for Conf<T> {
187 fn from(contents: T) -> Self {
188 Self::new(contents, MAX_CONFIDENCE)
189 }
190}
191
192impl Conf<&'_ Type> {
193 pub(crate) fn into_raw(value: Self) -> BNTypeWithConfidence {
194 BNTypeWithConfidence {
195 type_: value.contents.handle,
196 confidence: value.confidence,
197 }
198 }
199}
200
201impl Conf<Ref<Type>> {
202 pub(crate) fn from_raw(value: &BNTypeWithConfidence) -> Self {
203 Self::new(
204 unsafe { Type::from_raw(value.type_) }.to_owned(),
205 value.confidence,
206 )
207 }
208
209 pub(crate) fn from_owned_raw(value: BNTypeWithConfidence) -> Self {
210 let owned = Self::from_raw(&value);
211 Self::free_raw(value);
212 owned
213 }
214
215 pub(crate) fn into_raw(value: Self) -> BNTypeWithConfidence {
216 BNTypeWithConfidence {
217 type_: unsafe { Ref::into_raw(value.contents) }.handle,
218 confidence: value.confidence,
219 }
220 }
221
222 pub(crate) fn free_raw(value: BNTypeWithConfidence) {
223 let _ = unsafe { Type::ref_from_raw(value.type_) };
224 }
225}
226
227impl Conf<Ref<CoreCallingConvention>> {
228 pub(crate) fn from_raw(value: &BNCallingConventionWithConfidence) -> Self {
229 let arch = unsafe {
230 CoreArchitecture::from_raw(BNGetCallingConventionArchitecture(value.convention))
231 };
232 Self::new(
233 unsafe { CoreCallingConvention::from_raw(value.convention, arch).to_owned() },
234 value.confidence,
235 )
236 }
237
238 pub(crate) fn from_owned_raw(value: BNCallingConventionWithConfidence) -> Self {
239 let owned = Self::from_raw(&value);
240 Self::free_raw(value);
241 owned
242 }
243}
244
245impl Conf<Ref<CoreCallingConvention>> {
246 pub(crate) fn into_raw(value: Self) -> BNCallingConventionWithConfidence {
247 BNCallingConventionWithConfidence {
248 convention: unsafe { Ref::into_raw(value.contents) }.handle,
249 confidence: value.confidence,
250 }
251 }
252
253 pub(crate) fn into_owned_raw(value: &Self) -> BNCallingConventionWithConfidence {
254 BNCallingConventionWithConfidence {
255 convention: value.contents.handle,
256 confidence: value.confidence,
257 }
258 }
259
260 pub(crate) fn free_raw(value: BNCallingConventionWithConfidence) {
261 let arch = unsafe {
262 CoreArchitecture::from_raw(BNGetCallingConventionArchitecture(value.convention))
263 };
264 let _ = unsafe { CoreCallingConvention::ref_from_raw(value.convention, arch) };
265 }
266}
267
268impl From<BNBoolWithConfidence> for Conf<bool> {
269 fn from(bool_with_confidence: BNBoolWithConfidence) -> Self {
270 Self::new(bool_with_confidence.value, bool_with_confidence.confidence)
271 }
272}
273
274impl From<BNOffsetWithConfidence> for Conf<i64> {
275 fn from(offset_with_confidence: BNOffsetWithConfidence) -> Self {
276 Self::new(
277 offset_with_confidence.value,
278 offset_with_confidence.confidence,
279 )
280 }
281}
282
283impl From<Conf<bool>> for BNBoolWithConfidence {
284 fn from(conf: Conf<bool>) -> Self {
285 Self {
286 value: conf.contents,
287 confidence: conf.confidence,
288 }
289 }
290}
291
292impl From<Conf<i64>> for BNOffsetWithConfidence {
293 fn from(conf: Conf<i64>) -> Self {
294 Self {
295 value: conf.contents,
296 confidence: conf.confidence,
297 }
298 }
299}