1pub mod archive;
28pub mod container;
29pub mod enumeration;
30pub mod library;
31pub mod parser;
32pub mod printer;
33pub mod structure;
34
35use binaryninjacore_sys::*;
36
37use crate::{
38 architecture::Architecture,
39 binary_view::BinaryView,
40 calling_convention::CoreCallingConvention,
41 rc::*,
42 string::{BnString, IntoCStr},
43};
44
45use crate::confidence::{Conf, MAX_CONFIDENCE, MIN_CONFIDENCE};
46use crate::string::raw_to_string;
47use crate::variable::{Variable, VariableSourceType};
48use std::num::NonZeroUsize;
49use std::{
50 collections::HashSet,
51 fmt::{Debug, Display, Formatter},
52 hash::{Hash, Hasher},
53 iter::IntoIterator,
54};
55
56pub use archive::{TypeArchive, TypeArchiveId, TypeArchiveSnapshotId};
57pub use container::TypeContainer;
58pub use enumeration::{Enumeration, EnumerationBuilder, EnumerationMember};
59pub use library::TypeLibrary;
60pub use parser::{
61 CoreTypeParser, ParsedType, TypeParser, TypeParserError, TypeParserErrorSeverity,
62 TypeParserResult,
63};
64pub use printer::{CoreTypePrinter, TypePrinter};
65pub use structure::{
66 BaseStructure, InheritedStructureMember, Structure, StructureBuilder, StructureMember,
67};
68
69#[deprecated(note = "Use crate::qualified_name::QualifiedName instead")]
70pub use crate::qualified_name::QualifiedName;
72
73pub type StructureType = BNStructureVariant;
74pub type ReferenceType = BNReferenceType;
75pub type TypeClass = BNTypeClass;
76pub type NamedTypeReferenceClass = BNNamedTypeReferenceClass;
77pub type MemberAccess = BNMemberAccess;
78pub type MemberScope = BNMemberScope;
79pub type IntegerDisplayType = BNIntegerDisplayType;
80pub type PointerBaseType = BNPointerBaseType;
81
82#[derive(PartialEq, Eq, Hash)]
83pub struct TypeBuilder {
84 pub(crate) handle: *mut BNTypeBuilder,
85}
86
87impl TypeBuilder {
88 pub fn new(t: &Type) -> Self {
89 unsafe { Self::from_raw(BNCreateTypeBuilderFromType(t.handle)) }
90 }
91
92 pub(crate) unsafe fn from_raw(handle: *mut BNTypeBuilder) -> Self {
93 debug_assert!(!handle.is_null());
94 Self { handle }
95 }
96
97 pub fn finalize(&self) -> Ref<Type> {
99 unsafe { Type::ref_from_raw(BNFinalizeTypeBuilder(self.handle)) }
100 }
101
102 pub fn set_can_return<T: Into<Conf<bool>>>(&self, value: T) -> &Self {
103 let mut bool_with_confidence = value.into().into();
104 unsafe { BNSetFunctionTypeBuilderCanReturn(self.handle, &mut bool_with_confidence) };
105 self
106 }
107
108 pub fn set_pure<T: Into<Conf<bool>>>(&self, value: T) -> &Self {
109 let mut bool_with_confidence = value.into().into();
110 unsafe { BNSetTypeBuilderPure(self.handle, &mut bool_with_confidence) };
111 self
112 }
113
114 pub fn set_const<T: Into<Conf<bool>>>(&self, value: T) -> &Self {
115 let mut bool_with_confidence = value.into().into();
116 unsafe { BNTypeBuilderSetConst(self.handle, &mut bool_with_confidence) };
117 self
118 }
119
120 pub fn set_volatile<T: Into<Conf<bool>>>(&self, value: T) -> &Self {
121 let mut bool_with_confidence = value.into().into();
122 unsafe { BNTypeBuilderSetVolatile(self.handle, &mut bool_with_confidence) };
123 self
124 }
125
126 pub fn set_width(&self, width: usize) -> &Self {
130 unsafe { BNTypeBuilderSetWidth(self.handle, width) }
131 self
132 }
133
134 pub fn set_alignment(&self, alignment: usize) -> &Self {
138 unsafe { BNTypeBuilderSetAlignment(self.handle, alignment) }
139 self
140 }
141
142 pub fn set_pointer_base(&self, base_type: PointerBaseType, base_offset: i64) -> &Self {
143 unsafe { BNSetTypeBuilderPointerBase(self.handle, base_type, base_offset) }
144 self
145 }
146
147 pub fn set_child_type<'a, T: Into<Conf<&'a Type>>>(&self, ty: T) -> &Self {
148 let mut type_with_confidence = Conf::<&Type>::into_raw(ty.into());
149 unsafe { BNTypeBuilderSetChildType(self.handle, &mut type_with_confidence) };
150 self
151 }
152
153 pub fn set_target<'a, T: Into<Conf<&'a Type>>>(&self, ty: T) -> &Self {
155 self.set_child_type(ty)
156 }
157
158 pub fn set_element_type<'a, T: Into<Conf<&'a Type>>>(&self, ty: T) -> &Self {
160 self.set_child_type(ty)
161 }
162
163 pub fn set_return_value<'a, T: Into<Conf<&'a Type>>>(&self, ty: T) -> &Self {
165 self.set_child_type(ty)
166 }
167
168 pub fn set_signed<T: Into<Conf<bool>>>(&self, value: T) -> &Self {
169 let mut bool_with_confidence = value.into().into();
170 unsafe { BNTypeBuilderSetSigned(self.handle, &mut bool_with_confidence) };
171 self
172 }
173
174 pub fn set_integer_display_type(&self, display_type: IntegerDisplayType) -> &Self {
175 unsafe { BNSetIntegerTypeDisplayType(self.handle, display_type) };
176 self
177 }
178
179 pub fn type_class(&self) -> TypeClass {
182 unsafe { BNGetTypeBuilderClass(self.handle) }
183 }
184
185 pub fn width(&self) -> u64 {
186 unsafe { BNGetTypeBuilderWidth(self.handle) }
187 }
188
189 pub fn alignment(&self) -> usize {
190 unsafe { BNGetTypeBuilderAlignment(self.handle) }
191 }
192
193 pub fn is_signed(&self) -> Conf<bool> {
194 unsafe { BNIsTypeBuilderSigned(self.handle).into() }
195 }
196
197 pub fn integer_display_type(&self) -> IntegerDisplayType {
198 self.finalize().integer_display_type()
199 }
200
201 pub fn is_const(&self) -> Conf<bool> {
202 unsafe { BNIsTypeBuilderConst(self.handle).into() }
203 }
204
205 pub fn is_volatile(&self) -> Conf<bool> {
206 unsafe { BNIsTypeBuilderVolatile(self.handle).into() }
207 }
208
209 pub fn is_floating_point(&self) -> bool {
210 unsafe { BNIsTypeBuilderFloatingPoint(self.handle) }
211 }
212
213 pub fn child_type(&self) -> Option<Conf<Ref<Type>>> {
214 let raw_target = unsafe { BNGetTypeBuilderChildType(self.handle) };
215 match raw_target.type_.is_null() {
216 false => Some(Conf::<Ref<Type>>::from_owned_raw(raw_target)),
217 true => None,
218 }
219 }
220
221 pub fn target(&self) -> Option<Conf<Ref<Type>>> {
223 self.child_type()
224 }
225
226 pub fn element_type(&self) -> Option<Conf<Ref<Type>>> {
228 self.child_type()
229 }
230
231 pub fn return_value(&self) -> Option<Conf<Ref<Type>>> {
233 self.child_type()
234 }
235
236 pub fn calling_convention(&self) -> Option<Conf<Ref<CoreCallingConvention>>> {
237 let raw_convention_confidence = unsafe { BNGetTypeBuilderCallingConvention(self.handle) };
238 match raw_convention_confidence.convention.is_null() {
239 false => Some(Conf::<Ref<CoreCallingConvention>>::from_owned_raw(
240 raw_convention_confidence,
241 )),
242 true => None,
243 }
244 }
245
246 pub fn parameters(&self) -> Option<Vec<FunctionParameter>> {
247 unsafe {
248 let mut count = 0;
249 let raw_parameters_ptr = BNGetTypeBuilderParameters(self.handle, &mut count);
250 match raw_parameters_ptr.is_null() {
251 false => {
252 let raw_parameters = std::slice::from_raw_parts(raw_parameters_ptr, count);
253 let parameters = raw_parameters
254 .iter()
255 .map(FunctionParameter::from_raw)
256 .collect();
257 BNFreeTypeParameterList(raw_parameters_ptr, count);
258 Some(parameters)
259 }
260 true => None,
261 }
262 }
263 }
264
265 pub fn has_variable_arguments(&self) -> Conf<bool> {
266 unsafe { BNTypeBuilderHasVariableArguments(self.handle).into() }
267 }
268
269 pub fn can_return(&self) -> Conf<bool> {
270 unsafe { BNFunctionTypeBuilderCanReturn(self.handle).into() }
271 }
272
273 pub fn pure(&self) -> Conf<bool> {
274 unsafe { BNIsTypeBuilderPure(self.handle).into() }
275 }
276
277 pub fn get_structure(&self) -> Option<Ref<Structure>> {
280 let raw_struct_ptr = unsafe { BNGetTypeBuilderStructure(self.handle) };
281 match raw_struct_ptr.is_null() {
282 false => Some(unsafe { Structure::ref_from_raw(raw_struct_ptr) }),
283 true => None,
284 }
285 }
286
287 pub fn get_enumeration(&self) -> Option<Ref<Enumeration>> {
290 let raw_enum_ptr = unsafe { BNGetTypeBuilderEnumeration(self.handle) };
291 match raw_enum_ptr.is_null() {
292 false => Some(unsafe { Enumeration::ref_from_raw(raw_enum_ptr) }),
293 true => None,
294 }
295 }
296
297 pub fn get_named_type_reference(&self) -> Option<Ref<NamedTypeReference>> {
300 let raw_type_ref_ptr = unsafe { BNGetTypeBuilderNamedTypeReference(self.handle) };
301 match raw_type_ref_ptr.is_null() {
302 false => Some(unsafe { NamedTypeReference::ref_from_raw(raw_type_ref_ptr) }),
303 true => None,
304 }
305 }
306
307 pub fn count(&self) -> u64 {
308 unsafe { BNGetTypeBuilderElementCount(self.handle) }
309 }
310
311 pub fn offset(&self) -> u64 {
312 unsafe { BNGetTypeBuilderOffset(self.handle) }
313 }
314
315 pub fn stack_adjustment(&self) -> Conf<i64> {
316 unsafe { BNGetTypeBuilderStackAdjustment(self.handle).into() }
317 }
318
319 pub fn pointer_base_type(&self) -> PointerBaseType {
320 unsafe { BNTypeBuilderGetPointerBaseType(self.handle) }
321 }
322
323 pub fn pointer_base_offset(&self) -> i64 {
324 unsafe { BNTypeBuilderGetPointerBaseOffset(self.handle) }
325 }
326
327 pub fn void() -> Self {
332 unsafe { Self::from_raw(BNCreateVoidTypeBuilder()) }
333 }
334
335 pub fn bool() -> Self {
337 unsafe { Self::from_raw(BNCreateBoolTypeBuilder()) }
338 }
339
340 pub fn char() -> Self {
342 Self::int(1, true)
343 }
344
345 pub fn int(width: usize, is_signed: bool) -> Self {
347 let mut is_signed = Conf::new(is_signed, MAX_CONFIDENCE).into();
348
349 unsafe {
350 Self::from_raw(BNCreateIntegerTypeBuilder(
351 width,
352 &mut is_signed,
353 c"".as_ptr() as _,
354 ))
355 }
356 }
357
358 pub fn named_int(width: usize, is_signed: bool, alt_name: &str) -> Self {
361 let mut is_signed = Conf::new(is_signed, MAX_CONFIDENCE).into();
362 let alt_name = alt_name.to_cstr();
363
364 unsafe {
365 Self::from_raw(BNCreateIntegerTypeBuilder(
366 width,
367 &mut is_signed,
368 alt_name.as_ref().as_ptr() as _,
369 ))
370 }
371 }
372
373 pub fn float(width: usize) -> Self {
375 unsafe { Self::from_raw(BNCreateFloatTypeBuilder(width, c"".as_ptr())) }
376 }
377
378 pub fn named_float(width: usize, alt_name: &str) -> Self {
380 let alt_name = alt_name.to_cstr();
381 unsafe { Self::from_raw(BNCreateFloatTypeBuilder(width, alt_name.as_ptr())) }
382 }
383
384 pub fn array<'a, T: Into<Conf<&'a Type>>>(ty: T, count: u64) -> Self {
386 let owned_raw_ty = Conf::<&Type>::into_raw(ty.into());
387 unsafe { Self::from_raw(BNCreateArrayTypeBuilder(&owned_raw_ty, count)) }
388 }
389
390 pub fn enumeration<T: Into<Conf<bool>>>(
398 enumeration: &Enumeration,
399 width: NonZeroUsize,
400 is_signed: T,
401 ) -> Self {
402 unsafe {
403 Self::from_raw(BNCreateEnumerationTypeBuilder(
404 std::ptr::null_mut(),
406 enumeration.handle,
407 width.get(),
408 &mut is_signed.into().into(),
409 ))
410 }
411 }
412
413 pub fn structure(structure_type: &Structure) -> Self {
415 unsafe { Self::from_raw(BNCreateStructureTypeBuilder(structure_type.handle)) }
416 }
417
418 pub fn named_type(type_reference: &NamedTypeReference) -> Self {
420 let mut is_const = Conf::new(false, MIN_CONFIDENCE).into();
421 let mut is_volatile = Conf::new(false, MIN_CONFIDENCE).into();
422 unsafe {
423 Self::from_raw(BNCreateNamedTypeReferenceBuilder(
424 type_reference.handle,
425 0,
426 1,
427 &mut is_const,
428 &mut is_volatile,
429 ))
430 }
431 }
432
433 pub fn named_type_from_type<T: Into<QualifiedName>>(name: T, t: &Type) -> Self {
435 let mut raw_name = QualifiedName::into_raw(name.into());
436 let id = c"";
437
438 let result = unsafe {
439 Self::from_raw(BNCreateNamedTypeReferenceBuilderFromTypeAndId(
440 id.as_ptr() as *mut _,
441 &mut raw_name,
442 t.handle,
443 ))
444 };
445 QualifiedName::free_raw(raw_name);
446 result
447 }
448
449 pub fn function<'a, T: Into<Conf<&'a Type>>>(
453 return_type: T,
454 parameters: Vec<FunctionParameter>,
455 variable_arguments: bool,
456 ) -> Self {
457 let mut owned_raw_return_type = Conf::<&Type>::into_raw(return_type.into());
458 let mut variable_arguments = Conf::new(variable_arguments, MAX_CONFIDENCE).into();
459 let mut can_return = Conf::new(true, MIN_CONFIDENCE).into();
460 let mut pure = Conf::new(false, MIN_CONFIDENCE).into();
461
462 let mut raw_calling_convention: BNCallingConventionWithConfidence =
463 BNCallingConventionWithConfidence {
464 convention: std::ptr::null_mut(),
465 confidence: MIN_CONFIDENCE,
466 };
467
468 let mut stack_adjust = Conf::new(0, MIN_CONFIDENCE).into();
469 let mut raw_parameters = parameters
470 .into_iter()
471 .map(FunctionParameter::into_raw)
472 .collect::<Vec<_>>();
473 let reg_stack_adjust_regs = std::ptr::null_mut();
474 let reg_stack_adjust_values = std::ptr::null_mut();
475
476 let mut return_regs: BNRegisterSetWithConfidence = BNRegisterSetWithConfidence {
477 regs: std::ptr::null_mut(),
478 count: 0,
479 confidence: 0,
480 };
481
482 let result = unsafe {
483 Self::from_raw(BNCreateFunctionTypeBuilder(
484 &mut owned_raw_return_type,
485 &mut raw_calling_convention,
486 raw_parameters.as_mut_ptr(),
487 raw_parameters.len(),
488 &mut variable_arguments,
489 &mut can_return,
490 &mut stack_adjust,
491 reg_stack_adjust_regs,
492 reg_stack_adjust_values,
493 0,
494 &mut return_regs,
495 BNNameType::NoNameType,
496 &mut pure,
497 ))
498 };
499
500 for raw_param in raw_parameters {
501 FunctionParameter::free_raw(raw_param);
502 }
503
504 result
505 }
506
507 pub fn function_with_opts<
511 'a,
512 T: Into<Conf<&'a Type>>,
513 C: Into<Conf<Ref<CoreCallingConvention>>>,
514 >(
515 return_type: T,
516 parameters: &[FunctionParameter],
517 variable_arguments: bool,
518 calling_convention: C,
519 stack_adjust: Conf<i64>,
520 ) -> Self {
521 let mut owned_raw_return_type = Conf::<&Type>::into_raw(return_type.into());
522 let mut variable_arguments = Conf::new(variable_arguments, MAX_CONFIDENCE).into();
523 let mut can_return = Conf::new(true, MIN_CONFIDENCE).into();
524 let mut pure = Conf::new(false, MIN_CONFIDENCE).into();
525
526 let mut owned_raw_calling_convention =
527 Conf::<Ref<CoreCallingConvention>>::into_owned_raw(&calling_convention.into());
528
529 let mut stack_adjust = stack_adjust.into();
530 let mut raw_parameters = parameters
531 .iter()
532 .cloned()
533 .map(FunctionParameter::into_raw)
534 .collect::<Vec<_>>();
535
536 let reg_stack_adjust_regs = std::ptr::null_mut();
538 let reg_stack_adjust_values = std::ptr::null_mut();
539
540 let mut return_regs: BNRegisterSetWithConfidence = BNRegisterSetWithConfidence {
541 regs: std::ptr::null_mut(),
542 count: 0,
543 confidence: 0,
544 };
545
546 let result = unsafe {
547 Self::from_raw(BNCreateFunctionTypeBuilder(
548 &mut owned_raw_return_type,
549 &mut owned_raw_calling_convention,
550 raw_parameters.as_mut_ptr(),
551 raw_parameters.len(),
552 &mut variable_arguments,
553 &mut can_return,
554 &mut stack_adjust,
555 reg_stack_adjust_regs,
556 reg_stack_adjust_values,
557 0,
558 &mut return_regs,
559 BNNameType::NoNameType,
560 &mut pure,
561 ))
562 };
563
564 for raw_param in raw_parameters {
565 FunctionParameter::free_raw(raw_param);
566 }
567
568 result
569 }
570
571 pub fn pointer<'a, A: Architecture, T: Into<Conf<&'a Type>>>(arch: &A, ty: T) -> Self {
573 Self::pointer_with_options(arch, ty, false, false, None)
574 }
575
576 pub fn const_pointer<'a, A: Architecture, T: Into<Conf<&'a Type>>>(arch: &A, ty: T) -> Self {
578 Self::pointer_with_options(arch, ty, true, false, None)
579 }
580
581 pub fn pointer_with_options<'a, A: Architecture, T: Into<Conf<&'a Type>>>(
582 arch: &A,
583 ty: T,
584 is_const: bool,
585 is_volatile: bool,
586 ref_type: Option<ReferenceType>,
587 ) -> Self {
588 let arch_ptr_size = arch.address_size();
589 Self::pointer_of_width(ty, arch_ptr_size, is_const, is_volatile, ref_type)
590 }
591
592 pub fn pointer_of_width<'a, T: Into<Conf<&'a Type>>>(
593 ty: T,
594 size: usize,
595 is_const: bool,
596 is_volatile: bool,
597 ref_type: Option<ReferenceType>,
598 ) -> Self {
599 let mut is_const = Conf::new(is_const, MAX_CONFIDENCE).into();
600 let mut is_volatile = Conf::new(is_volatile, MAX_CONFIDENCE).into();
601 let owned_raw_ty = Conf::<&Type>::into_raw(ty.into());
602 unsafe {
603 Self::from_raw(BNCreatePointerTypeBuilderOfWidth(
604 size,
605 &owned_raw_ty,
606 &mut is_const,
607 &mut is_volatile,
608 ref_type.unwrap_or(ReferenceType::PointerReferenceType),
609 ))
610 }
611 }
612}
613
614impl Display for TypeBuilder {
615 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
616 write!(f, "{}", unsafe {
617 BnString::into_string(BNGetTypeBuilderString(self.handle, std::ptr::null_mut()))
618 })
619 }
620}
621
622impl Drop for TypeBuilder {
623 fn drop(&mut self) {
624 unsafe { BNFreeTypeBuilder(self.handle) };
625 }
626}
627
628#[repr(transparent)]
663pub struct Type {
664 pub handle: *mut BNType,
665}
666
667impl Type {
668 pub unsafe fn from_raw(handle: *mut BNType) -> Self {
669 debug_assert!(!handle.is_null());
670 Self { handle }
671 }
672
673 pub unsafe fn ref_from_raw(handle: *mut BNType) -> Ref<Self> {
674 debug_assert!(!handle.is_null());
675 Ref::new(Self { handle })
676 }
677
678 pub fn to_builder(&self) -> TypeBuilder {
679 TypeBuilder::new(self)
680 }
681
682 pub fn type_class(&self) -> TypeClass {
683 unsafe { BNGetTypeClass(self.handle) }
684 }
685
686 pub fn width(&self) -> u64 {
690 unsafe { BNGetTypeWidth(self.handle) }
691 }
692
693 pub fn alignment(&self) -> usize {
694 unsafe { BNGetTypeAlignment(self.handle) }
695 }
696
697 pub fn is_signed(&self) -> Conf<bool> {
698 unsafe { BNIsTypeSigned(self.handle).into() }
699 }
700
701 pub fn integer_display_type(&self) -> IntegerDisplayType {
702 unsafe { BNGetIntegerTypeDisplayType(self.handle) }
703 }
704
705 pub fn is_const(&self) -> Conf<bool> {
706 unsafe { BNIsTypeConst(self.handle).into() }
707 }
708
709 pub fn is_volatile(&self) -> Conf<bool> {
710 unsafe { BNIsTypeVolatile(self.handle).into() }
711 }
712
713 pub fn is_floating_point(&self) -> bool {
714 unsafe { BNIsTypeFloatingPoint(self.handle) }
715 }
716
717 pub fn child_type(&self) -> Option<Conf<Ref<Type>>> {
718 let raw_target = unsafe { BNGetChildType(self.handle) };
719 match raw_target.type_.is_null() {
720 false => Some(Conf::<Ref<Type>>::from_owned_raw(raw_target)),
721 true => None,
722 }
723 }
724
725 pub fn target(&self) -> Option<Conf<Ref<Type>>> {
727 self.child_type()
728 }
729
730 pub fn element_type(&self) -> Option<Conf<Ref<Type>>> {
732 self.child_type()
733 }
734
735 pub fn return_value(&self) -> Option<Conf<Ref<Type>>> {
737 self.child_type()
738 }
739
740 pub fn calling_convention(&self) -> Option<Conf<Ref<CoreCallingConvention>>> {
741 let convention_confidence = unsafe { BNGetTypeCallingConvention(self.handle) };
742 match convention_confidence.convention.is_null() {
743 false => Some(Conf::<Ref<CoreCallingConvention>>::from_owned_raw(
744 convention_confidence,
745 )),
746 true => None,
747 }
748 }
749
750 pub fn parameters(&self) -> Option<Vec<FunctionParameter>> {
751 unsafe {
752 let mut count = 0;
753 let raw_parameters_ptr = BNGetTypeParameters(self.handle, &mut count);
754 match raw_parameters_ptr.is_null() {
755 false => {
756 let raw_parameters = std::slice::from_raw_parts(raw_parameters_ptr, count);
757 let parameters = raw_parameters
758 .iter()
759 .map(FunctionParameter::from_raw)
760 .collect();
761 BNFreeTypeParameterList(raw_parameters_ptr, count);
762 Some(parameters)
763 }
764 true => None,
765 }
766 }
767 }
768
769 pub fn has_variable_arguments(&self) -> Conf<bool> {
770 unsafe { BNTypeHasVariableArguments(self.handle).into() }
771 }
772
773 pub fn can_return(&self) -> Conf<bool> {
774 unsafe { BNFunctionTypeCanReturn(self.handle).into() }
775 }
776
777 pub fn pure(&self) -> Conf<bool> {
778 unsafe { BNIsTypePure(self.handle).into() }
779 }
780
781 pub fn get_structure(&self) -> Option<Ref<Structure>> {
784 let raw_struct_ptr = unsafe { BNGetTypeStructure(self.handle) };
785 match raw_struct_ptr.is_null() {
786 false => Some(unsafe { Structure::ref_from_raw(raw_struct_ptr) }),
787 true => None,
788 }
789 }
790
791 pub fn get_enumeration(&self) -> Option<Ref<Enumeration>> {
794 let raw_enum_ptr = unsafe { BNGetTypeEnumeration(self.handle) };
795 match raw_enum_ptr.is_null() {
796 false => Some(unsafe { Enumeration::ref_from_raw(raw_enum_ptr) }),
797 true => None,
798 }
799 }
800
801 pub fn get_named_type_reference(&self) -> Option<Ref<NamedTypeReference>> {
804 let raw_type_ref_ptr = unsafe { BNGetTypeNamedTypeReference(self.handle) };
805 match raw_type_ref_ptr.is_null() {
806 false => Some(unsafe { NamedTypeReference::ref_from_raw(raw_type_ref_ptr) }),
807 true => None,
808 }
809 }
810
811 pub fn count(&self) -> u64 {
812 unsafe { BNGetTypeElementCount(self.handle) }
813 }
814
815 pub fn offset(&self) -> u64 {
816 unsafe { BNGetTypeOffset(self.handle) }
817 }
818
819 pub fn stack_adjustment(&self) -> Conf<i64> {
820 unsafe { BNGetTypeStackAdjustment(self.handle).into() }
821 }
822
823 pub fn registered_name(&self) -> Option<Ref<NamedTypeReference>> {
824 let raw_type_ref_ptr = unsafe { BNGetRegisteredTypeName(self.handle) };
825 match raw_type_ref_ptr.is_null() {
826 false => Some(unsafe { NamedTypeReference::ref_from_raw(raw_type_ref_ptr) }),
827 true => None,
828 }
829 }
830
831 pub fn pointer_base_type(&self) -> BNPointerBaseType {
832 unsafe { BNTypeGetPointerBaseType(self.handle) }
833 }
834
835 pub fn pointer_base_offset(&self) -> i64 {
836 unsafe { BNTypeGetPointerBaseOffset(self.handle) }
837 }
838
839 pub fn void() -> Ref<Self> {
843 unsafe { Self::ref_from_raw(BNCreateVoidType()) }
844 }
845
846 pub fn bool() -> Ref<Self> {
847 unsafe { Self::ref_from_raw(BNCreateBoolType()) }
848 }
849
850 pub fn char() -> Ref<Self> {
851 Self::int(1, true)
852 }
853
854 pub fn wide_char(width: usize) -> Ref<Self> {
855 unsafe { Self::ref_from_raw(BNCreateWideCharType(width, c"".as_ptr())) }
856 }
857
858 pub fn int(width: usize, is_signed: bool) -> Ref<Self> {
859 let mut is_signed = Conf::new(is_signed, MAX_CONFIDENCE).into();
860 unsafe { Self::ref_from_raw(BNCreateIntegerType(width, &mut is_signed, c"".as_ptr())) }
861 }
862
863 pub fn named_int(width: usize, is_signed: bool, alt_name: &str) -> Ref<Self> {
864 let mut is_signed = Conf::new(is_signed, MAX_CONFIDENCE).into();
865 let alt_name = alt_name.to_cstr();
866
867 unsafe {
868 Self::ref_from_raw(BNCreateIntegerType(
869 width,
870 &mut is_signed,
871 alt_name.as_ptr(),
872 ))
873 }
874 }
875
876 pub fn float(width: usize) -> Ref<Self> {
877 unsafe { Self::ref_from_raw(BNCreateFloatType(width, c"".as_ptr())) }
878 }
879
880 pub fn named_float(width: usize, alt_name: &str) -> Ref<Self> {
881 let alt_name = alt_name.to_cstr();
882 unsafe { Self::ref_from_raw(BNCreateFloatType(width, alt_name.as_ptr())) }
883 }
884
885 pub fn array<'a, T: Into<Conf<&'a Type>>>(ty: T, count: u64) -> Ref<Self> {
886 let owned_raw_ty = Conf::<&Type>::into_raw(ty.into());
887 unsafe { Self::ref_from_raw(BNCreateArrayType(&owned_raw_ty, count)) }
888 }
889
890 pub fn enumeration<T: Into<Conf<bool>>>(
896 enumeration: &Enumeration,
897 width: NonZeroUsize,
898 is_signed: T,
899 ) -> Ref<Self> {
900 unsafe {
901 Self::ref_from_raw(BNCreateEnumerationType(
902 std::ptr::null_mut(),
904 enumeration.handle,
905 width.get(),
906 &mut is_signed.into().into(),
907 ))
908 }
909 }
910
911 pub fn structure(structure: &Structure) -> Ref<Self> {
912 unsafe { Self::ref_from_raw(BNCreateStructureType(structure.handle)) }
913 }
914
915 pub fn named_type(type_reference: &NamedTypeReference) -> Ref<Self> {
916 let mut is_const = Conf::new(false, MIN_CONFIDENCE).into();
917 let mut is_volatile = Conf::new(false, MIN_CONFIDENCE).into();
918 unsafe {
919 Self::ref_from_raw(BNCreateNamedTypeReference(
920 type_reference.handle,
921 0,
922 1,
923 &mut is_const,
924 &mut is_volatile,
925 ))
926 }
927 }
928
929 pub fn named_type_from_type<T: Into<QualifiedName>>(name: T, t: &Type) -> Ref<Self> {
930 let mut raw_name = QualifiedName::into_raw(name.into());
931 let id = c"";
933
934 let result = unsafe {
935 Self::ref_from_raw(BNCreateNamedTypeReferenceFromTypeAndId(
936 id.as_ptr(),
937 &mut raw_name,
938 t.handle,
939 ))
940 };
941 QualifiedName::free_raw(raw_name);
942 result
943 }
944
945 pub fn function<'a, T: Into<Conf<&'a Type>>>(
947 return_type: T,
948 parameters: Vec<FunctionParameter>,
949 variable_arguments: bool,
950 ) -> Ref<Self> {
951 let mut owned_raw_return_type = Conf::<&Type>::into_raw(return_type.into());
952 let mut variable_arguments = Conf::new(variable_arguments, MAX_CONFIDENCE).into();
953 let mut can_return = Conf::new(true, MIN_CONFIDENCE).into();
954 let mut pure = Conf::new(false, MIN_CONFIDENCE).into();
955
956 let mut raw_calling_convention: BNCallingConventionWithConfidence =
957 BNCallingConventionWithConfidence {
958 convention: std::ptr::null_mut(),
959 confidence: MIN_CONFIDENCE,
960 };
961
962 let mut stack_adjust = Conf::new(0, MIN_CONFIDENCE).into();
963 let mut raw_parameters = parameters
964 .into_iter()
965 .map(FunctionParameter::into_raw)
966 .collect::<Vec<_>>();
967 let reg_stack_adjust_regs = std::ptr::null_mut();
968 let reg_stack_adjust_values = std::ptr::null_mut();
969
970 let mut return_regs: BNRegisterSetWithConfidence = BNRegisterSetWithConfidence {
971 regs: std::ptr::null_mut(),
972 count: 0,
973 confidence: 0,
974 };
975
976 let result = unsafe {
977 Self::ref_from_raw(BNCreateFunctionType(
978 &mut owned_raw_return_type,
979 &mut raw_calling_convention,
980 raw_parameters.as_mut_ptr(),
981 raw_parameters.len(),
982 &mut variable_arguments,
983 &mut can_return,
984 &mut stack_adjust,
985 reg_stack_adjust_regs,
986 reg_stack_adjust_values,
987 0,
988 &mut return_regs,
989 BNNameType::NoNameType,
990 &mut pure,
991 ))
992 };
993
994 for raw_param in raw_parameters {
995 FunctionParameter::free_raw(raw_param);
996 }
997
998 result
999 }
1000
1001 pub fn function_with_opts<
1003 'a,
1004 T: Into<Conf<&'a Type>>,
1005 C: Into<Conf<Ref<CoreCallingConvention>>>,
1006 >(
1007 return_type: T,
1008 parameters: &[FunctionParameter],
1009 variable_arguments: bool,
1010 calling_convention: C,
1011 stack_adjust: Conf<i64>,
1012 ) -> Ref<Self> {
1013 let mut owned_raw_return_type = Conf::<&Type>::into_raw(return_type.into());
1014 let mut variable_arguments = Conf::new(variable_arguments, MAX_CONFIDENCE).into();
1015 let mut can_return = Conf::new(true, MIN_CONFIDENCE).into();
1016 let mut pure = Conf::new(false, MIN_CONFIDENCE).into();
1017
1018 let mut owned_raw_calling_convention =
1019 Conf::<Ref<CoreCallingConvention>>::into_owned_raw(&calling_convention.into());
1020
1021 let mut stack_adjust = stack_adjust.into();
1022 let mut raw_parameters = parameters
1023 .iter()
1024 .cloned()
1025 .map(FunctionParameter::into_raw)
1026 .collect::<Vec<_>>();
1027
1028 let reg_stack_adjust_regs = std::ptr::null_mut();
1030 let reg_stack_adjust_values = std::ptr::null_mut();
1031
1032 let mut return_regs: BNRegisterSetWithConfidence = BNRegisterSetWithConfidence {
1033 regs: std::ptr::null_mut(),
1034 count: 0,
1035 confidence: 0,
1036 };
1037
1038 let result = unsafe {
1039 Self::ref_from_raw(BNCreateFunctionType(
1040 &mut owned_raw_return_type,
1041 &mut owned_raw_calling_convention,
1042 raw_parameters.as_mut_ptr(),
1043 raw_parameters.len(),
1044 &mut variable_arguments,
1045 &mut can_return,
1046 &mut stack_adjust,
1047 reg_stack_adjust_regs,
1048 reg_stack_adjust_values,
1049 0,
1050 &mut return_regs,
1051 BNNameType::NoNameType,
1052 &mut pure,
1053 ))
1054 };
1055
1056 for raw_param in raw_parameters {
1057 FunctionParameter::free_raw(raw_param);
1058 }
1059
1060 result
1061 }
1062
1063 pub fn pointer<'a, A: Architecture, T: Into<Conf<&'a Type>>>(arch: &A, ty: T) -> Ref<Self> {
1064 Self::pointer_with_options(arch, ty, false, false, None)
1065 }
1066
1067 pub fn const_pointer<'a, A: Architecture, T: Into<Conf<&'a Type>>>(
1068 arch: &A,
1069 ty: T,
1070 ) -> Ref<Self> {
1071 Self::pointer_with_options(arch, ty, true, false, None)
1072 }
1073
1074 pub fn pointer_with_options<'a, A: Architecture, T: Into<Conf<&'a Type>>>(
1075 arch: &A,
1076 ty: T,
1077 is_const: bool,
1078 is_volatile: bool,
1079 ref_type: Option<ReferenceType>,
1080 ) -> Ref<Self> {
1081 let arch_pointer_size = arch.address_size();
1082 Self::pointer_of_width(ty, arch_pointer_size, is_const, is_volatile, ref_type)
1083 }
1084
1085 pub fn pointer_of_width<'a, T: Into<Conf<&'a Type>>>(
1086 ty: T,
1087 size: usize,
1088 is_const: bool,
1089 is_volatile: bool,
1090 ref_type: Option<ReferenceType>,
1091 ) -> Ref<Self> {
1092 let mut is_const = Conf::new(is_const, MAX_CONFIDENCE).into();
1093 let mut is_volatile = Conf::new(is_volatile, MAX_CONFIDENCE).into();
1094 let owned_raw_ty = Conf::<&Type>::into_raw(ty.into());
1095 unsafe {
1096 Self::ref_from_raw(BNCreatePointerTypeOfWidth(
1097 size,
1098 &owned_raw_ty,
1099 &mut is_const,
1100 &mut is_volatile,
1101 ref_type.unwrap_or(ReferenceType::PointerReferenceType),
1102 ))
1103 }
1104 }
1105
1106 pub fn generate_auto_demangled_type_id<T: Into<QualifiedName>>(name: T) -> String {
1107 let mut raw_name = QualifiedName::into_raw(name.into());
1108 let type_id =
1109 unsafe { BnString::into_string(BNGenerateAutoDemangledTypeId(&mut raw_name)) };
1110 QualifiedName::free_raw(raw_name);
1111 type_id
1112 }
1113}
1114
1115impl Display for Type {
1116 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1117 write!(f, "{}", unsafe {
1118 BnString::into_string(BNGetTypeString(
1119 self.handle,
1120 std::ptr::null_mut(),
1121 BNTokenEscapingType::NoTokenEscapingType,
1122 ))
1123 })
1124 }
1125}
1126
1127impl Debug for Type {
1128 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1129 f.debug_struct("Type")
1134 .field("type_class", &self.type_class())
1135 .field("width", &self.width())
1136 .field("alignment", &self.alignment())
1137 .field("is_signed", &self.is_signed())
1138 .field("is_const", &self.is_const())
1139 .field("is_volatile", &self.is_volatile())
1140 .field("child_type", &self.child_type())
1141 .field("calling_convention", &self.calling_convention())
1142 .field("parameters", &self.parameters())
1143 .field("has_variable_arguments", &self.has_variable_arguments())
1144 .field("can_return", &self.can_return())
1145 .field("pure", &self.pure())
1146 .field("get_structure", &self.get_structure())
1147 .field("get_enumeration", &self.get_enumeration())
1148 .field("get_named_type_reference", &self.get_named_type_reference())
1149 .field("count", &self.count())
1150 .field("offset", &self.offset())
1151 .field("stack_adjustment", &self.stack_adjustment())
1152 .field("registered_name", &self.registered_name())
1153 .finish()
1154 }
1155}
1156
1157impl PartialEq for Type {
1158 fn eq(&self, other: &Self) -> bool {
1159 unsafe { BNTypesEqual(self.handle, other.handle) }
1160 }
1161}
1162
1163impl Eq for Type {}
1164
1165impl Hash for Type {
1166 fn hash<H: Hasher>(&self, state: &mut H) {
1167 self.handle.hash(state);
1168 }
1169}
1170
1171unsafe impl Send for Type {}
1172unsafe impl Sync for Type {}
1173
1174unsafe impl RefCountable for Type {
1175 unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
1176 Self::ref_from_raw(BNNewTypeReference(handle.handle))
1177 }
1178
1179 unsafe fn dec_ref(handle: &Self) {
1180 BNFreeType(handle.handle);
1181 }
1182}
1183
1184impl ToOwned for Type {
1185 type Owned = Ref<Self>;
1186
1187 fn to_owned(&self) -> Self::Owned {
1188 unsafe { RefCountable::inc_ref(self) }
1189 }
1190}
1191
1192impl CoreArrayProvider for Type {
1193 type Raw = *mut BNType;
1194 type Context = ();
1195 type Wrapped<'a> = &'a Self;
1196}
1197
1198unsafe impl CoreArrayProviderInner for Type {
1199 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
1200 BNFreeTypeList(raw, count)
1201 }
1202
1203 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
1204 std::mem::transmute(raw)
1206 }
1207}
1208
1209#[derive(Debug, Clone, Hash, PartialEq, Eq)]
1210pub struct FunctionParameter {
1211 pub ty: Conf<Ref<Type>>,
1212 pub name: String,
1213 pub location: Option<Variable>,
1214}
1215
1216impl FunctionParameter {
1217 pub(crate) fn from_raw(value: &BNFunctionParameter) -> Self {
1218 let name = if value.name.is_null() {
1221 if value.location.type_ == VariableSourceType::RegisterVariableSourceType {
1222 format!("reg_{}", value.location.storage)
1223 } else if value.location.type_ == VariableSourceType::StackVariableSourceType {
1224 format!("arg_{}", value.location.storage)
1225 } else {
1226 String::new()
1227 }
1228 } else {
1229 raw_to_string(value.name as *const _).unwrap()
1230 };
1231
1232 Self {
1233 ty: Conf::new(
1234 unsafe { Type::from_raw(value.type_).to_owned() },
1235 value.typeConfidence,
1236 ),
1237 name,
1238 location: match value.defaultLocation {
1239 false => Some(Variable::from(value.location)),
1240 true => None,
1241 },
1242 }
1243 }
1244
1245 #[allow(unused)]
1246 pub(crate) fn from_owned_raw(value: BNFunctionParameter) -> Self {
1247 let owned = Self::from_raw(&value);
1248 Self::free_raw(value);
1249 owned
1250 }
1251
1252 pub(crate) fn into_raw(value: Self) -> BNFunctionParameter {
1253 let bn_name = BnString::new(value.name);
1254 BNFunctionParameter {
1255 name: BnString::into_raw(bn_name),
1256 type_: unsafe { Ref::into_raw(value.ty.contents) }.handle,
1257 typeConfidence: value.ty.confidence,
1258 defaultLocation: value.location.is_none(),
1259 location: value.location.map(Into::into).unwrap_or_default(),
1260 }
1261 }
1262
1263 pub(crate) fn free_raw(value: BNFunctionParameter) {
1264 unsafe { BnString::free_raw(value.name) };
1265 let _ = unsafe { Type::ref_from_raw(value.type_) };
1266 }
1267
1268 pub fn new<T: Into<Conf<Ref<Type>>>>(ty: T, name: String, location: Option<Variable>) -> Self {
1269 Self {
1270 ty: ty.into(),
1271 name,
1272 location,
1273 }
1274 }
1275}
1276
1277#[derive(PartialEq, Eq, Hash)]
1278pub struct NamedTypeReference {
1279 pub(crate) handle: *mut BNNamedTypeReference,
1280}
1281
1282impl NamedTypeReference {
1283 pub(crate) unsafe fn from_raw(handle: *mut BNNamedTypeReference) -> Self {
1284 debug_assert!(!handle.is_null());
1285 Self { handle }
1286 }
1287
1288 pub(crate) unsafe fn ref_from_raw(handle: *mut BNNamedTypeReference) -> Ref<Self> {
1289 debug_assert!(!handle.is_null());
1290 Ref::new(Self { handle })
1291 }
1292
1293 pub fn new<T: Into<QualifiedName>>(type_class: NamedTypeReferenceClass, name: T) -> Ref<Self> {
1299 let mut raw_name = QualifiedName::into_raw(name.into());
1300 let result = unsafe {
1301 Self::ref_from_raw(BNCreateNamedType(
1302 type_class,
1303 std::ptr::null(),
1304 &mut raw_name,
1305 ))
1306 };
1307 QualifiedName::free_raw(raw_name);
1308 result
1309 }
1310
1311 pub fn new_with_id<T: Into<QualifiedName>>(
1317 type_class: NamedTypeReferenceClass,
1318 type_id: &str,
1319 name: T,
1320 ) -> Ref<Self> {
1321 let type_id = type_id.to_cstr();
1322 let mut raw_name = QualifiedName::into_raw(name.into());
1323 let result = unsafe {
1324 Self::ref_from_raw(BNCreateNamedType(
1325 type_class,
1326 type_id.as_ref().as_ptr() as _,
1327 &mut raw_name,
1328 ))
1329 };
1330 QualifiedName::free_raw(raw_name);
1331 result
1332 }
1333
1334 pub fn name(&self) -> QualifiedName {
1335 let raw_name = unsafe { BNGetTypeReferenceName(self.handle) };
1336 QualifiedName::from_owned_raw(raw_name)
1337 }
1338
1339 pub fn id(&self) -> String {
1340 unsafe { BnString::into_string(BNGetTypeReferenceId(self.handle)) }
1341 }
1342
1343 pub fn class(&self) -> NamedTypeReferenceClass {
1344 unsafe { BNGetTypeReferenceClass(self.handle) }
1345 }
1346
1347 fn target_helper(&self, bv: &BinaryView, visited: &mut HashSet<String>) -> Option<Ref<Type>> {
1348 let ty = bv.type_by_id(&self.id())?;
1349 match ty.type_class() {
1350 TypeClass::NamedTypeReferenceClass => {
1351 let ntr = ty
1353 .get_named_type_reference()
1354 .expect("NTR type class should always have a valid NTR");
1355 match visited.insert(ntr.id()) {
1356 true => ntr.target_helper(bv, visited),
1357 false => None,
1359 }
1360 }
1361 _ => Some(ty),
1363 }
1364 }
1365
1366 pub fn target(&self, bv: &BinaryView) -> Option<Ref<Type>> {
1370 self.target_helper(bv, &mut HashSet::new())
1371 }
1372}
1373
1374impl ToOwned for NamedTypeReference {
1375 type Owned = Ref<Self>;
1376
1377 fn to_owned(&self) -> Self::Owned {
1378 unsafe { RefCountable::inc_ref(self) }
1379 }
1380}
1381
1382unsafe impl RefCountable for NamedTypeReference {
1383 unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
1384 Self::ref_from_raw(BNNewNamedTypeReference(handle.handle))
1385 }
1386
1387 unsafe fn dec_ref(handle: &Self) {
1388 BNFreeNamedTypeReference(handle.handle)
1389 }
1390}
1391
1392impl Debug for NamedTypeReference {
1393 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1394 write!(f, "{} (id: {})", self.name(), self.id())
1395 }
1396}
1397
1398#[derive(Debug, Clone, Hash, PartialEq, Eq)]
1399pub struct QualifiedNameAndType {
1400 pub name: QualifiedName,
1401 pub ty: Ref<Type>,
1402}
1403
1404impl QualifiedNameAndType {
1405 pub(crate) fn from_raw(value: &BNQualifiedNameAndType) -> Self {
1406 Self {
1407 name: QualifiedName::from_raw(&value.name),
1408 ty: unsafe { Type::from_raw(value.type_).to_owned() },
1409 }
1410 }
1411
1412 pub(crate) fn from_owned_raw(value: BNQualifiedNameAndType) -> Self {
1413 let owned = Self::from_raw(&value);
1414 Self::free_raw(value);
1415 owned
1416 }
1417
1418 pub(crate) fn into_raw(value: Self) -> BNQualifiedNameAndType {
1419 BNQualifiedNameAndType {
1420 name: QualifiedName::into_raw(value.name),
1421 type_: unsafe { Ref::into_raw(value.ty).handle },
1422 }
1423 }
1424
1425 pub(crate) fn free_raw(value: BNQualifiedNameAndType) {
1426 QualifiedName::free_raw(value.name);
1427 let _ = unsafe { Type::ref_from_raw(value.type_) };
1428 }
1429
1430 pub fn new(name: QualifiedName, ty: Ref<Type>) -> Self {
1431 Self { name, ty }
1432 }
1433}
1434
1435impl<T> From<(T, Ref<Type>)> for QualifiedNameAndType
1436where
1437 T: Into<QualifiedName>,
1438{
1439 fn from(value: (T, Ref<Type>)) -> Self {
1440 Self {
1441 name: value.0.into(),
1442 ty: value.1,
1443 }
1444 }
1445}
1446
1447impl<T> From<(T, &Type)> for QualifiedNameAndType
1448where
1449 T: Into<QualifiedName>,
1450{
1451 fn from(value: (T, &Type)) -> Self {
1452 let ty = value.1.to_owned();
1453 Self {
1454 name: value.0.into(),
1455 ty,
1456 }
1457 }
1458}
1459
1460impl CoreArrayProvider for QualifiedNameAndType {
1461 type Raw = BNQualifiedNameAndType;
1462 type Context = ();
1463 type Wrapped<'a> = Self;
1464}
1465
1466unsafe impl CoreArrayProviderInner for QualifiedNameAndType {
1467 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
1468 BNFreeTypeAndNameList(raw, count);
1469 }
1470
1471 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
1472 QualifiedNameAndType::from_raw(raw)
1473 }
1474}
1475
1476#[derive(Debug, Clone, Hash, PartialEq, Eq)]
1477pub struct QualifiedNameTypeAndId {
1478 pub name: QualifiedName,
1479 pub ty: Ref<Type>,
1480 pub id: String,
1481}
1482
1483impl QualifiedNameTypeAndId {
1484 pub(crate) fn from_raw(value: &BNQualifiedNameTypeAndId) -> Self {
1485 Self {
1486 name: QualifiedName::from_raw(&value.name),
1487 ty: unsafe { Type::from_raw(value.type_) }.to_owned(),
1488 id: raw_to_string(value.id).unwrap(),
1489 }
1490 }
1491
1492 #[allow(unused)]
1493 pub(crate) fn from_owned_raw(value: BNQualifiedNameTypeAndId) -> Self {
1494 let owned = Self::from_raw(&value);
1495 Self::free_raw(value);
1496 owned
1497 }
1498
1499 pub(crate) fn into_raw(value: Self) -> BNQualifiedNameTypeAndId {
1500 let bn_id = BnString::new(value.id);
1501 BNQualifiedNameTypeAndId {
1502 name: QualifiedName::into_raw(value.name),
1503 id: BnString::into_raw(bn_id),
1504 type_: unsafe { Ref::into_raw(value.ty) }.handle,
1505 }
1506 }
1507
1508 pub(crate) fn free_raw(value: BNQualifiedNameTypeAndId) {
1509 QualifiedName::free_raw(value.name);
1510 let _ = unsafe { Type::ref_from_raw(value.type_) };
1511 let _ = unsafe { BnString::from_raw(value.id) };
1512 }
1513}
1514
1515impl CoreArrayProvider for QualifiedNameTypeAndId {
1516 type Raw = BNQualifiedNameTypeAndId;
1517 type Context = ();
1518 type Wrapped<'a> = QualifiedNameTypeAndId;
1519}
1520
1521unsafe impl CoreArrayProviderInner for QualifiedNameTypeAndId {
1522 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
1523 BNFreeTypeIdList(raw, count);
1524 }
1525
1526 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
1527 QualifiedNameTypeAndId::from_raw(raw)
1528 }
1529}
1530
1531#[derive(Debug, Clone, Eq, PartialEq, Hash)]
1536pub struct NameAndType {
1537 pub name: String,
1538 pub ty: Conf<Ref<Type>>,
1539}
1540
1541impl NameAndType {
1542 pub(crate) fn from_raw(value: &BNNameAndType) -> Self {
1543 Self {
1544 name: raw_to_string(value.name as *mut _).unwrap(),
1546 ty: Conf::new(
1547 unsafe { Type::from_raw(value.type_).to_owned() },
1548 value.typeConfidence,
1549 ),
1550 }
1551 }
1552
1553 #[allow(unused)]
1554 pub(crate) fn from_owned_raw(value: BNNameAndType) -> Self {
1555 let owned = Self::from_raw(&value);
1556 Self::free_raw(value);
1557 owned
1558 }
1559
1560 pub(crate) fn into_raw(value: Self) -> BNNameAndType {
1561 let bn_name = BnString::new(value.name);
1562 BNNameAndType {
1563 name: BnString::into_raw(bn_name),
1564 type_: unsafe { Ref::into_raw(value.ty.contents) }.handle,
1565 typeConfidence: value.ty.confidence,
1566 }
1567 }
1568
1569 pub(crate) fn free_raw(value: BNNameAndType) {
1570 unsafe { BnString::free_raw(value.name) };
1571 let _ = unsafe { Type::ref_from_raw(value.type_) };
1572 }
1573
1574 pub fn new(name: impl Into<String>, ty: Conf<Ref<Type>>) -> Self {
1575 Self {
1576 name: name.into(),
1577 ty,
1578 }
1579 }
1580}
1581
1582impl CoreArrayProvider for NameAndType {
1583 type Raw = BNNameAndType;
1584 type Context = ();
1585 type Wrapped<'a> = Self;
1586}
1587
1588unsafe impl CoreArrayProviderInner for NameAndType {
1589 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
1590 BNFreeNameAndTypeList(raw, count);
1591 }
1592
1593 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
1594 NameAndType::from_raw(raw)
1595 }
1596}