use crate::{CID, Error, MemoryMessage, MemoryRange, Message};
#[derive(Debug)]
pub struct Carton<'a> {
range: MemoryRange,
valid: MemoryRange,
slice: &'a [u8],
should_drop: bool,
}
impl<'a> Carton<'a> {
pub fn from_bytes(bytes: &[u8]) -> Self {
let src_mem = bytes.as_ptr();
let remainder = bytes.len() & 4095;
let size = bytes.len() + (4096 - remainder);
let flags = crate::MemoryFlags::R | crate::MemoryFlags::W;
let new_mem = crate::map_memory(None, None, size, flags).unwrap();
unsafe {
core::ptr::copy(src_mem, new_mem.as_mut_ptr(), bytes.len());
};
let valid = unsafe { MemoryRange::new(new_mem.as_mut_ptr() as usize, bytes.len()).unwrap() };
Carton {
range: new_mem,
slice: unsafe { core::slice::from_raw_parts_mut(new_mem.as_mut_ptr(), bytes.len()) },
valid,
should_drop: true,
}
}
pub fn into_message(mut self, id: usize) -> MemoryMessage {
self.should_drop = false;
MemoryMessage { id, buf: self.valid, offset: None, valid: None }
}
pub fn lend(&self, connection: CID, id: usize) -> Result<crate::Result, Error> {
let msg = MemoryMessage { id, buf: self.valid, offset: None, valid: None };
crate::send_message(connection, Message::Borrow(msg))
}
pub fn lend_mut(&mut self, connection: CID, id: usize) -> Result<crate::Result, Error> {
let msg = MemoryMessage { id, buf: self.valid, offset: None, valid: None };
crate::send_message(connection, Message::MutableBorrow(msg))
}
}
impl<'a> AsRef<MemoryRange> for Carton<'a> {
fn as_ref(&self) -> &MemoryRange { &self.valid }
}
impl<'a> AsRef<[u8]> for Carton<'a> {
fn as_ref(&self) -> &[u8] { self.slice }
}
impl<'a> Drop for Carton<'a> {
fn drop(&mut self) {
if self.should_drop {
crate::unmap_memory(self.range).unwrap();
}
}
}