1#![allow(unused)]
15
16use binaryninjacore_sys::*;
21
22use crate::{
23 architecture::{Architecture, CoreArchitecture},
24 binary_view::{BinaryView, BinaryViewExt},
25 calling_convention::CoreCallingConvention,
26 rc::*,
27 string::{BnString, IntoCStr},
28};
29
30use crate::confidence::{Conf, MAX_CONFIDENCE, MIN_CONFIDENCE};
31use crate::string::{raw_to_string, strings_to_string_list};
32use crate::type_container::TypeContainer;
33use crate::variable::{Variable, VariableSourceType};
34use std::borrow::Cow;
35use std::num::NonZeroUsize;
36use std::ops::{Index, IndexMut};
37use std::{
38 collections::HashSet,
39 ffi::CStr,
40 fmt::{Debug, Display, Formatter},
41 hash::{Hash, Hasher},
42 iter::IntoIterator,
43};
44
45pub type StructureType = BNStructureVariant;
46pub type ReferenceType = BNReferenceType;
47pub type TypeClass = BNTypeClass;
48pub type NamedTypeReferenceClass = BNNamedTypeReferenceClass;
49pub type MemberAccess = BNMemberAccess;
50pub type MemberScope = BNMemberScope;
51pub type IntegerDisplayType = BNIntegerDisplayType;
52pub type PointerBaseType = BNPointerBaseType;
53
54#[derive(PartialEq, Eq, Hash)]
55pub struct TypeBuilder {
56 pub(crate) handle: *mut BNTypeBuilder,
57}
58
59impl TypeBuilder {
60 pub fn new(t: &Type) -> Self {
61 unsafe { Self::from_raw(BNCreateTypeBuilderFromType(t.handle)) }
62 }
63
64 pub(crate) unsafe fn from_raw(handle: *mut BNTypeBuilder) -> Self {
65 debug_assert!(!handle.is_null());
66 Self { handle }
67 }
68
69 pub fn finalize(&self) -> Ref<Type> {
71 unsafe { Type::ref_from_raw(BNFinalizeTypeBuilder(self.handle)) }
72 }
73
74 pub fn set_can_return<T: Into<Conf<bool>>>(&self, value: T) -> &Self {
77 let mut bool_with_confidence = value.into().into();
78 unsafe { BNSetFunctionTypeBuilderCanReturn(self.handle, &mut bool_with_confidence) };
79 self
80 }
81
82 pub fn set_pure<T: Into<Conf<bool>>>(&self, value: T) -> &Self {
83 let mut bool_with_confidence = value.into().into();
84 unsafe { BNSetTypeBuilderPure(self.handle, &mut bool_with_confidence) };
85 self
86 }
87
88 pub fn set_const<T: Into<Conf<bool>>>(&self, value: T) -> &Self {
89 let mut bool_with_confidence = value.into().into();
90 unsafe { BNTypeBuilderSetConst(self.handle, &mut bool_with_confidence) };
91 self
92 }
93
94 pub fn set_volatile<T: Into<Conf<bool>>>(&self, value: T) -> &Self {
95 let mut bool_with_confidence = value.into().into();
96 unsafe { BNTypeBuilderSetVolatile(self.handle, &mut bool_with_confidence) };
97 self
98 }
99
100 pub fn set_pointer_base(&self, base_type: PointerBaseType, base_offset: i64) -> &Self {
101 unsafe { BNSetTypeBuilderPointerBase(self.handle, base_type, base_offset) }
102 self
103 }
104
105 pub fn set_child_type<'a, T: Into<Conf<&'a Type>>>(&self, ty: T) -> &Self {
106 let mut type_with_confidence = Conf::<&Type>::into_raw(ty.into());
107 unsafe { BNTypeBuilderSetChildType(self.handle, &mut type_with_confidence) };
108 self
109 }
110
111 pub fn set_target<'a, T: Into<Conf<&'a Type>>>(&self, ty: T) -> &Self {
113 self.set_child_type(ty)
114 }
115
116 pub fn set_element_type<'a, T: Into<Conf<&'a Type>>>(&self, ty: T) -> &Self {
118 self.set_child_type(ty)
119 }
120
121 pub fn set_return_value<'a, T: Into<Conf<&'a Type>>>(&self, ty: T) -> &Self {
123 self.set_child_type(ty)
124 }
125
126 pub fn type_class(&self) -> TypeClass {
129 unsafe { BNGetTypeBuilderClass(self.handle) }
130 }
131
132 pub fn width(&self) -> u64 {
133 unsafe { BNGetTypeBuilderWidth(self.handle) }
134 }
135
136 pub fn alignment(&self) -> usize {
137 unsafe { BNGetTypeBuilderAlignment(self.handle) }
138 }
139
140 pub fn is_signed(&self) -> Conf<bool> {
141 unsafe { BNIsTypeBuilderSigned(self.handle).into() }
142 }
143
144 pub fn is_const(&self) -> Conf<bool> {
145 unsafe { BNIsTypeBuilderConst(self.handle).into() }
146 }
147
148 pub fn is_volatile(&self) -> Conf<bool> {
149 unsafe { BNIsTypeBuilderVolatile(self.handle).into() }
150 }
151
152 pub fn is_floating_point(&self) -> bool {
153 unsafe { BNIsTypeBuilderFloatingPoint(self.handle) }
154 }
155
156 pub fn child_type(&self) -> Option<Conf<Ref<Type>>> {
157 let raw_target = unsafe { BNGetTypeBuilderChildType(self.handle) };
158 match raw_target.type_.is_null() {
159 false => Some(Conf::<Ref<Type>>::from_owned_raw(raw_target)),
160 true => None,
161 }
162 }
163
164 pub fn target(&self) -> Option<Conf<Ref<Type>>> {
166 self.child_type()
167 }
168
169 pub fn element_type(&self) -> Option<Conf<Ref<Type>>> {
171 self.child_type()
172 }
173
174 pub fn return_value(&self) -> Option<Conf<Ref<Type>>> {
176 self.child_type()
177 }
178
179 pub fn calling_convention(&self) -> Option<Conf<Ref<CoreCallingConvention>>> {
180 let raw_convention_confidence = unsafe { BNGetTypeBuilderCallingConvention(self.handle) };
181 match raw_convention_confidence.convention.is_null() {
182 false => Some(Conf::<Ref<CoreCallingConvention>>::from_owned_raw(
183 raw_convention_confidence,
184 )),
185 true => None,
186 }
187 }
188
189 pub fn parameters(&self) -> Option<Vec<FunctionParameter>> {
190 unsafe {
191 let mut count = 0;
192 let raw_parameters_ptr = BNGetTypeBuilderParameters(self.handle, &mut count);
193 match raw_parameters_ptr.is_null() {
194 false => {
195 let raw_parameters = std::slice::from_raw_parts(raw_parameters_ptr, count);
196 let parameters = raw_parameters
197 .iter()
198 .map(FunctionParameter::from_raw)
199 .collect();
200 BNFreeTypeParameterList(raw_parameters_ptr, count);
201 Some(parameters)
202 }
203 true => None,
204 }
205 }
206 }
207
208 pub fn has_variable_arguments(&self) -> Conf<bool> {
209 unsafe { BNTypeBuilderHasVariableArguments(self.handle).into() }
210 }
211
212 pub fn can_return(&self) -> Conf<bool> {
213 unsafe { BNFunctionTypeBuilderCanReturn(self.handle).into() }
214 }
215
216 pub fn pure(&self) -> Conf<bool> {
217 unsafe { BNIsTypeBuilderPure(self.handle).into() }
218 }
219
220 pub fn get_structure(&self) -> Option<Ref<Structure>> {
223 let raw_struct_ptr = unsafe { BNGetTypeBuilderStructure(self.handle) };
224 match raw_struct_ptr.is_null() {
225 false => Some(unsafe { Structure::ref_from_raw(raw_struct_ptr) }),
226 true => None,
227 }
228 }
229
230 pub fn get_enumeration(&self) -> Option<Ref<Enumeration>> {
233 let raw_enum_ptr = unsafe { BNGetTypeBuilderEnumeration(self.handle) };
234 match raw_enum_ptr.is_null() {
235 false => Some(unsafe { Enumeration::ref_from_raw(raw_enum_ptr) }),
236 true => None,
237 }
238 }
239
240 pub fn get_named_type_reference(&self) -> Option<Ref<NamedTypeReference>> {
243 let raw_type_ref_ptr = unsafe { BNGetTypeBuilderNamedTypeReference(self.handle) };
244 match raw_type_ref_ptr.is_null() {
245 false => Some(unsafe { NamedTypeReference::ref_from_raw(raw_type_ref_ptr) }),
246 true => None,
247 }
248 }
249
250 pub fn count(&self) -> u64 {
251 unsafe { BNGetTypeBuilderElementCount(self.handle) }
252 }
253
254 pub fn offset(&self) -> u64 {
255 unsafe { BNGetTypeBuilderOffset(self.handle) }
256 }
257
258 pub fn stack_adjustment(&self) -> Conf<i64> {
259 unsafe { BNGetTypeBuilderStackAdjustment(self.handle).into() }
260 }
261
262 pub fn pointer_base_type(&self) -> PointerBaseType {
263 unsafe { BNTypeBuilderGetPointerBaseType(self.handle) }
264 }
265
266 pub fn pointer_base_offset(&self) -> i64 {
267 unsafe { BNTypeBuilderGetPointerBaseOffset(self.handle) }
268 }
269
270 pub fn void() -> Self {
274 unsafe { Self::from_raw(BNCreateVoidTypeBuilder()) }
275 }
276
277 pub fn bool() -> Self {
278 unsafe { Self::from_raw(BNCreateBoolTypeBuilder()) }
279 }
280
281 pub fn char() -> Self {
282 Self::int(1, true)
283 }
284
285 pub fn int(width: usize, is_signed: bool) -> Self {
286 let mut is_signed = Conf::new(is_signed, MAX_CONFIDENCE).into();
287
288 unsafe {
289 Self::from_raw(BNCreateIntegerTypeBuilder(
290 width,
291 &mut is_signed,
292 BnString::new("").as_ptr() as *mut _,
293 ))
294 }
295 }
296
297 pub fn named_int(width: usize, is_signed: bool, alt_name: &str) -> Self {
298 let mut is_signed = Conf::new(is_signed, MAX_CONFIDENCE).into();
299 let alt_name = alt_name.to_cstr(); unsafe {
303 Self::from_raw(BNCreateIntegerTypeBuilder(
304 width,
305 &mut is_signed,
306 alt_name.as_ref().as_ptr() as _,
307 ))
308 }
309 }
310
311 pub fn float(width: usize) -> Self {
312 unsafe { Self::from_raw(BNCreateFloatTypeBuilder(width, c"".as_ptr())) }
313 }
314
315 pub fn named_float(width: usize, alt_name: &str) -> Self {
316 let alt_name = alt_name.to_cstr();
317 unsafe { Self::from_raw(BNCreateFloatTypeBuilder(width, alt_name.as_ptr())) }
318 }
319
320 pub fn array<'a, T: Into<Conf<&'a Type>>>(ty: T, count: u64) -> Self {
321 let owned_raw_ty = Conf::<&Type>::into_raw(ty.into());
322 unsafe { Self::from_raw(BNCreateArrayTypeBuilder(&owned_raw_ty, count)) }
323 }
324
325 pub fn enumeration<T: Into<Conf<bool>>>(
331 enumeration: &Enumeration,
332 width: NonZeroUsize,
333 is_signed: T,
334 ) -> Self {
335 unsafe {
336 Self::from_raw(BNCreateEnumerationTypeBuilder(
337 std::ptr::null_mut(),
339 enumeration.handle,
340 width.get(),
341 &mut is_signed.into().into(),
342 ))
343 }
344 }
345
346 pub fn structure(structure_type: &Structure) -> Self {
347 unsafe { Self::from_raw(BNCreateStructureTypeBuilder(structure_type.handle)) }
348 }
349
350 pub fn named_type(type_reference: NamedTypeReference) -> Self {
351 let mut is_const = Conf::new(false, MIN_CONFIDENCE).into();
352 let mut is_volatile = Conf::new(false, MIN_CONFIDENCE).into();
353 unsafe {
354 Self::from_raw(BNCreateNamedTypeReferenceBuilder(
355 type_reference.handle,
356 0,
357 1,
358 &mut is_const,
359 &mut is_volatile,
360 ))
361 }
362 }
363
364 pub fn named_type_from_type<T: Into<QualifiedName>>(name: T, t: &Type) -> Self {
365 let mut raw_name = QualifiedName::into_raw(name.into());
366 let id = c"";
367
368 let result = unsafe {
369 Self::from_raw(BNCreateNamedTypeReferenceBuilderFromTypeAndId(
370 id.as_ptr() as *mut _,
371 &mut raw_name,
372 t.handle,
373 ))
374 };
375 QualifiedName::free_raw(raw_name);
376 result
377 }
378
379 pub fn pointer<'a, A: Architecture, T: Into<Conf<&'a Type>>>(arch: &A, ty: T) -> Self {
382 let mut is_const = Conf::new(false, MIN_CONFIDENCE).into();
383 let mut is_volatile = Conf::new(false, MIN_CONFIDENCE).into();
384 let owned_raw_ty = Conf::<&Type>::into_raw(ty.into());
385 unsafe {
386 Self::from_raw(BNCreatePointerTypeBuilder(
387 arch.as_ref().handle,
388 &owned_raw_ty,
389 &mut is_const,
390 &mut is_volatile,
391 ReferenceType::PointerReferenceType,
392 ))
393 }
394 }
395
396 pub fn const_pointer<'a, A: Architecture, T: Into<Conf<&'a Type>>>(arch: &A, ty: T) -> Self {
397 let mut is_const = Conf::new(true, MAX_CONFIDENCE).into();
398 let mut is_volatile = Conf::new(false, MIN_CONFIDENCE).into();
399 let owned_raw_ty = Conf::<&Type>::into_raw(ty.into());
400 unsafe {
401 Self::from_raw(BNCreatePointerTypeBuilder(
402 arch.as_ref().handle,
403 &owned_raw_ty,
404 &mut is_const,
405 &mut is_volatile,
406 ReferenceType::PointerReferenceType,
407 ))
408 }
409 }
410
411 pub fn pointer_of_width<'a, T: Into<Conf<&'a Type>>>(
412 ty: T,
413 size: usize,
414 is_const: bool,
415 is_volatile: bool,
416 ref_type: Option<ReferenceType>,
417 ) -> Self {
418 let mut is_const = Conf::new(is_const, MAX_CONFIDENCE).into();
419 let mut is_volatile = Conf::new(is_volatile, MAX_CONFIDENCE).into();
420 let owned_raw_ty = Conf::<&Type>::into_raw(ty.into());
421 unsafe {
422 Self::from_raw(BNCreatePointerTypeBuilderOfWidth(
423 size,
424 &owned_raw_ty,
425 &mut is_const,
426 &mut is_volatile,
427 ref_type.unwrap_or(ReferenceType::PointerReferenceType),
428 ))
429 }
430 }
431
432 pub fn pointer_with_options<'a, A: Architecture, T: Into<Conf<&'a Type>>>(
433 arch: &A,
434 ty: T,
435 is_const: bool,
436 is_volatile: bool,
437 ref_type: Option<ReferenceType>,
438 ) -> Self {
439 let mut is_const = Conf::new(is_const, MAX_CONFIDENCE).into();
440 let mut is_volatile = Conf::new(is_volatile, MAX_CONFIDENCE).into();
441 let owned_raw_ty = Conf::<&Type>::into_raw(ty.into());
442 unsafe {
443 Self::from_raw(BNCreatePointerTypeBuilder(
444 arch.as_ref().handle,
445 &owned_raw_ty,
446 &mut is_const,
447 &mut is_volatile,
448 ref_type.unwrap_or(ReferenceType::PointerReferenceType),
449 ))
450 }
451 }
452}
453
454impl Display for TypeBuilder {
455 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
456 write!(f, "{}", unsafe {
457 BnString::into_string(BNGetTypeBuilderString(self.handle, std::ptr::null_mut()))
458 })
459 }
460}
461
462impl Drop for TypeBuilder {
463 fn drop(&mut self) {
464 unsafe { BNFreeTypeBuilder(self.handle) };
465 }
466}
467
468#[repr(transparent)]
469pub struct Type {
470 pub handle: *mut BNType,
471}
472
473impl Type {
483 pub unsafe fn from_raw(handle: *mut BNType) -> Self {
484 debug_assert!(!handle.is_null());
485 Self { handle }
486 }
487
488 pub unsafe fn ref_from_raw(handle: *mut BNType) -> Ref<Self> {
489 debug_assert!(!handle.is_null());
490 Ref::new(Self { handle })
491 }
492
493 pub fn to_builder(&self) -> TypeBuilder {
494 TypeBuilder::new(self)
495 }
496
497 pub fn type_class(&self) -> TypeClass {
498 unsafe { BNGetTypeClass(self.handle) }
499 }
500
501 pub fn width(&self) -> u64 {
504 unsafe { BNGetTypeWidth(self.handle) }
505 }
506
507 pub fn alignment(&self) -> usize {
508 unsafe { BNGetTypeAlignment(self.handle) }
509 }
510
511 pub fn is_signed(&self) -> Conf<bool> {
512 unsafe { BNIsTypeSigned(self.handle).into() }
513 }
514
515 pub fn is_const(&self) -> Conf<bool> {
516 unsafe { BNIsTypeConst(self.handle).into() }
517 }
518
519 pub fn is_volatile(&self) -> Conf<bool> {
520 unsafe { BNIsTypeVolatile(self.handle).into() }
521 }
522
523 pub fn is_floating_point(&self) -> bool {
524 unsafe { BNIsTypeFloatingPoint(self.handle) }
525 }
526
527 pub fn child_type(&self) -> Option<Conf<Ref<Type>>> {
528 let raw_target = unsafe { BNGetChildType(self.handle) };
529 match raw_target.type_.is_null() {
530 false => Some(Conf::<Ref<Type>>::from_owned_raw(raw_target)),
531 true => None,
532 }
533 }
534
535 pub fn target(&self) -> Option<Conf<Ref<Type>>> {
537 self.child_type()
538 }
539
540 pub fn element_type(&self) -> Option<Conf<Ref<Type>>> {
542 self.child_type()
543 }
544
545 pub fn return_value(&self) -> Option<Conf<Ref<Type>>> {
547 self.child_type()
548 }
549
550 pub fn calling_convention(&self) -> Option<Conf<Ref<CoreCallingConvention>>> {
551 let convention_confidence = unsafe { BNGetTypeCallingConvention(self.handle) };
552 match convention_confidence.convention.is_null() {
553 false => Some(Conf::<Ref<CoreCallingConvention>>::from_owned_raw(
554 convention_confidence,
555 )),
556 true => None,
557 }
558 }
559
560 pub fn parameters(&self) -> Option<Vec<FunctionParameter>> {
561 unsafe {
562 let mut count = 0;
563 let raw_parameters_ptr = BNGetTypeParameters(self.handle, &mut count);
564 match raw_parameters_ptr.is_null() {
565 false => {
566 let raw_parameters = std::slice::from_raw_parts(raw_parameters_ptr, count);
567 let parameters = raw_parameters
568 .iter()
569 .map(FunctionParameter::from_raw)
570 .collect();
571 BNFreeTypeParameterList(raw_parameters_ptr, count);
572 Some(parameters)
573 }
574 true => None,
575 }
576 }
577 }
578
579 pub fn has_variable_arguments(&self) -> Conf<bool> {
580 unsafe { BNTypeHasVariableArguments(self.handle).into() }
581 }
582
583 pub fn can_return(&self) -> Conf<bool> {
584 unsafe { BNFunctionTypeCanReturn(self.handle).into() }
585 }
586
587 pub fn pure(&self) -> Conf<bool> {
588 unsafe { BNIsTypePure(self.handle).into() }
589 }
590
591 pub fn get_structure(&self) -> Option<Ref<Structure>> {
594 let raw_struct_ptr = unsafe { BNGetTypeStructure(self.handle) };
595 match raw_struct_ptr.is_null() {
596 false => Some(unsafe { Structure::ref_from_raw(raw_struct_ptr) }),
597 true => None,
598 }
599 }
600
601 pub fn get_enumeration(&self) -> Option<Ref<Enumeration>> {
604 let raw_enum_ptr = unsafe { BNGetTypeEnumeration(self.handle) };
605 match raw_enum_ptr.is_null() {
606 false => Some(unsafe { Enumeration::ref_from_raw(raw_enum_ptr) }),
607 true => None,
608 }
609 }
610
611 pub fn get_named_type_reference(&self) -> Option<Ref<NamedTypeReference>> {
614 let raw_type_ref_ptr = unsafe { BNGetTypeNamedTypeReference(self.handle) };
615 match raw_type_ref_ptr.is_null() {
616 false => Some(unsafe { NamedTypeReference::ref_from_raw(raw_type_ref_ptr) }),
617 true => None,
618 }
619 }
620
621 pub fn count(&self) -> u64 {
622 unsafe { BNGetTypeElementCount(self.handle) }
623 }
624
625 pub fn offset(&self) -> u64 {
626 unsafe { BNGetTypeOffset(self.handle) }
627 }
628
629 pub fn stack_adjustment(&self) -> Conf<i64> {
630 unsafe { BNGetTypeStackAdjustment(self.handle).into() }
631 }
632
633 pub fn registered_name(&self) -> Option<Ref<NamedTypeReference>> {
634 let raw_type_ref_ptr = unsafe { BNGetRegisteredTypeName(self.handle) };
635 match raw_type_ref_ptr.is_null() {
636 false => Some(unsafe { NamedTypeReference::ref_from_raw(raw_type_ref_ptr) }),
637 true => None,
638 }
639 }
640
641 pub fn pointer_base_type(&self) -> BNPointerBaseType {
642 unsafe { BNTypeGetPointerBaseType(self.handle) }
643 }
644
645 pub fn pointer_base_offset(&self) -> i64 {
646 unsafe { BNTypeGetPointerBaseOffset(self.handle) }
647 }
648
649 pub fn void() -> Ref<Self> {
653 unsafe { Self::ref_from_raw(BNCreateVoidType()) }
654 }
655
656 pub fn bool() -> Ref<Self> {
657 unsafe { Self::ref_from_raw(BNCreateBoolType()) }
658 }
659
660 pub fn char() -> Ref<Self> {
661 Self::int(1, true)
662 }
663
664 pub fn wide_char(width: usize) -> Ref<Self> {
665 unsafe { Self::ref_from_raw(BNCreateWideCharType(width, c"".as_ptr())) }
666 }
667
668 pub fn int(width: usize, is_signed: bool) -> Ref<Self> {
669 let mut is_signed = Conf::new(is_signed, MAX_CONFIDENCE).into();
670 unsafe { Self::ref_from_raw(BNCreateIntegerType(width, &mut is_signed, c"".as_ptr())) }
671 }
672
673 pub fn named_int(width: usize, is_signed: bool, alt_name: &str) -> Ref<Self> {
674 let mut is_signed = Conf::new(is_signed, MAX_CONFIDENCE).into();
675 let alt_name = alt_name.to_cstr();
676
677 unsafe {
678 Self::ref_from_raw(BNCreateIntegerType(
679 width,
680 &mut is_signed,
681 alt_name.as_ptr(),
682 ))
683 }
684 }
685
686 pub fn float(width: usize) -> Ref<Self> {
687 unsafe { Self::ref_from_raw(BNCreateFloatType(width, c"".as_ptr())) }
688 }
689
690 pub fn named_float(width: usize, alt_name: &str) -> Ref<Self> {
691 let alt_name = alt_name.to_cstr();
692 unsafe { Self::ref_from_raw(BNCreateFloatType(width, alt_name.as_ptr())) }
693 }
694
695 pub fn array<'a, T: Into<Conf<&'a Type>>>(ty: T, count: u64) -> Ref<Self> {
696 let owned_raw_ty = Conf::<&Type>::into_raw(ty.into());
697 unsafe { Self::ref_from_raw(BNCreateArrayType(&owned_raw_ty, count)) }
698 }
699
700 pub fn enumeration<T: Into<Conf<bool>>>(
706 enumeration: &Enumeration,
707 width: NonZeroUsize,
708 is_signed: T,
709 ) -> Ref<Self> {
710 unsafe {
711 Self::ref_from_raw(BNCreateEnumerationType(
712 std::ptr::null_mut(),
714 enumeration.handle,
715 width.get(),
716 &mut is_signed.into().into(),
717 ))
718 }
719 }
720
721 pub fn structure(structure: &Structure) -> Ref<Self> {
722 unsafe { Self::ref_from_raw(BNCreateStructureType(structure.handle)) }
723 }
724
725 pub fn named_type(type_reference: &NamedTypeReference) -> Ref<Self> {
726 let mut is_const = Conf::new(false, MIN_CONFIDENCE).into();
727 let mut is_volatile = Conf::new(false, MIN_CONFIDENCE).into();
728 unsafe {
729 Self::ref_from_raw(BNCreateNamedTypeReference(
730 type_reference.handle,
731 0,
732 1,
733 &mut is_const,
734 &mut is_volatile,
735 ))
736 }
737 }
738
739 pub fn named_type_from_type<T: Into<QualifiedName>>(name: T, t: &Type) -> Ref<Self> {
740 let mut raw_name = QualifiedName::into_raw(name.into());
741 let id = c"";
743
744 let result = unsafe {
745 Self::ref_from_raw(BNCreateNamedTypeReferenceFromTypeAndId(
746 id.as_ptr(),
747 &mut raw_name,
748 t.handle,
749 ))
750 };
751 QualifiedName::free_raw(raw_name);
752 result
753 }
754
755 pub fn function<'a, T: Into<Conf<&'a Type>>>(
757 return_type: T,
758 parameters: Vec<FunctionParameter>,
759 variable_arguments: bool,
760 ) -> Ref<Self> {
761 let mut owned_raw_return_type = Conf::<&Type>::into_raw(return_type.into());
762 let mut variable_arguments = Conf::new(variable_arguments, MAX_CONFIDENCE).into();
763 let mut can_return = Conf::new(true, MIN_CONFIDENCE).into();
764 let mut pure = Conf::new(false, MIN_CONFIDENCE).into();
765
766 let mut raw_calling_convention: BNCallingConventionWithConfidence =
767 BNCallingConventionWithConfidence {
768 convention: std::ptr::null_mut(),
769 confidence: MIN_CONFIDENCE,
770 };
771
772 let mut stack_adjust = Conf::new(0, MIN_CONFIDENCE).into();
773 let mut raw_parameters = parameters
774 .into_iter()
775 .map(FunctionParameter::into_raw)
776 .collect::<Vec<_>>();
777 let reg_stack_adjust_regs = std::ptr::null_mut();
778 let reg_stack_adjust_values = std::ptr::null_mut();
779
780 let mut return_regs: BNRegisterSetWithConfidence = BNRegisterSetWithConfidence {
781 regs: std::ptr::null_mut(),
782 count: 0,
783 confidence: 0,
784 };
785
786 let result = unsafe {
787 Self::ref_from_raw(BNCreateFunctionType(
788 &mut owned_raw_return_type,
789 &mut raw_calling_convention,
790 raw_parameters.as_mut_ptr(),
791 raw_parameters.len(),
792 &mut variable_arguments,
793 &mut can_return,
794 &mut stack_adjust,
795 reg_stack_adjust_regs,
796 reg_stack_adjust_values,
797 0,
798 &mut return_regs,
799 BNNameType::NoNameType,
800 &mut pure,
801 ))
802 };
803
804 for raw_param in raw_parameters {
805 FunctionParameter::free_raw(raw_param);
806 }
807
808 result
809 }
810
811 pub fn function_with_opts<
813 'a,
814 T: Into<Conf<&'a Type>>,
815 C: Into<Conf<Ref<CoreCallingConvention>>>,
816 >(
817 return_type: T,
818 parameters: &[FunctionParameter],
819 variable_arguments: bool,
820 calling_convention: C,
821 stack_adjust: Conf<i64>,
822 ) -> Ref<Self> {
823 let mut owned_raw_return_type = Conf::<&Type>::into_raw(return_type.into());
824 let mut variable_arguments = Conf::new(variable_arguments, MAX_CONFIDENCE).into();
825 let mut can_return = Conf::new(true, MIN_CONFIDENCE).into();
826 let mut pure = Conf::new(false, MIN_CONFIDENCE).into();
827
828 let mut owned_raw_calling_convention =
829 Conf::<Ref<CoreCallingConvention>>::into_owned_raw(&calling_convention.into());
830
831 let mut stack_adjust = stack_adjust.into();
832 let mut raw_parameters = parameters
833 .iter()
834 .cloned()
835 .map(FunctionParameter::into_raw)
836 .collect::<Vec<_>>();
837
838 let reg_stack_adjust_regs = std::ptr::null_mut();
840 let reg_stack_adjust_values = std::ptr::null_mut();
841
842 let mut return_regs: BNRegisterSetWithConfidence = BNRegisterSetWithConfidence {
843 regs: std::ptr::null_mut(),
844 count: 0,
845 confidence: 0,
846 };
847
848 let result = unsafe {
849 Self::ref_from_raw(BNCreateFunctionType(
850 &mut owned_raw_return_type,
851 &mut owned_raw_calling_convention,
852 raw_parameters.as_mut_ptr(),
853 raw_parameters.len(),
854 &mut variable_arguments,
855 &mut can_return,
856 &mut stack_adjust,
857 reg_stack_adjust_regs,
858 reg_stack_adjust_values,
859 0,
860 &mut return_regs,
861 BNNameType::NoNameType,
862 &mut pure,
863 ))
864 };
865
866 for raw_param in raw_parameters {
867 FunctionParameter::free_raw(raw_param);
868 }
869
870 result
871 }
872
873 pub fn pointer<'a, A: Architecture, T: Into<Conf<&'a Type>>>(arch: &A, ty: T) -> Ref<Self> {
874 let mut is_const = Conf::new(false, MIN_CONFIDENCE).into();
875 let mut is_volatile = Conf::new(false, MIN_CONFIDENCE).into();
876 let owned_raw_ty = Conf::<&Type>::into_raw(ty.into());
877 unsafe {
878 Self::ref_from_raw(BNCreatePointerType(
879 arch.as_ref().handle,
880 &owned_raw_ty,
881 &mut is_const,
882 &mut is_volatile,
883 ReferenceType::PointerReferenceType,
884 ))
885 }
886 }
887
888 pub fn const_pointer<'a, A: Architecture, T: Into<Conf<&'a Type>>>(
889 arch: &A,
890 ty: T,
891 ) -> Ref<Self> {
892 let mut is_const = Conf::new(true, MAX_CONFIDENCE).into();
893 let mut is_volatile = Conf::new(false, MIN_CONFIDENCE).into();
894 let owned_raw_ty = Conf::<&Type>::into_raw(ty.into());
895 unsafe {
896 Self::ref_from_raw(BNCreatePointerType(
897 arch.as_ref().handle,
898 &owned_raw_ty,
899 &mut is_const,
900 &mut is_volatile,
901 ReferenceType::PointerReferenceType,
902 ))
903 }
904 }
905
906 pub fn pointer_of_width<'a, T: Into<Conf<&'a Type>>>(
907 ty: T,
908 size: usize,
909 is_const: bool,
910 is_volatile: bool,
911 ref_type: Option<ReferenceType>,
912 ) -> Ref<Self> {
913 let mut is_const = Conf::new(is_const, MAX_CONFIDENCE).into();
914 let mut is_volatile = Conf::new(is_volatile, MAX_CONFIDENCE).into();
915 let owned_raw_ty = Conf::<&Type>::into_raw(ty.into());
916 unsafe {
917 Self::ref_from_raw(BNCreatePointerTypeOfWidth(
918 size,
919 &owned_raw_ty,
920 &mut is_const,
921 &mut is_volatile,
922 ref_type.unwrap_or(ReferenceType::PointerReferenceType),
923 ))
924 }
925 }
926
927 pub fn pointer_with_options<'a, A: Architecture, T: Into<Conf<&'a Type>>>(
928 arch: &A,
929 ty: T,
930 is_const: bool,
931 is_volatile: bool,
932 ref_type: Option<ReferenceType>,
933 ) -> Ref<Self> {
934 let mut is_const = Conf::new(is_const, MAX_CONFIDENCE).into();
935 let mut is_volatile = Conf::new(is_volatile, MAX_CONFIDENCE).into();
936 let owned_raw_ty = Conf::<&Type>::into_raw(ty.into());
937 unsafe {
938 Self::ref_from_raw(BNCreatePointerType(
939 arch.as_ref().handle,
940 &owned_raw_ty,
941 &mut is_const,
942 &mut is_volatile,
943 ref_type.unwrap_or(ReferenceType::PointerReferenceType),
944 ))
945 }
946 }
947
948 pub fn generate_auto_demangled_type_id<T: Into<QualifiedName>>(name: T) -> String {
949 let mut raw_name = QualifiedName::into_raw(name.into());
950 let type_id =
951 unsafe { BnString::into_string(BNGenerateAutoDemangledTypeId(&mut raw_name)) };
952 QualifiedName::free_raw(raw_name);
953 type_id
954 }
955}
956
957impl Display for Type {
958 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
959 write!(f, "{}", unsafe {
960 BnString::into_string(BNGetTypeString(
961 self.handle,
962 std::ptr::null_mut(),
963 BNTokenEscapingType::NoTokenEscapingType,
964 ))
965 })
966 }
967}
968
969impl Debug for Type {
970 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
971 f.debug_struct("Type")
976 .field("type_class", &self.type_class())
977 .field("width", &self.width())
978 .field("alignment", &self.alignment())
979 .field("is_signed", &self.is_signed())
980 .field("is_const", &self.is_const())
981 .field("is_volatile", &self.is_volatile())
982 .field("child_type", &self.child_type())
983 .field("calling_convention", &self.calling_convention())
984 .field("parameters", &self.parameters())
985 .field("has_variable_arguments", &self.has_variable_arguments())
986 .field("can_return", &self.can_return())
987 .field("pure", &self.pure())
988 .field("get_structure", &self.get_structure())
989 .field("get_enumeration", &self.get_enumeration())
990 .field("get_named_type_reference", &self.get_named_type_reference())
991 .field("count", &self.count())
992 .field("offset", &self.offset())
993 .field("stack_adjustment", &self.stack_adjustment())
994 .field("registered_name", &self.registered_name())
995 .finish()
996 }
997}
998
999impl PartialEq for Type {
1000 fn eq(&self, other: &Self) -> bool {
1001 unsafe { BNTypesEqual(self.handle, other.handle) }
1002 }
1003}
1004
1005impl Eq for Type {}
1006
1007impl Hash for Type {
1008 fn hash<H: Hasher>(&self, state: &mut H) {
1009 self.handle.hash(state);
1010 }
1011}
1012
1013unsafe impl Send for Type {}
1014unsafe impl Sync for Type {}
1015
1016unsafe impl RefCountable for Type {
1017 unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
1018 Self::ref_from_raw(BNNewTypeReference(handle.handle))
1019 }
1020
1021 unsafe fn dec_ref(handle: &Self) {
1022 BNFreeType(handle.handle);
1023 }
1024}
1025
1026impl ToOwned for Type {
1027 type Owned = Ref<Self>;
1028
1029 fn to_owned(&self) -> Self::Owned {
1030 unsafe { RefCountable::inc_ref(self) }
1031 }
1032}
1033
1034impl CoreArrayProvider for Type {
1035 type Raw = *mut BNType;
1036 type Context = ();
1037 type Wrapped<'a> = &'a Self;
1038}
1039
1040unsafe impl CoreArrayProviderInner for Type {
1041 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
1042 BNFreeTypeList(raw, count)
1043 }
1044
1045 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
1046 std::mem::transmute(raw)
1048 }
1049}
1050
1051pub struct ComponentReferencedType;
1054
1055impl CoreArrayProvider for ComponentReferencedType {
1056 type Raw = *mut BNType;
1057 type Context = ();
1058 type Wrapped<'a> = &'a Type;
1059}
1060
1061unsafe impl CoreArrayProviderInner for ComponentReferencedType {
1062 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
1063 BNComponentFreeReferencedTypes(raw, count)
1064 }
1065
1066 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
1067 std::mem::transmute(raw)
1069 }
1070}
1071
1072#[derive(Debug, Clone, Hash, PartialEq, Eq)]
1073pub struct FunctionParameter {
1074 pub ty: Conf<Ref<Type>>,
1075 pub name: String,
1076 pub location: Option<Variable>,
1077}
1078
1079impl FunctionParameter {
1080 pub(crate) fn from_raw(value: &BNFunctionParameter) -> Self {
1081 let name = if value.name.is_null() {
1084 if value.location.type_ == VariableSourceType::RegisterVariableSourceType {
1085 format!("reg_{}", value.location.storage)
1086 } else if value.location.type_ == VariableSourceType::StackVariableSourceType {
1087 format!("arg_{}", value.location.storage)
1088 } else {
1089 String::new()
1090 }
1091 } else {
1092 raw_to_string(value.name as *const _).unwrap()
1093 };
1094
1095 Self {
1096 ty: Conf::new(
1097 unsafe { Type::from_raw(value.type_).to_owned() },
1098 value.typeConfidence,
1099 ),
1100 name,
1101 location: match value.defaultLocation {
1102 false => Some(Variable::from(value.location)),
1103 true => None,
1104 },
1105 }
1106 }
1107
1108 pub(crate) fn from_owned_raw(value: BNFunctionParameter) -> Self {
1109 let owned = Self::from_raw(&value);
1110 Self::free_raw(value);
1111 owned
1112 }
1113
1114 pub(crate) fn into_raw(value: Self) -> BNFunctionParameter {
1115 let bn_name = BnString::new(value.name);
1116 BNFunctionParameter {
1117 name: BnString::into_raw(bn_name),
1118 type_: unsafe { Ref::into_raw(value.ty.contents) }.handle,
1119 typeConfidence: value.ty.confidence,
1120 defaultLocation: value.location.is_none(),
1121 location: value.location.map(Into::into).unwrap_or_default(),
1122 }
1123 }
1124
1125 pub(crate) fn free_raw(value: BNFunctionParameter) {
1126 unsafe { BnString::free_raw(value.name) };
1127 let _ = unsafe { Type::ref_from_raw(value.type_) };
1128 }
1129
1130 pub fn new<T: Into<Conf<Ref<Type>>>>(ty: T, name: String, location: Option<Variable>) -> Self {
1131 Self {
1132 ty: ty.into(),
1133 name,
1134 location,
1135 }
1136 }
1137}
1138
1139#[derive(Debug, Clone, Hash, PartialEq, Eq)]
1140pub struct EnumerationMember {
1141 pub name: String,
1142 pub value: u64,
1144 pub default: bool,
1146}
1147
1148impl EnumerationMember {
1149 pub(crate) fn from_raw(value: &BNEnumerationMember) -> Self {
1150 Self {
1151 name: raw_to_string(value.name).unwrap(),
1152 value: value.value,
1153 default: value.isDefault,
1154 }
1155 }
1156
1157 pub(crate) fn from_owned_raw(value: BNEnumerationMember) -> Self {
1158 let owned = Self::from_raw(&value);
1159 Self::free_raw(value);
1160 owned
1161 }
1162
1163 pub(crate) fn into_raw(value: Self) -> BNEnumerationMember {
1164 let bn_name = BnString::new(value.name);
1165 BNEnumerationMember {
1166 name: BnString::into_raw(bn_name),
1167 value: value.value,
1168 isDefault: value.default,
1169 }
1170 }
1171
1172 pub(crate) fn free_raw(value: BNEnumerationMember) {
1173 unsafe { BnString::free_raw(value.name) };
1174 }
1175
1176 pub fn new(name: String, value: u64, default: bool) -> Self {
1177 Self {
1178 name,
1179 value,
1180 default,
1181 }
1182 }
1183}
1184
1185#[derive(PartialEq, Eq, Hash)]
1186pub struct EnumerationBuilder {
1187 pub(crate) handle: *mut BNEnumerationBuilder,
1188}
1189
1190impl EnumerationBuilder {
1191 pub fn new() -> Self {
1192 Self {
1193 handle: unsafe { BNCreateEnumerationBuilder() },
1194 }
1195 }
1196
1197 pub(crate) unsafe fn from_raw(handle: *mut BNEnumerationBuilder) -> Self {
1198 Self { handle }
1199 }
1200
1201 pub fn finalize(&self) -> Ref<Enumeration> {
1202 unsafe { Enumeration::ref_from_raw(BNFinalizeEnumerationBuilder(self.handle)) }
1203 }
1204
1205 pub fn append(&mut self, name: &str) -> &mut Self {
1206 let name = name.to_cstr();
1207 unsafe {
1208 BNAddEnumerationBuilderMember(self.handle, name.as_ref().as_ptr() as _);
1209 }
1210 self
1211 }
1212
1213 pub fn insert(&mut self, name: &str, value: u64) -> &mut Self {
1214 let name = name.to_cstr();
1215 unsafe {
1216 BNAddEnumerationBuilderMemberWithValue(self.handle, name.as_ref().as_ptr() as _, value);
1217 }
1218 self
1219 }
1220
1221 pub fn replace(&mut self, id: usize, name: &str, value: u64) -> &mut Self {
1222 let name = name.to_cstr();
1223 unsafe {
1224 BNReplaceEnumerationBuilderMember(self.handle, id, name.as_ref().as_ptr() as _, value);
1225 }
1226 self
1227 }
1228
1229 pub fn remove(&mut self, id: usize) -> &mut Self {
1230 unsafe {
1231 BNRemoveEnumerationBuilderMember(self.handle, id);
1232 }
1233
1234 self
1235 }
1236
1237 pub fn members(&self) -> Vec<EnumerationMember> {
1238 unsafe {
1239 let mut count = 0;
1240 let members_raw_ptr = BNGetEnumerationBuilderMembers(self.handle, &mut count);
1241 let members_raw: &[BNEnumerationMember] =
1242 std::slice::from_raw_parts(members_raw_ptr, count);
1243 let members = members_raw
1244 .iter()
1245 .map(EnumerationMember::from_raw)
1246 .collect();
1247 BNFreeEnumerationMemberList(members_raw_ptr, count);
1248 members
1249 }
1250 }
1251}
1252
1253impl Default for EnumerationBuilder {
1254 fn default() -> Self {
1255 Self::new()
1256 }
1257}
1258
1259impl From<&Enumeration> for EnumerationBuilder {
1260 fn from(enumeration: &Enumeration) -> Self {
1261 unsafe {
1262 Self::from_raw(BNCreateEnumerationBuilderFromEnumeration(
1263 enumeration.handle,
1264 ))
1265 }
1266 }
1267}
1268
1269impl Drop for EnumerationBuilder {
1270 fn drop(&mut self) {
1271 unsafe { BNFreeEnumerationBuilder(self.handle) };
1272 }
1273}
1274
1275#[derive(PartialEq, Eq, Hash)]
1276pub struct Enumeration {
1277 pub(crate) handle: *mut BNEnumeration,
1278}
1279
1280impl Enumeration {
1281 pub(crate) unsafe fn ref_from_raw(handle: *mut BNEnumeration) -> Ref<Self> {
1282 debug_assert!(!handle.is_null());
1283 Ref::new(Self { handle })
1284 }
1285
1286 pub fn builder() -> EnumerationBuilder {
1287 EnumerationBuilder::new()
1288 }
1289
1290 pub fn members(&self) -> Vec<EnumerationMember> {
1291 unsafe {
1292 let mut count = 0;
1293 let members_raw_ptr = BNGetEnumerationMembers(self.handle, &mut count);
1294 debug_assert!(!members_raw_ptr.is_null());
1295 let members_raw: &[BNEnumerationMember] =
1296 std::slice::from_raw_parts(members_raw_ptr, count);
1297 let members = members_raw
1298 .iter()
1299 .map(EnumerationMember::from_raw)
1300 .collect();
1301 BNFreeEnumerationMemberList(members_raw_ptr, count);
1302 members
1303 }
1304 }
1305}
1306
1307impl Debug for Enumeration {
1308 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1309 f.debug_struct("Enumeration")
1310 .field("members", &self.members())
1311 .finish()
1312 }
1313}
1314
1315unsafe impl RefCountable for Enumeration {
1316 unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
1317 Self::ref_from_raw(BNNewEnumerationReference(handle.handle))
1318 }
1319
1320 unsafe fn dec_ref(handle: &Self) {
1321 BNFreeEnumeration(handle.handle);
1322 }
1323}
1324
1325impl ToOwned for Enumeration {
1326 type Owned = Ref<Self>;
1327
1328 fn to_owned(&self) -> Self::Owned {
1329 unsafe { RefCountable::inc_ref(self) }
1330 }
1331}
1332
1333#[derive(PartialEq, Eq, Hash)]
1334pub struct StructureBuilder {
1335 pub(crate) handle: *mut BNStructureBuilder,
1336}
1337
1338impl StructureBuilder {
1390 pub fn new() -> Self {
1391 Self {
1392 handle: unsafe { BNCreateStructureBuilder() },
1393 }
1394 }
1395
1396 pub(crate) unsafe fn from_raw(handle: *mut BNStructureBuilder) -> Self {
1397 debug_assert!(!handle.is_null());
1398 Self { handle }
1399 }
1400
1401 pub fn finalize(&self) -> Ref<Structure> {
1403 let raw_struct_ptr = unsafe { BNFinalizeStructureBuilder(self.handle) };
1404 unsafe { Structure::ref_from_raw(raw_struct_ptr) }
1405 }
1406
1407 pub fn width(&mut self, width: u64) -> &mut Self {
1413 unsafe {
1414 BNSetStructureBuilderWidth(self.handle, width);
1415 }
1416 self
1417 }
1418
1419 pub fn alignment(&mut self, alignment: usize) -> &mut Self {
1420 unsafe {
1421 BNSetStructureBuilderAlignment(self.handle, alignment);
1422 }
1423 self
1424 }
1425
1426 pub fn packed(&mut self, packed: bool) -> &mut Self {
1430 unsafe {
1431 BNSetStructureBuilderPacked(self.handle, packed);
1432 }
1433 self
1434 }
1435
1436 pub fn structure_type(&mut self, t: StructureType) -> &mut Self {
1437 unsafe { BNSetStructureBuilderType(self.handle, t) };
1438 self
1439 }
1440
1441 pub fn pointer_offset(&mut self, offset: i64) -> &mut Self {
1442 unsafe { BNSetStructureBuilderPointerOffset(self.handle, offset) };
1443 self
1444 }
1445
1446 pub fn propagates_data_var_refs(&mut self, propagates: bool) -> &mut Self {
1447 unsafe { BNSetStructureBuilderPropagatesDataVariableReferences(self.handle, propagates) };
1448 self
1449 }
1450
1451 pub fn base_structures(&mut self, bases: &[BaseStructure]) -> &mut Self {
1452 let raw_base_structs: Vec<BNBaseStructure> =
1453 bases.iter().map(BaseStructure::into_owned_raw).collect();
1454 unsafe {
1455 BNSetBaseStructuresForStructureBuilder(
1456 self.handle,
1457 raw_base_structs.as_ptr() as *mut _,
1458 raw_base_structs.len(),
1459 )
1460 };
1461 self
1462 }
1463
1464 pub fn append<'a, T: Into<Conf<&'a Type>>>(
1472 &mut self,
1473 ty: T,
1474 name: &str,
1475 access: MemberAccess,
1476 scope: MemberScope,
1477 ) -> &mut Self {
1478 let name = name.to_cstr();
1479 let owned_raw_ty = Conf::<&Type>::into_raw(ty.into());
1480 unsafe {
1481 BNAddStructureBuilderMember(
1482 self.handle,
1483 &owned_raw_ty,
1484 name.as_ref().as_ptr() as _,
1485 access,
1486 scope,
1487 );
1488 }
1489 self
1490 }
1491
1492 pub fn insert_member(
1500 &mut self,
1501 member: StructureMember,
1502 overwrite_existing: bool,
1503 ) -> &mut Self {
1504 self.insert_bitwise(
1505 &member.ty,
1506 &member.name,
1507 member.bit_offset(),
1508 member.bit_width,
1509 overwrite_existing,
1510 member.access,
1511 member.scope,
1512 );
1513 self
1514 }
1515
1516 pub fn insert<'a, T: Into<Conf<&'a Type>>>(
1521 &mut self,
1522 ty: T,
1523 name: &str,
1524 offset: u64,
1525 overwrite_existing: bool,
1526 access: MemberAccess,
1527 scope: MemberScope,
1528 ) -> &mut Self {
1529 self.insert_bitwise(
1530 ty,
1531 name,
1532 offset * 8,
1533 None,
1534 overwrite_existing,
1535 access,
1536 scope,
1537 )
1538 }
1539
1540 pub fn insert_bitwise<'a, T: Into<Conf<&'a Type>>>(
1545 &mut self,
1546 ty: T,
1547 name: &str,
1548 bit_offset: u64,
1549 bit_width: Option<u8>,
1550 overwrite_existing: bool,
1551 access: MemberAccess,
1552 scope: MemberScope,
1553 ) -> &mut Self {
1554 let name = name.to_cstr();
1555 let owned_raw_ty = Conf::<&Type>::into_raw(ty.into());
1556 let byte_offset = bit_offset / 8;
1557 let bit_position = bit_offset % 8;
1558 unsafe {
1559 BNAddStructureBuilderMemberAtOffset(
1560 self.handle,
1561 &owned_raw_ty,
1562 name.as_ref().as_ptr() as _,
1563 byte_offset,
1564 overwrite_existing,
1565 access,
1566 scope,
1567 bit_position as u8,
1568 bit_width.unwrap_or(0),
1569 );
1570 }
1571 self
1572 }
1573
1574 pub fn replace<'a, T: Into<Conf<&'a Type>>>(
1575 &mut self,
1576 index: usize,
1577 ty: T,
1578 name: &str,
1579 overwrite_existing: bool,
1580 ) -> &mut Self {
1581 let name = name.to_cstr();
1582 let owned_raw_ty = Conf::<&Type>::into_raw(ty.into());
1583 unsafe {
1584 BNReplaceStructureBuilderMember(
1585 self.handle,
1586 index,
1587 &owned_raw_ty,
1588 name.as_ref().as_ptr() as _,
1589 overwrite_existing,
1590 )
1591 }
1592 self
1593 }
1594
1595 pub fn remove(&mut self, index: usize) -> &mut Self {
1597 unsafe { BNRemoveStructureBuilderMember(self.handle, index) };
1598 self
1599 }
1600
1601 pub fn current_width(&self) -> u64 {
1606 unsafe { BNGetStructureBuilderWidth(self.handle) }
1607 }
1608}
1609
1610impl From<&Structure> for StructureBuilder {
1611 fn from(structure: &Structure) -> StructureBuilder {
1612 unsafe { Self::from_raw(BNCreateStructureBuilderFromStructure(structure.handle)) }
1613 }
1614}
1615
1616impl From<Vec<StructureMember>> for StructureBuilder {
1617 fn from(members: Vec<StructureMember>) -> StructureBuilder {
1618 let mut builder = StructureBuilder::new();
1619 for member in members {
1620 builder.insert_member(member, false);
1621 }
1622 builder
1623 }
1624}
1625
1626impl Drop for StructureBuilder {
1627 fn drop(&mut self) {
1628 unsafe { BNFreeStructureBuilder(self.handle) };
1629 }
1630}
1631
1632impl Default for StructureBuilder {
1633 fn default() -> Self {
1634 Self::new()
1635 }
1636}
1637
1638#[derive(PartialEq, Eq, Hash)]
1639pub struct Structure {
1640 pub(crate) handle: *mut BNStructure,
1641}
1642
1643impl Structure {
1644 pub(crate) unsafe fn ref_from_raw(handle: *mut BNStructure) -> Ref<Self> {
1645 debug_assert!(!handle.is_null());
1646 Ref::new(Self { handle })
1647 }
1648
1649 pub fn builder() -> StructureBuilder {
1650 StructureBuilder::new()
1651 }
1652
1653 pub fn width(&self) -> u64 {
1654 unsafe { BNGetStructureWidth(self.handle) }
1655 }
1656
1657 pub fn structure_type(&self) -> StructureType {
1658 unsafe { BNGetStructureType(self.handle) }
1659 }
1660
1661 pub fn members_at_offset(
1673 &self,
1674 container: &TypeContainer,
1675 offset: u64,
1676 ) -> Vec<StructureMember> {
1677 self.members_including_inherited(container)
1678 .into_iter()
1679 .filter(|m| m.member.is_offset_valid(offset))
1680 .map(|m| m.member)
1681 .collect()
1682 }
1683
1684 pub fn members(&self) -> Vec<StructureMember> {
1689 unsafe {
1690 let mut count = 0;
1691 let members_raw_ptr: *mut BNStructureMember =
1692 BNGetStructureMembers(self.handle, &mut count);
1693 debug_assert!(!members_raw_ptr.is_null());
1694 let members_raw = std::slice::from_raw_parts(members_raw_ptr, count);
1695 let members = members_raw.iter().map(StructureMember::from_raw).collect();
1696 BNFreeStructureMemberList(members_raw_ptr, count);
1697 members
1698 }
1699 }
1700
1701 pub fn members_including_inherited(
1706 &self,
1707 container: &TypeContainer,
1708 ) -> Vec<InheritedStructureMember> {
1709 unsafe {
1710 let mut count = 0;
1711 let members_raw_ptr: *mut BNInheritedStructureMember =
1712 BNGetStructureMembersIncludingInherited(
1713 self.handle,
1714 container.handle.as_ptr(),
1715 &mut count,
1716 );
1717 debug_assert!(!members_raw_ptr.is_null());
1718 let members_raw = std::slice::from_raw_parts(members_raw_ptr, count);
1719 let members = members_raw
1720 .iter()
1721 .map(InheritedStructureMember::from_raw)
1722 .collect();
1723 BNFreeInheritedStructureMemberList(members_raw_ptr, count);
1724 members
1725 }
1726 }
1727
1728 pub fn base_structures(&self) -> Vec<BaseStructure> {
1731 let mut count = 0;
1732 let bases_raw_ptr = unsafe { BNGetBaseStructuresForStructure(self.handle, &mut count) };
1733 debug_assert!(!bases_raw_ptr.is_null());
1734 let bases_raw = unsafe { std::slice::from_raw_parts(bases_raw_ptr, count) };
1735 let bases = bases_raw.iter().map(BaseStructure::from_raw).collect();
1736 unsafe { BNFreeBaseStructureList(bases_raw_ptr, count) };
1737 bases
1738 }
1739
1740 pub fn is_packed(&self) -> bool {
1742 unsafe { BNIsStructurePacked(self.handle) }
1743 }
1744
1745 pub fn alignment(&self) -> usize {
1746 unsafe { BNGetStructureAlignment(self.handle) }
1747 }
1748}
1749
1750impl Debug for Structure {
1751 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1752 f.debug_struct("Structure")
1753 .field("width", &self.width())
1754 .field("alignment", &self.alignment())
1755 .field("packed", &self.is_packed())
1756 .field("structure_type", &self.structure_type())
1757 .field("base_structures", &self.base_structures())
1758 .field("members", &self.members())
1759 .finish()
1760 }
1761}
1762
1763unsafe impl RefCountable for Structure {
1764 unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
1765 Self::ref_from_raw(BNNewStructureReference(handle.handle))
1766 }
1767
1768 unsafe fn dec_ref(handle: &Self) {
1769 BNFreeStructure(handle.handle);
1770 }
1771}
1772
1773impl ToOwned for Structure {
1774 type Owned = Ref<Self>;
1775
1776 fn to_owned(&self) -> Self::Owned {
1777 unsafe { RefCountable::inc_ref(self) }
1778 }
1779}
1780
1781#[derive(Debug, Clone, Hash, PartialEq, Eq)]
1782pub struct StructureMember {
1783 pub ty: Conf<Ref<Type>>,
1784 pub name: String,
1786 pub offset: u64,
1788 pub access: MemberAccess,
1789 pub scope: MemberScope,
1790 pub bit_position: Option<u8>,
1792 pub bit_width: Option<u8>,
1793}
1794
1795impl StructureMember {
1796 pub(crate) fn from_raw(value: &BNStructureMember) -> Self {
1797 Self {
1798 ty: Conf::new(
1799 unsafe { Type::from_raw(value.type_) }.to_owned(),
1800 value.typeConfidence,
1801 ),
1802 name: raw_to_string(value.name as *mut _).unwrap(),
1804 offset: value.offset,
1805 access: value.access,
1806 scope: value.scope,
1807 bit_position: match value.bitPosition {
1808 0 => None,
1809 _ => Some(value.bitPosition),
1810 },
1811 bit_width: match value.bitWidth {
1812 0 => None,
1813 _ => Some(value.bitWidth),
1814 },
1815 }
1816 }
1817
1818 pub(crate) fn from_owned_raw(value: BNStructureMember) -> Self {
1819 let owned = Self::from_raw(&value);
1820 Self::free_raw(value);
1821 owned
1822 }
1823
1824 pub(crate) fn into_raw(value: Self) -> BNStructureMember {
1825 let bn_name = BnString::new(value.name);
1826 BNStructureMember {
1827 type_: unsafe { Ref::into_raw(value.ty.contents) }.handle,
1828 name: BnString::into_raw(bn_name),
1829 offset: value.offset,
1830 typeConfidence: value.ty.confidence,
1831 access: value.access,
1832 scope: value.scope,
1833 bitPosition: value.bit_position.unwrap_or(0),
1834 bitWidth: value.bit_width.unwrap_or(0),
1835 }
1836 }
1837
1838 pub(crate) fn free_raw(value: BNStructureMember) {
1839 let _ = unsafe { Type::ref_from_raw(value.type_) };
1840 unsafe { BnString::free_raw(value.name) };
1841 }
1842
1843 pub fn new(
1844 ty: Conf<Ref<Type>>,
1845 name: String,
1846 offset: u64,
1847 access: MemberAccess,
1848 scope: MemberScope,
1849 ) -> Self {
1850 Self {
1851 ty,
1852 name,
1853 offset,
1854 access,
1855 scope,
1856 bit_position: None,
1857 bit_width: None,
1858 }
1859 }
1860
1861 pub fn new_bitfield(
1862 ty: Conf<Ref<Type>>,
1863 name: String,
1864 bit_offset: u64,
1865 bit_width: u8,
1866 access: MemberAccess,
1867 scope: MemberScope,
1868 ) -> Self {
1869 Self {
1870 ty,
1871 name,
1872 offset: bit_offset / 8,
1873 access,
1874 scope,
1875 bit_position: Some((bit_offset % 8) as u8),
1876 bit_width: Some(bit_width),
1877 }
1878 }
1879
1880 pub fn is_offset_valid(&self, offset: u64) -> bool {
1883 self.offset <= offset && offset < self.offset + self.ty.contents.width()
1884 }
1885
1886 pub fn bit_offset(&self) -> u64 {
1888 (self.offset * 8) + self.bit_position.unwrap_or(0) as u64
1889 }
1890}
1891
1892impl CoreArrayProvider for StructureMember {
1893 type Raw = BNStructureMember;
1894 type Context = ();
1895 type Wrapped<'a> = Self;
1896}
1897
1898unsafe impl CoreArrayProviderInner for StructureMember {
1899 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
1900 BNFreeStructureMemberList(raw, count)
1901 }
1902
1903 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
1904 Self::from_raw(raw)
1905 }
1906}
1907
1908#[derive(Debug, Clone, Hash, PartialEq, Eq)]
1909pub struct InheritedStructureMember {
1910 pub base: Ref<NamedTypeReference>,
1911 pub base_offset: u64,
1912 pub member: StructureMember,
1913 pub member_index: usize,
1914}
1915
1916impl InheritedStructureMember {
1917 pub(crate) fn from_raw(value: &BNInheritedStructureMember) -> Self {
1918 Self {
1919 base: unsafe { NamedTypeReference::from_raw(value.base) }.to_owned(),
1920 base_offset: value.baseOffset,
1921 member: StructureMember::from_raw(&value.member),
1922 member_index: value.memberIndex,
1923 }
1924 }
1925
1926 pub(crate) fn from_owned_raw(value: BNInheritedStructureMember) -> Self {
1927 let owned = Self::from_raw(&value);
1928 Self::free_raw(value);
1929 owned
1930 }
1931
1932 pub(crate) fn into_raw(value: Self) -> BNInheritedStructureMember {
1933 BNInheritedStructureMember {
1934 base: unsafe { Ref::into_raw(value.base) }.handle,
1935 baseOffset: value.base_offset,
1936 member: StructureMember::into_raw(value.member),
1937 memberIndex: value.member_index,
1938 }
1939 }
1940
1941 pub(crate) fn free_raw(value: BNInheritedStructureMember) {
1942 let _ = unsafe { NamedTypeReference::ref_from_raw(value.base) };
1943 StructureMember::free_raw(value.member);
1944 }
1945
1946 pub fn new(
1947 base: Ref<NamedTypeReference>,
1948 base_offset: u64,
1949 member: StructureMember,
1950 member_index: usize,
1951 ) -> Self {
1952 Self {
1953 base,
1954 base_offset,
1955 member,
1956 member_index,
1957 }
1958 }
1959}
1960
1961#[derive(Debug, Clone, Hash, PartialEq, Eq)]
1962pub struct BaseStructure {
1963 pub ty: Ref<NamedTypeReference>,
1964 pub offset: u64,
1965 pub width: u64,
1966}
1967
1968impl BaseStructure {
1969 pub(crate) fn from_raw(value: &BNBaseStructure) -> Self {
1970 Self {
1971 ty: unsafe { NamedTypeReference::from_raw(value.type_) }.to_owned(),
1972 offset: value.offset,
1973 width: value.width,
1974 }
1975 }
1976
1977 pub(crate) fn from_owned_raw(value: BNBaseStructure) -> Self {
1978 let owned = Self::from_raw(&value);
1979 Self::free_raw(value);
1980 owned
1981 }
1982
1983 pub(crate) fn into_raw(value: Self) -> BNBaseStructure {
1984 BNBaseStructure {
1985 type_: unsafe { Ref::into_raw(value.ty) }.handle,
1986 offset: value.offset,
1987 width: value.width,
1988 }
1989 }
1990
1991 pub(crate) fn into_owned_raw(value: &Self) -> BNBaseStructure {
1992 BNBaseStructure {
1993 type_: value.ty.handle,
1994 offset: value.offset,
1995 width: value.width,
1996 }
1997 }
1998
1999 pub(crate) fn free_raw(value: BNBaseStructure) {
2000 let _ = unsafe { NamedTypeReference::ref_from_raw(value.type_) };
2001 }
2002
2003 pub fn new(ty: Ref<NamedTypeReference>, offset: u64, width: u64) -> Self {
2004 Self { ty, offset, width }
2005 }
2006}
2007
2008#[derive(PartialEq, Eq, Hash)]
2009pub struct NamedTypeReference {
2010 pub(crate) handle: *mut BNNamedTypeReference,
2011}
2012
2013impl NamedTypeReference {
2014 pub(crate) unsafe fn from_raw(handle: *mut BNNamedTypeReference) -> Self {
2015 debug_assert!(!handle.is_null());
2016 Self { handle }
2017 }
2018
2019 pub(crate) unsafe fn ref_from_raw(handle: *mut BNNamedTypeReference) -> Ref<Self> {
2020 debug_assert!(!handle.is_null());
2021 Ref::new(Self { handle })
2022 }
2023
2024 pub fn new<T: Into<QualifiedName>>(type_class: NamedTypeReferenceClass, name: T) -> Ref<Self> {
2030 let mut raw_name = QualifiedName::into_raw(name.into());
2031 let result = unsafe {
2032 Self::ref_from_raw(BNCreateNamedType(
2033 type_class,
2034 std::ptr::null(),
2035 &mut raw_name,
2036 ))
2037 };
2038 QualifiedName::free_raw(raw_name);
2039 result
2040 }
2041
2042 pub fn new_with_id<T: Into<QualifiedName>>(
2048 type_class: NamedTypeReferenceClass,
2049 type_id: &str,
2050 name: T,
2051 ) -> Ref<Self> {
2052 let type_id = type_id.to_cstr();
2053 let mut raw_name = QualifiedName::into_raw(name.into());
2054 let result = unsafe {
2055 Self::ref_from_raw(BNCreateNamedType(
2056 type_class,
2057 type_id.as_ref().as_ptr() as _,
2058 &mut raw_name,
2059 ))
2060 };
2061 QualifiedName::free_raw(raw_name);
2062 result
2063 }
2064
2065 pub fn name(&self) -> QualifiedName {
2066 let raw_name = unsafe { BNGetTypeReferenceName(self.handle) };
2067 QualifiedName::from_owned_raw(raw_name)
2068 }
2069
2070 pub fn id(&self) -> String {
2071 unsafe { BnString::into_string(BNGetTypeReferenceId(self.handle)) }
2072 }
2073
2074 pub fn class(&self) -> NamedTypeReferenceClass {
2075 unsafe { BNGetTypeReferenceClass(self.handle) }
2076 }
2077
2078 fn target_helper(&self, bv: &BinaryView, visited: &mut HashSet<String>) -> Option<Ref<Type>> {
2079 let ty = bv.type_by_id(&self.id())?;
2080 match ty.type_class() {
2081 TypeClass::NamedTypeReferenceClass => {
2082 let ntr = ty
2084 .get_named_type_reference()
2085 .expect("NTR type class should always have a valid NTR");
2086 match visited.insert(ntr.id()) {
2087 true => ntr.target_helper(bv, visited),
2088 false => None,
2090 }
2091 }
2092 _ => Some(ty),
2094 }
2095 }
2096
2097 pub fn target(&self, bv: &BinaryView) -> Option<Ref<Type>> {
2101 self.target_helper(bv, &mut HashSet::new())
2102 }
2103}
2104
2105impl ToOwned for NamedTypeReference {
2106 type Owned = Ref<Self>;
2107
2108 fn to_owned(&self) -> Self::Owned {
2109 unsafe { RefCountable::inc_ref(self) }
2110 }
2111}
2112
2113unsafe impl RefCountable for NamedTypeReference {
2114 unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
2115 Self::ref_from_raw(BNNewNamedTypeReference(handle.handle))
2116 }
2117
2118 unsafe fn dec_ref(handle: &Self) {
2119 BNFreeNamedTypeReference(handle.handle)
2120 }
2121}
2122
2123impl Debug for NamedTypeReference {
2124 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
2125 write!(f, "{} (id: {})", self.name(), self.id())
2126 }
2127}
2128
2129#[derive(Default, Debug, Clone, Hash, PartialEq, Eq, Ord, PartialOrd)]
2131pub struct QualifiedName {
2132 pub separator: String,
2134 pub items: Vec<String>,
2135}
2136
2137impl QualifiedName {
2138 pub(crate) fn from_raw(value: &BNQualifiedName) -> Self {
2139 let raw_names = unsafe { std::slice::from_raw_parts(value.name, value.nameCount) };
2141 let items = raw_names
2142 .iter()
2143 .filter_map(|&raw_name| raw_to_string(raw_name as *const _))
2144 .collect();
2145 let separator = raw_to_string(value.join).unwrap();
2146 Self { items, separator }
2147 }
2148
2149 pub(crate) fn from_owned_raw(value: BNQualifiedName) -> Self {
2150 let result = Self::from_raw(&value);
2151 Self::free_raw(value);
2152 result
2153 }
2154
2155 pub fn into_raw(value: Self) -> BNQualifiedName {
2156 let bn_join = BnString::new(&value.separator);
2157 BNQualifiedName {
2158 name: strings_to_string_list(&value.items),
2160 join: BnString::into_raw(bn_join),
2162 nameCount: value.items.len(),
2163 }
2164 }
2165
2166 pub(crate) fn free_raw(value: BNQualifiedName) {
2167 unsafe { BnString::free_raw(value.join) };
2168 unsafe { BNFreeStringList(value.name, value.nameCount) };
2169 }
2170
2171 pub fn new(items: Vec<String>) -> Self {
2172 Self::new_with_separator(items, "::".to_string())
2173 }
2174
2175 pub fn new_with_separator(items: Vec<String>, separator: String) -> Self {
2176 Self { items, separator }
2177 }
2178
2179 pub fn with_item(&self, item: impl Into<String>) -> Self {
2180 let mut items = self.items.clone();
2181 items.push(item.into());
2182 Self::new_with_separator(items, self.separator.clone())
2183 }
2184
2185 pub fn push(&mut self, item: String) {
2186 self.items.push(item);
2187 }
2188
2189 pub fn pop(&mut self) -> Option<String> {
2190 self.items.pop()
2191 }
2192
2193 pub fn insert(&mut self, index: usize, item: String) {
2194 if index <= self.items.len() {
2195 self.items.insert(index, item);
2196 }
2197 }
2198
2199 pub fn split_last(&self) -> Option<(String, QualifiedName)> {
2200 self.items.split_last().map(|(a, b)| {
2201 (
2202 a.to_owned(),
2203 QualifiedName::new_with_separator(b.to_vec(), self.separator.clone()),
2204 )
2205 })
2206 }
2207
2208 pub fn replace(&self, from: &str, to: &str) -> Self {
2225 Self {
2226 items: self
2227 .items
2228 .iter()
2229 .map(|item| item.replace(from, to))
2230 .collect(),
2231 separator: self.separator.clone(),
2232 }
2233 }
2234
2235 pub fn last(&self) -> Option<&String> {
2237 self.items.last()
2238 }
2239
2240 pub fn last_mut(&mut self) -> Option<&mut String> {
2242 self.items.last_mut()
2243 }
2244
2245 pub fn len(&self) -> usize {
2246 self.items.len()
2247 }
2248
2249 pub fn is_empty(&self) -> bool {
2254 self.items.is_empty()
2255 }
2256}
2257
2258impl From<String> for QualifiedName {
2259 fn from(value: String) -> Self {
2260 Self {
2261 items: vec![value],
2262 separator: String::from("::"),
2264 }
2265 }
2266}
2267
2268impl From<&str> for QualifiedName {
2269 fn from(value: &str) -> Self {
2270 Self::from(value.to_string())
2271 }
2272}
2273
2274impl From<&String> for QualifiedName {
2275 fn from(value: &String) -> Self {
2276 Self::from(value.to_owned())
2277 }
2278}
2279
2280impl From<Cow<'_, str>> for QualifiedName {
2281 fn from(value: Cow<'_, str>) -> Self {
2282 Self::from(value.to_string())
2283 }
2284}
2285
2286impl From<Vec<String>> for QualifiedName {
2287 fn from(value: Vec<String>) -> Self {
2288 Self::new(value)
2289 }
2290}
2291
2292impl From<Vec<&str>> for QualifiedName {
2293 fn from(value: Vec<&str>) -> Self {
2294 value
2295 .iter()
2296 .map(ToString::to_string)
2297 .collect::<Vec<_>>()
2298 .into()
2299 }
2300}
2301
2302impl From<QualifiedName> for String {
2303 fn from(value: QualifiedName) -> Self {
2304 value.to_string()
2305 }
2306}
2307
2308impl Index<usize> for QualifiedName {
2309 type Output = String;
2310
2311 fn index(&self, index: usize) -> &Self::Output {
2312 &self.items[index]
2313 }
2314}
2315
2316impl IndexMut<usize> for QualifiedName {
2317 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
2318 &mut self.items[index]
2319 }
2320}
2321
2322impl Display for QualifiedName {
2323 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
2324 write!(f, "{}", self.items.join(&self.separator))
2325 }
2326}
2327
2328impl CoreArrayProvider for QualifiedName {
2329 type Raw = BNQualifiedName;
2330 type Context = ();
2331 type Wrapped<'a> = Self;
2332}
2333
2334unsafe impl CoreArrayProviderInner for QualifiedName {
2335 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
2336 BNFreeTypeNameList(raw, count);
2337 }
2338
2339 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
2340 QualifiedName::from_raw(raw)
2341 }
2342}
2343
2344#[derive(Debug, Clone, Hash, PartialEq, Eq)]
2345pub struct QualifiedNameAndType {
2346 pub name: QualifiedName,
2347 pub ty: Ref<Type>,
2348}
2349
2350impl QualifiedNameAndType {
2351 pub(crate) fn from_raw(value: &BNQualifiedNameAndType) -> Self {
2352 Self {
2353 name: QualifiedName::from_raw(&value.name),
2354 ty: unsafe { Type::from_raw(value.type_).to_owned() },
2355 }
2356 }
2357
2358 pub(crate) fn from_owned_raw(value: BNQualifiedNameAndType) -> Self {
2359 let owned = Self::from_raw(&value);
2360 Self::free_raw(value);
2361 owned
2362 }
2363
2364 pub(crate) fn into_raw(value: Self) -> BNQualifiedNameAndType {
2365 BNQualifiedNameAndType {
2366 name: QualifiedName::into_raw(value.name),
2367 type_: unsafe { Ref::into_raw(value.ty).handle },
2368 }
2369 }
2370
2371 pub(crate) fn free_raw(value: BNQualifiedNameAndType) {
2372 QualifiedName::free_raw(value.name);
2373 let _ = unsafe { Type::ref_from_raw(value.type_) };
2374 }
2375
2376 pub fn new(name: QualifiedName, ty: Ref<Type>) -> Self {
2377 Self { name, ty }
2378 }
2379}
2380
2381impl<T> From<(T, Ref<Type>)> for QualifiedNameAndType
2382where
2383 T: Into<QualifiedName>,
2384{
2385 fn from(value: (T, Ref<Type>)) -> Self {
2386 Self {
2387 name: value.0.into(),
2388 ty: value.1,
2389 }
2390 }
2391}
2392
2393impl<T> From<(T, &Type)> for QualifiedNameAndType
2394where
2395 T: Into<QualifiedName>,
2396{
2397 fn from(value: (T, &Type)) -> Self {
2398 let ty = value.1.to_owned();
2399 Self {
2400 name: value.0.into(),
2401 ty,
2402 }
2403 }
2404}
2405
2406impl CoreArrayProvider for QualifiedNameAndType {
2407 type Raw = BNQualifiedNameAndType;
2408 type Context = ();
2409 type Wrapped<'a> = Self;
2410}
2411
2412unsafe impl CoreArrayProviderInner for QualifiedNameAndType {
2413 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
2414 BNFreeTypeAndNameList(raw, count);
2415 }
2416
2417 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
2418 QualifiedNameAndType::from_raw(raw)
2419 }
2420}
2421
2422#[derive(Debug, Clone, Hash, PartialEq, Eq)]
2423pub struct QualifiedNameTypeAndId {
2424 pub name: QualifiedName,
2425 pub ty: Ref<Type>,
2426 pub id: String,
2427}
2428
2429impl QualifiedNameTypeAndId {
2430 pub(crate) fn from_raw(value: &BNQualifiedNameTypeAndId) -> Self {
2431 Self {
2432 name: QualifiedName::from_raw(&value.name),
2433 ty: unsafe { Type::from_raw(value.type_) }.to_owned(),
2434 id: raw_to_string(value.id).unwrap(),
2435 }
2436 }
2437
2438 pub(crate) fn from_owned_raw(value: BNQualifiedNameTypeAndId) -> Self {
2439 let owned = Self::from_raw(&value);
2440 Self::free_raw(value);
2441 owned
2442 }
2443
2444 pub(crate) fn into_raw(value: Self) -> BNQualifiedNameTypeAndId {
2445 let bn_id = BnString::new(value.id);
2446 BNQualifiedNameTypeAndId {
2447 name: QualifiedName::into_raw(value.name),
2448 id: BnString::into_raw(bn_id),
2449 type_: unsafe { Ref::into_raw(value.ty) }.handle,
2450 }
2451 }
2452
2453 pub(crate) fn free_raw(value: BNQualifiedNameTypeAndId) {
2454 QualifiedName::free_raw(value.name);
2455 let _ = unsafe { Type::ref_from_raw(value.type_) };
2456 let _ = unsafe { BnString::from_raw(value.id) };
2457 }
2458}
2459
2460impl CoreArrayProvider for QualifiedNameTypeAndId {
2461 type Raw = BNQualifiedNameTypeAndId;
2462 type Context = ();
2463 type Wrapped<'a> = QualifiedNameTypeAndId;
2464}
2465
2466unsafe impl CoreArrayProviderInner for QualifiedNameTypeAndId {
2467 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
2468 BNFreeTypeIdList(raw, count);
2469 }
2470
2471 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
2472 QualifiedNameTypeAndId::from_raw(raw)
2473 }
2474}
2475
2476#[derive(Debug, Clone, Eq, PartialEq, Hash)]
2481pub struct NameAndType {
2482 pub name: String,
2483 pub ty: Conf<Ref<Type>>,
2484}
2485
2486impl NameAndType {
2487 pub(crate) fn from_raw(value: &BNNameAndType) -> Self {
2488 Self {
2489 name: raw_to_string(value.name as *mut _).unwrap(),
2491 ty: Conf::new(
2492 unsafe { Type::from_raw(value.type_).to_owned() },
2493 value.typeConfidence,
2494 ),
2495 }
2496 }
2497
2498 pub(crate) fn from_owned_raw(value: BNNameAndType) -> Self {
2499 let owned = Self::from_raw(&value);
2500 Self::free_raw(value);
2501 owned
2502 }
2503
2504 pub(crate) fn into_raw(value: Self) -> BNNameAndType {
2505 let bn_name = BnString::new(value.name);
2506 BNNameAndType {
2507 name: BnString::into_raw(bn_name),
2508 type_: unsafe { Ref::into_raw(value.ty.contents) }.handle,
2509 typeConfidence: value.ty.confidence,
2510 }
2511 }
2512
2513 pub(crate) fn free_raw(value: BNNameAndType) {
2514 unsafe { BnString::free_raw(value.name) };
2515 let _ = unsafe { Type::ref_from_raw(value.type_) };
2516 }
2517
2518 pub fn new(name: impl Into<String>, ty: Conf<Ref<Type>>) -> Self {
2519 Self {
2520 name: name.into(),
2521 ty,
2522 }
2523 }
2524}
2525
2526impl CoreArrayProvider for NameAndType {
2527 type Raw = BNNameAndType;
2528 type Context = ();
2529 type Wrapped<'a> = Self;
2530}
2531
2532unsafe impl CoreArrayProviderInner for NameAndType {
2533 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
2534 BNFreeNameAndTypeList(raw, count);
2535 }
2536
2537 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
2538 NameAndType::from_raw(raw)
2539 }
2540}