1use std::ffi::CStr;
2
3use crate::{Context, object::get_default_allocator};
4
5#[repr(transparent)]
10pub struct Handle {
11 pub(crate) raw: libddwaf_sys::ddwaf_handle,
12}
13impl Handle {
14 #[must_use]
16 pub fn new_context(&self) -> Context {
17 Context {
18 raw: unsafe {
19 libddwaf_sys::ddwaf_context_init(self.raw, get_default_allocator().into())
20 },
21 }
22 }
23
24 pub fn known_actions(&self) -> Vec<&CStr> {
26 self.call_cstr_array_fn(libddwaf_sys::ddwaf_known_actions)
27 }
28
29 pub fn known_addresses(&self) -> Vec<&CStr> {
34 self.call_cstr_array_fn(libddwaf_sys::ddwaf_known_addresses)
35 }
36
37 fn call_cstr_array_fn(
38 &self,
39 f: unsafe extern "C" fn(
40 libddwaf_sys::ddwaf_handle,
41 *mut u32,
42 ) -> *const *const std::os::raw::c_char,
43 ) -> Vec<&CStr> {
44 let mut size = std::mem::MaybeUninit::<u32>::uninit();
45 let ptr = unsafe { f(self.raw, size.as_mut_ptr()) };
46 if ptr.is_null() {
47 return vec![];
48 }
49 let size = unsafe { size.assume_init() as usize };
50 let arr = unsafe { std::slice::from_raw_parts(ptr, size) };
51 arr.iter().map(|&x| unsafe { CStr::from_ptr(x) }).collect()
52 }
53}
54impl Drop for Handle {
55 fn drop(&mut self) {
56 unsafe { libddwaf_sys::ddwaf_destroy(self.raw) }
57 }
58}
59unsafe impl Send for Handle {}
61unsafe impl Sync for Handle {}