use std::mem;
#[unsafe(no_mangle)]
extern "C" fn allocate(capacity: usize) -> usize {
let mut data = vec![0; capacity];
data.resize(capacity, 0); let ptr = data.as_mut_ptr();
mem::forget(data); ptr as usize
}
#[unsafe(no_mangle)]
extern "C" fn deallocate(region_addr: usize) {
let _ = unsafe { Region::consume(region_addr as *mut Region) };
}
#[repr(C)]
pub struct Region {
offset: usize,
capacity: usize,
length: usize,
}
impl Region {
pub fn build(data: &[u8]) -> Box<Region> {
Box::new(Self {
offset: data.as_ptr() as usize,
capacity: data.len(),
length: data.len(),
})
}
pub fn release_buffer(data: Vec<u8>) -> *mut Self {
let region = Box::new(Self {
offset: data.as_ptr() as usize,
capacity: data.capacity(),
length: data.len(),
});
mem::forget(data);
Box::into_raw(region)
}
#[allow(clippy::missing_safety_doc)]
pub unsafe fn consume(ptr: *mut Region) -> Vec<u8> {
assert!(!ptr.is_null(), "Region pointer is null");
let region = unsafe { Box::from_raw(ptr) };
let region_start = region.offset as *mut u8;
assert!(!region_start.is_null(), "Region starts as null address");
unsafe { Vec::from_raw_parts(region_start, region.length, region.capacity) }
}
}