1use std::ffi::CStr;
2
3use crate::Context;
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 { libddwaf_sys::ddwaf_context_init(self.raw) },
19 keepalive: Vec::new(),
20 }
21 }
22
23 pub fn known_actions(&self) -> Vec<&CStr> {
25 self.call_cstr_array_fn(libddwaf_sys::ddwaf_known_actions)
26 }
27
28 pub fn known_addresses(&self) -> Vec<&CStr> {
33 self.call_cstr_array_fn(libddwaf_sys::ddwaf_known_addresses)
34 }
35
36 fn call_cstr_array_fn(
37 &self,
38 f: unsafe extern "C" fn(
39 libddwaf_sys::ddwaf_handle,
40 *mut u32,
41 ) -> *const *const std::os::raw::c_char,
42 ) -> Vec<&CStr> {
43 let mut size = std::mem::MaybeUninit::<u32>::uninit();
44 let ptr = unsafe { f(self.raw, size.as_mut_ptr()) };
45 if ptr.is_null() {
46 return vec![];
47 }
48 let size = unsafe { size.assume_init() as usize };
49 let arr = unsafe { std::slice::from_raw_parts(ptr, size) };
50 arr.iter().map(|&x| unsafe { CStr::from_ptr(x) }).collect()
51 }
52}
53impl Drop for Handle {
54 fn drop(&mut self) {
55 unsafe { libddwaf_sys::ddwaf_destroy(self.raw) }
56 }
57}
58unsafe impl Send for Handle {}
60unsafe impl Sync for Handle {}