@@ -64,7 +64,7 @@ use std::collections::HashMap;
6464use std:: ffi:: { c_char, c_void, CString } ;
6565use std:: fmt:: { Display , Formatter } ;
6666use std:: ops:: Range ;
67- use std:: path:: Path ;
67+ use std:: path:: { Path , PathBuf } ;
6868use std:: ptr:: NonNull ;
6969use std:: { result, slice} ;
7070// TODO : general reorg of modules related to bv
@@ -76,6 +76,7 @@ pub mod writer;
7676
7777use crate :: binary_view:: search:: SearchQuery ;
7878use crate :: disassembly:: DisassemblySettings ;
79+ use crate :: type_archive:: { TypeArchive , TypeArchiveId } ;
7980use crate :: workflow:: Workflow ;
8081pub use memory_map:: MemoryMap ;
8182pub use reader:: BinaryReader ;
@@ -2355,23 +2356,45 @@ pub trait BinaryViewExt: BinaryViewBase {
23552356 }
23562357 }
23572358
2358- //
2359- // fn type_archives(&self) -> Array<TypeArchive> {
2360- // let mut ids: *mut *mut c_char = std::ptr::null_mut();
2361- // let mut paths: *mut *mut c_char = std::ptr::null_mut();
2362- // let count = unsafe { BNBinaryViewGetTypeArchives(self.as_ref().handle, &mut ids, &mut paths) };
2363- // let path_list = unsafe { Array::<BnString>::new(paths, count, ()) };
2364- // let ids_list = unsafe { std::slice::from_raw_parts(ids, count).to_vec() };
2365- // let archives = ids_list.iter().filter_map(|id| {
2366- // let archive_raw = unsafe { BNBinaryViewGetTypeArchive(self.as_ref().handle, *id) };
2367- // match archive_raw.is_null() {
2368- // true => None,
2369- // false => Some(archive_raw)
2370- // }
2371- // }).collect();
2372- // unsafe { BNFreeStringList(ids, count) };
2373- // Array::new(archives)
2374- // }
2359+ /// Retrieve the attached type archives as their [`TypeArchiveId`].
2360+ ///
2361+ /// Using the returned id you can retrieve the [`TypeArchive`] with [`BinaryViewExt::type_archive_by_id`].
2362+ fn attached_type_archives ( & self ) -> Vec < TypeArchiveId > {
2363+ let mut ids: * mut * mut c_char = std:: ptr:: null_mut ( ) ;
2364+ let mut paths: * mut * mut c_char = std:: ptr:: null_mut ( ) ;
2365+ let count =
2366+ unsafe { BNBinaryViewGetTypeArchives ( self . as_ref ( ) . handle , & mut ids, & mut paths) } ;
2367+ // We discard the path here, you can retrieve it later with [`BinaryViewExt::type_archive_path_by_id`],
2368+ // this is so we can simplify the return type which will commonly just want to query through to the type
2369+ // archive itself.
2370+ let _path_list = unsafe { Array :: < BnString > :: new ( paths, count, ( ) ) } ;
2371+ let id_list = unsafe { Array :: < BnString > :: new ( ids, count, ( ) ) } ;
2372+ id_list
2373+ . into_iter ( )
2374+ . map ( |id| TypeArchiveId ( id. to_string ( ) ) )
2375+ . collect ( )
2376+ }
2377+
2378+ /// Look up a connected [`TypeArchive`] by its `id`.
2379+ ///
2380+ /// NOTE: A [`TypeArchive`] can be attached but not connected, returning `None`.
2381+ fn type_archive_by_id ( & self , id : & TypeArchiveId ) -> Option < Ref < TypeArchive > > {
2382+ let id = id. 0 . as_str ( ) . to_cstr ( ) ;
2383+ let result = unsafe { BNBinaryViewGetTypeArchive ( self . as_ref ( ) . handle , id. as_ptr ( ) ) } ;
2384+ let result_ptr = NonNull :: new ( result) ?;
2385+ Some ( unsafe { TypeArchive :: ref_from_raw ( result_ptr) } )
2386+ }
2387+
2388+ /// Look up the path for an attached (but not necessarily connected) [`TypeArchive`] by its `id`.
2389+ fn type_archive_path_by_id ( & self , id : & TypeArchiveId ) -> Option < PathBuf > {
2390+ let id = id. 0 . as_str ( ) . to_cstr ( ) ;
2391+ let result = unsafe { BNBinaryViewGetTypeArchivePath ( self . as_ref ( ) . handle , id. as_ptr ( ) ) } ;
2392+ if result. is_null ( ) {
2393+ return None ;
2394+ }
2395+ let path_str = unsafe { BnString :: into_string ( result) } ;
2396+ Some ( PathBuf :: from ( path_str) )
2397+ }
23752398}
23762399
23772400impl < T : BinaryViewBase > BinaryViewExt for T { }
0 commit comments