#![allow(clippy::missing_safety_doc)]
use crate::c;
use core::mem::size_of_val;
use corevm_types::{flags::RecvMessage, GuestId, RecvMessageOutcome};
#[cfg(feature = "alloc")]
pub fn try_recv_message() -> Option<(alloc::vec::Vec<u8>, GuestId)> {
let ret = unsafe { c::recv_message(0, 0, RecvMessage::NON_BLOCKING.bits()) };
let (len, source) = RecvMessageOutcome::from_reg(ret).into_inner()?;
let mut buf = alloc::vec::Vec::with_capacity(len as usize);
unsafe {
c::recv_message(buf.as_mut_ptr() as u64, u64::from(len), RecvMessage::NON_BLOCKING.bits())
};
unsafe { buf.set_len(len as usize) };
Some((buf, source))
}
#[inline]
pub fn try_recv_message_into(buf: &mut [u8]) -> Option<Result<(usize, GuestId), usize>> {
let ret = unsafe {
c::recv_message(buf.as_mut_ptr() as u64, buf.len() as u64, RecvMessage::NON_BLOCKING.bits())
};
let (len, source) = RecvMessageOutcome::from_reg(ret).into_inner()?;
if len > buf.len() as u32 {
return Some(Err(len as usize));
}
Some(Ok((len as usize, source)))
}
#[inline]
pub fn try_recv_bounded_message_into(buf: &mut [u8]) -> Option<(usize, GuestId)> {
let ret = unsafe {
c::recv_message(
buf.as_mut_ptr() as u64,
buf.len() as u64,
RecvMessage::DISCARD.bits() | RecvMessage::NON_BLOCKING.bits(),
)
};
let (len, source) = RecvMessageOutcome::from_reg(ret).into_inner()?;
Some((len as usize, source))
}
#[cfg(feature = "alloc")]
pub fn recv_message() -> (alloc::vec::Vec<u8>, GuestId) {
let ret = unsafe { c::recv_message(0, 0, 0) };
let (len, source) =
RecvMessageOutcome::from_reg(ret).into_inner().expect("The call is blocking");
let mut buf = alloc::vec::Vec::with_capacity(len as usize);
unsafe { c::recv_message(buf.as_mut_ptr() as u64, u64::from(len), 0) };
unsafe { buf.set_len(len as usize) };
(buf, source)
}
#[inline]
pub fn recv_message_into(buf: &mut [u8]) -> Result<(usize, GuestId), usize> {
let ret = unsafe { c::recv_message(buf.as_mut_ptr() as u64, buf.len() as u64, 0) };
let (len, source) =
RecvMessageOutcome::from_reg(ret).into_inner().expect("The call is blocking");
if len > buf.len() as u32 {
return Err(len as usize);
}
Ok((len as usize, source))
}
#[inline]
pub fn recv_bounded_message_into(buf: &mut [u8]) -> Option<(usize, GuestId)> {
let ret = unsafe {
c::recv_message(buf.as_mut_ptr() as u64, buf.len() as u64, RecvMessage::DISCARD.bits())
};
let (len, source) = RecvMessageOutcome::from_reg(ret).into_inner()?;
Some((len as usize, source))
}
#[inline]
pub fn send_message(guest_id: GuestId, message: &[u8]) {
let address = message.as_ptr() as u64;
let len = size_of_val(message) as u64;
unsafe { c::send_message(u64::from(guest_id), address, len) };
}