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