11use binaryninjacore_sys:: * ;
22
3+ use crate :: rc:: { Guard , RefCountable } ;
34use crate :: {
45 architecture:: CoreArchitecture ,
56 metadata:: Metadata ,
@@ -8,45 +9,37 @@ use crate::{
89 string:: { BnString , IntoCStr } ,
910 types:: { QualifiedName , QualifiedNameAndType , Type } ,
1011} ;
11- use core:: { ffi, mem, ptr} ;
1212use std:: path:: Path ;
13+ use std:: ptr:: NonNull ;
1314
1415#[ repr( transparent) ]
1516pub struct TypeLibrary {
16- handle : ptr :: NonNull < BNTypeLibrary > ,
17+ handle : NonNull < BNTypeLibrary > ,
1718}
1819
1920impl TypeLibrary {
20- pub ( crate ) unsafe fn from_raw ( handle : ptr :: NonNull < BNTypeLibrary > ) -> Self {
21+ pub ( crate ) unsafe fn from_raw ( handle : NonNull < BNTypeLibrary > ) -> Self {
2122 Self { handle }
2223 }
2324
24- pub ( crate ) unsafe fn ref_from_raw ( handle : & * mut BNTypeLibrary ) -> & Self {
25- assert ! ( !handle. is_null( ) ) ;
26- mem:: transmute ( handle)
25+ pub ( crate ) unsafe fn ref_from_raw ( handle : NonNull < BNTypeLibrary > ) -> Ref < Self > {
26+ Ref :: new ( Self { handle } )
2727 }
2828
2929 #[ allow( clippy:: mut_from_ref) ]
3030 pub ( crate ) unsafe fn as_raw ( & self ) -> & mut BNTypeLibrary {
3131 & mut * self . handle . as_ptr ( )
3232 }
3333
34- pub fn new_reference ( & self ) -> Self {
35- unsafe {
36- Self :: from_raw ( ptr:: NonNull :: new ( BNNewTypeLibraryReference ( self . as_raw ( ) ) ) . unwrap ( ) )
37- }
38- }
39-
40- pub fn new_duplicated ( & self ) -> Self {
41- unsafe { Self :: from_raw ( ptr:: NonNull :: new ( BNDuplicateTypeLibrary ( self . as_raw ( ) ) ) . unwrap ( ) ) }
34+ pub fn new_duplicated ( & self ) -> Ref < Self > {
35+ unsafe { Self :: ref_from_raw ( NonNull :: new ( BNDuplicateTypeLibrary ( self . as_raw ( ) ) ) . unwrap ( ) ) }
4236 }
4337
4438 /// Creates an empty type library object with a random GUID and the provided name.
45- pub fn new ( arch : CoreArchitecture , name : & str ) -> TypeLibrary {
39+ pub fn new ( arch : CoreArchitecture , name : & str ) -> Ref < TypeLibrary > {
4640 let name = name. to_cstr ( ) ;
47- let new_lib =
48- unsafe { BNNewTypeLibrary ( arch. handle , name. as_ref ( ) . as_ptr ( ) as * const ffi:: c_char ) } ;
49- unsafe { TypeLibrary :: from_raw ( ptr:: NonNull :: new ( new_lib) . unwrap ( ) ) }
41+ let new_lib = unsafe { BNNewTypeLibrary ( arch. handle , name. as_ptr ( ) ) } ;
42+ unsafe { TypeLibrary :: ref_from_raw ( NonNull :: new ( new_lib) . unwrap ( ) ) }
5043 }
5144
5245 pub fn all ( arch : CoreArchitecture ) -> Array < TypeLibrary > {
@@ -60,47 +53,35 @@ impl TypeLibrary {
6053 pub fn decompress_to_file ( path : & Path , output_path : & Path ) -> bool {
6154 let path = path. to_cstr ( ) ;
6255 let output = output_path. to_cstr ( ) ;
63- unsafe {
64- BNTypeLibraryDecompressToFile (
65- path. as_ref ( ) . as_ptr ( ) as * const ffi:: c_char ,
66- output. as_ref ( ) . as_ptr ( ) as * const ffi:: c_char ,
67- )
68- }
56+ unsafe { BNTypeLibraryDecompressToFile ( path. as_ptr ( ) , output. as_ptr ( ) ) }
6957 }
7058
7159 /// Loads a finalized type library instance from file
72- pub fn load_from_file ( path : & Path ) -> Option < TypeLibrary > {
60+ pub fn load_from_file ( path : & Path ) -> Option < Ref < TypeLibrary > > {
7361 let path = path. to_cstr ( ) ;
74- let handle =
75- unsafe { BNLoadTypeLibraryFromFile ( path. as_ref ( ) . as_ptr ( ) as * const ffi:: c_char ) } ;
76- ptr:: NonNull :: new ( handle) . map ( |h| unsafe { TypeLibrary :: from_raw ( h) } )
62+ let handle = unsafe { BNLoadTypeLibraryFromFile ( path. as_ptr ( ) ) } ;
63+ NonNull :: new ( handle) . map ( |h| unsafe { TypeLibrary :: ref_from_raw ( h) } )
7764 }
7865
7966 /// Saves a finalized type library instance to file
8067 pub fn write_to_file ( & self , path : & Path ) -> bool {
8168 let path = path. to_cstr ( ) ;
82- unsafe {
83- BNWriteTypeLibraryToFile ( self . as_raw ( ) , path. as_ref ( ) . as_ptr ( ) as * const ffi:: c_char )
84- }
69+ unsafe { BNWriteTypeLibraryToFile ( self . as_raw ( ) , path. as_ptr ( ) ) }
8570 }
8671
8772 /// Looks up the first type library found with a matching name. Keep in mind that names are not
8873 /// necessarily unique.
89- pub fn from_name ( arch : CoreArchitecture , name : & str ) -> Option < TypeLibrary > {
74+ pub fn from_name ( arch : CoreArchitecture , name : & str ) -> Option < Ref < TypeLibrary > > {
9075 let name = name. to_cstr ( ) ;
91- let handle = unsafe {
92- BNLookupTypeLibraryByName ( arch. handle , name. as_ref ( ) . as_ptr ( ) as * const ffi:: c_char )
93- } ;
94- ptr:: NonNull :: new ( handle) . map ( |h| unsafe { TypeLibrary :: from_raw ( h) } )
76+ let handle = unsafe { BNLookupTypeLibraryByName ( arch. handle , name. as_ptr ( ) ) } ;
77+ NonNull :: new ( handle) . map ( |h| unsafe { TypeLibrary :: ref_from_raw ( h) } )
9578 }
9679
9780 /// Attempts to grab a type library associated with the provided Architecture and GUID pair
98- pub fn from_guid ( arch : CoreArchitecture , guid : & str ) -> Option < TypeLibrary > {
81+ pub fn from_guid ( arch : CoreArchitecture , guid : & str ) -> Option < Ref < TypeLibrary > > {
9982 let guid = guid. to_cstr ( ) ;
100- let handle = unsafe {
101- BNLookupTypeLibraryByGuid ( arch. handle , guid. as_ref ( ) . as_ptr ( ) as * const ffi:: c_char )
102- } ;
103- ptr:: NonNull :: new ( handle) . map ( |h| unsafe { TypeLibrary :: from_raw ( h) } )
83+ let handle = unsafe { BNLookupTypeLibraryByGuid ( arch. handle , guid. as_ptr ( ) ) } ;
84+ NonNull :: new ( handle) . map ( |h| unsafe { TypeLibrary :: ref_from_raw ( h) } )
10485 }
10586
10687 /// The Architecture this type library is associated with
@@ -119,9 +100,7 @@ impl TypeLibrary {
119100 /// Sets the name of a type library instance that has not been finalized
120101 pub fn set_name ( & self , value : & str ) {
121102 let value = value. to_cstr ( ) ;
122- unsafe {
123- BNSetTypeLibraryName ( self . as_raw ( ) , value. as_ref ( ) . as_ptr ( ) as * const ffi:: c_char )
124- }
103+ unsafe { BNSetTypeLibraryName ( self . as_raw ( ) , value. as_ptr ( ) ) }
125104 }
126105
127106 /// The `dependency_name` of a library is the name used to record dependencies across
@@ -137,12 +116,7 @@ impl TypeLibrary {
137116 /// Sets the dependency name of a type library instance that has not been finalized
138117 pub fn set_dependency_name ( & self , value : & str ) {
139118 let value = value. to_cstr ( ) ;
140- unsafe {
141- BNSetTypeLibraryDependencyName (
142- self . as_raw ( ) ,
143- value. as_ref ( ) . as_ptr ( ) as * const ffi:: c_char ,
144- )
145- }
119+ unsafe { BNSetTypeLibraryDependencyName ( self . as_raw ( ) , value. as_ptr ( ) ) }
146120 }
147121
148122 /// Returns the GUID associated with the type library
@@ -154,9 +128,7 @@ impl TypeLibrary {
154128 /// Sets the GUID of a type library instance that has not been finalized
155129 pub fn set_guid ( & self , value : & str ) {
156130 let value = value. to_cstr ( ) ;
157- unsafe {
158- BNSetTypeLibraryGuid ( self . as_raw ( ) , value. as_ref ( ) . as_ptr ( ) as * const ffi:: c_char )
159- }
131+ unsafe { BNSetTypeLibraryGuid ( self . as_raw ( ) , value. as_ptr ( ) ) }
160132 }
161133
162134 /// A list of extra names that will be considered a match by [Platform::get_type_libraries_by_name]
@@ -170,12 +142,7 @@ impl TypeLibrary {
170142 /// Adds an extra name to this type library used during library lookups and dependency resolution
171143 pub fn add_alternate_name ( & self , value : & str ) {
172144 let value = value. to_cstr ( ) ;
173- unsafe {
174- BNAddTypeLibraryAlternateName (
175- self . as_raw ( ) ,
176- value. as_ref ( ) . as_ptr ( ) as * const ffi:: c_char ,
177- )
178- }
145+ unsafe { BNAddTypeLibraryAlternateName ( self . as_raw ( ) , value. as_ptr ( ) ) }
179146 }
180147
181148 /// Returns a list of all platform names that this type library will register with during platform
@@ -214,9 +181,7 @@ impl TypeLibrary {
214181 /// Retrieves a metadata associated with the given key stored in the type library
215182 pub fn query_metadata ( & self , key : & str ) -> Option < Metadata > {
216183 let key = key. to_cstr ( ) ;
217- let result = unsafe {
218- BNTypeLibraryQueryMetadata ( self . as_raw ( ) , key. as_ref ( ) . as_ptr ( ) as * const ffi:: c_char )
219- } ;
184+ let result = unsafe { BNTypeLibraryQueryMetadata ( self . as_raw ( ) , key. as_ptr ( ) ) } ;
220185 ( !result. is_null ( ) ) . then ( || unsafe { Metadata :: from_raw ( result) } )
221186 }
222187
@@ -233,21 +198,13 @@ impl TypeLibrary {
233198 /// * `md` - object to store.
234199 pub fn store_metadata ( & self , key : & str , md : & Metadata ) {
235200 let key = key. to_cstr ( ) ;
236- unsafe {
237- BNTypeLibraryStoreMetadata (
238- self . as_raw ( ) ,
239- key. as_ref ( ) . as_ptr ( ) as * const ffi:: c_char ,
240- md. handle ,
241- )
242- }
201+ unsafe { BNTypeLibraryStoreMetadata ( self . as_raw ( ) , key. as_ptr ( ) , md. handle ) }
243202 }
244203
245204 /// Removes the metadata associated with key from the current type library.
246205 pub fn remove_metadata ( & self , key : & str ) {
247206 let key = key. to_cstr ( ) ;
248- unsafe {
249- BNTypeLibraryRemoveMetadata ( self . as_raw ( ) , key. as_ref ( ) . as_ptr ( ) as * const ffi:: c_char )
250- }
207+ unsafe { BNTypeLibraryRemoveMetadata ( self . as_raw ( ) , key. as_ptr ( ) ) }
251208 }
252209
253210 /// Retrieves the metadata associated with the current type library.
@@ -262,7 +219,7 @@ impl TypeLibrary {
262219 // /// The Type Container's Platform will be the first platform associated with the Type Library.
263220 // pub fn type_container(&self) -> TypeContainer {
264221 // let result = unsafe{ BNGetTypeLibraryTypeContainer(self.as_raw())};
265- // unsafe{TypeContainer::from_raw(ptr:: NonNull::new(result).unwrap())}
222+ // unsafe{TypeContainer::from_raw(NonNull::new(result).unwrap())}
266223 // }
267224
268225 /// Directly inserts a named object into the type library's object store.
@@ -302,13 +259,7 @@ impl TypeLibrary {
302259 pub fn add_type_source ( & self , name : QualifiedName , source : & str ) {
303260 let source = source. to_cstr ( ) ;
304261 let mut raw_name = QualifiedName :: into_raw ( name) ;
305- unsafe {
306- BNAddTypeLibraryNamedTypeSource (
307- self . as_raw ( ) ,
308- & mut raw_name,
309- source. as_ref ( ) . as_ptr ( ) as * const ffi:: c_char ,
310- )
311- }
262+ unsafe { BNAddTypeLibraryNamedTypeSource ( self . as_raw ( ) , & mut raw_name, source. as_ptr ( ) ) }
312263 QualifiedName :: free_raw ( raw_name) ;
313264 }
314265
@@ -349,24 +300,38 @@ impl TypeLibrary {
349300 }
350301}
351302
352- impl Drop for TypeLibrary {
353- fn drop ( & mut self ) {
354- unsafe { BNFreeTypeLibrary ( self . as_raw ( ) ) }
303+ unsafe impl RefCountable for TypeLibrary {
304+ unsafe fn inc_ref ( handle : & Self ) -> Ref < Self > {
305+ Ref :: new ( Self {
306+ handle : NonNull :: new ( BNNewTypeLibraryReference ( handle. handle . as_ptr ( ) ) ) . unwrap ( ) ,
307+ } )
308+ }
309+
310+ unsafe fn dec_ref ( handle : & Self ) {
311+ BNFreeTypeLibrary ( handle. handle . as_ptr ( ) ) ;
312+ }
313+ }
314+
315+ impl ToOwned for TypeLibrary {
316+ type Owned = Ref < Self > ;
317+
318+ fn to_owned ( & self ) -> Self :: Owned {
319+ unsafe { RefCountable :: inc_ref ( self ) }
355320 }
356321}
357322
358323impl CoreArrayProvider for TypeLibrary {
359324 type Raw = * mut BNTypeLibrary ;
360325 type Context = ( ) ;
361- type Wrapped < ' a > = & ' a Self ;
326+ type Wrapped < ' a > = Guard < ' a , Self > ;
362327}
363328
364329unsafe impl CoreArrayProviderInner for TypeLibrary {
365330 unsafe fn free ( raw : * mut Self :: Raw , count : usize , _context : & Self :: Context ) {
366331 BNFreeTypeLibraryList ( raw, count)
367332 }
368333
369- unsafe fn wrap_raw < ' a > ( raw : & ' a Self :: Raw , _context : & ' a Self :: Context ) -> Self :: Wrapped < ' a > {
370- Self :: ref_from_raw ( raw)
334+ unsafe fn wrap_raw < ' a > ( raw : & ' a Self :: Raw , context : & ' a Self :: Context ) -> Self :: Wrapped < ' a > {
335+ Guard :: new ( Self :: from_raw ( NonNull :: new ( * raw) . unwrap ( ) ) , context )
371336 }
372337}
0 commit comments