use {
crate::{alloc::LibCAlloc, LibCBox},
std::ptr::NonNull,
};
pub fn last_os_error() -> std::io::Error {
std::io::Error::last_os_error()
}
pub fn check_pointer_null<T>(ptr: *mut T) -> std::io::Result<()> {
if ptr.is_null() {
Err(last_os_error())
} else {
Ok(())
}
}
pub fn check_status_zero(status: std::ffi::c_int) -> std::io::Result<()> {
if status == 0 {
Ok(())
} else {
Err(last_os_error())
}
}
pub fn wrap_handle<T>(value: usize, wrap: impl Fn(usize) -> T) -> std::io::Result<T> {
if value == 0 {
Err(last_os_error())
} else {
Ok(wrap(value))
}
}
pub unsafe fn boxed_slice_from_ffi<T>(data: *mut T, len: usize) -> LibCBox<[T]> {
let data = match (len == 0, data.is_null()) {
(true, true) => NonNull::dangling().as_ptr(),
(false, true) => {
panic!("Hivex library returned null pointer to slice while having non-zero length")
}
(_, false) => data,
};
unsafe {
let vector = allocator_api2::vec::Vec::from_raw_parts_in(data, len, len, LibCAlloc);
vector.into_boxed_slice()
}
}
pub unsafe fn boxed_str_from_ffi(data: *mut std::ffi::c_char, len: usize) -> LibCBox<str> {
unsafe {
let data = boxed_slice_from_ffi(data, len);
LibCBox::from_raw_in(LibCBox::into_raw(data) as *mut str, LibCAlloc)
}
}