use alloc::alloc::{Layout, alloc, dealloc};
use core::slice;
use bytecheck::CheckBytes;
use rkyv::de::deserializers::SharedDeserializeMap;
use rkyv::validation::validators::DefaultValidator;
use rkyv::{Archive, Deserialize, check_archived_root};
use crate::ffi::error::ErrorCode;
const ALIGNMENT: usize = 1;
#[unsafe(no_mangle)]
pub extern "C" fn malloc(len: u32) -> u32 {
unsafe {
let layout = Layout::from_size_align_unchecked(len as usize, ALIGNMENT);
let ptr = alloc(layout);
ptr as _
}
}
#[unsafe(no_mangle)]
pub extern "C" fn free(ptr: u32, len: u32) {
unsafe {
let layout = Layout::from_size_align_unchecked(len as usize, ALIGNMENT);
dealloc(ptr as _, layout);
}
}
pub unsafe fn read_buffer<'a>(ptr: *const u8) -> &'a [u8] {
let len = slice::from_raw_parts(ptr, 4);
let len = u32::from_le_bytes(len.try_into().unwrap()) as usize;
slice::from_raw_parts(ptr.add(4), len)
}
pub unsafe fn parse_buffer<T>(bytes: &[u8]) -> Result<T, ErrorCode>
where
T: Archive,
for<'a> T::Archived:
CheckBytes<DefaultValidator<'a>> + Deserialize<T, SharedDeserializeMap>,
{
let aligned = bytes.to_vec();
let aligned_slice: &[u8] = &aligned;
check_archived_root::<T>(aligned_slice)
.or(Err(ErrorCode::UnarchivingError))?
.deserialize(&mut SharedDeserializeMap::default())
.or(Err(ErrorCode::UnarchivingError))
}
pub unsafe fn from_buffer<T>(ptr: *const u8) -> Result<T, ErrorCode>
where
T: Archive,
for<'a> T::Archived:
CheckBytes<DefaultValidator<'a>> + Deserialize<T, SharedDeserializeMap>,
{
let bytes = read_buffer(ptr);
parse_buffer::<T>(bytes)
}