Skip to content

Commit b52660f

Browse files
committed
[Rust] Add APIs to retrieve type archives for a binary view
1 parent efd88f0 commit b52660f

File tree

1 file changed

+41
-18
lines changed

1 file changed

+41
-18
lines changed

rust/src/binary_view.rs

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ use std::collections::HashMap;
6464
use std::ffi::{c_char, c_void, CString};
6565
use std::fmt::{Display, Formatter};
6666
use std::ops::Range;
67-
use std::path::Path;
67+
use std::path::{Path, PathBuf};
6868
use std::ptr::NonNull;
6969
use std::{result, slice};
7070
// TODO : general reorg of modules related to bv
@@ -76,6 +76,7 @@ pub mod writer;
7676

7777
use crate::binary_view::search::SearchQuery;
7878
use crate::disassembly::DisassemblySettings;
79+
use crate::type_archive::{TypeArchive, TypeArchiveId};
7980
use crate::workflow::Workflow;
8081
pub use memory_map::MemoryMap;
8182
pub 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

23772400
impl<T: BinaryViewBase> BinaryViewExt for T {}

0 commit comments

Comments
 (0)