use crate::buf::Alloc;
use crate::{Alignment, BodyBuf, Signature, Storable};
pub struct Raw<'a> {
buf: &'a mut BodyBuf,
}
impl<'a> Raw<'a> {
#[inline]
pub(crate) fn new(buf: &'a mut BodyBuf) -> Self {
Self { buf }
}
#[inline]
pub fn as_raw(&mut self) -> Raw<'_> {
Raw::new(self.buf)
}
#[inline]
pub fn align(&mut self, alignment: Alignment) {
self.buf.align_mut_to(alignment.in_bytes());
}
#[inline]
pub fn store<T>(&mut self, value: T)
where
T: Storable,
{
value.store_to(self.buf);
}
#[inline]
pub fn store_signature(&mut self, signature: &Signature) {
self.buf.write_only(signature);
}
#[inline]
pub fn write_slice(&mut self, bytes: &[u8]) {
self.buf.extend_from_slice(bytes);
}
#[inline]
pub fn store_array(&mut self, alignment: Alignment) -> RawArray<'_> {
RawArray::new(self.buf, alignment)
}
#[inline]
pub fn into_array(self, alignment: Alignment) -> RawArray<'a> {
RawArray::new(self.buf, alignment)
}
}
pub struct RawArray<'a> {
buf: &'a mut BodyBuf,
len: Alloc<u32>,
start: usize,
}
impl<'a> RawArray<'a> {
#[inline]
fn new(buf: &'a mut BodyBuf, alignment: Alignment) -> Self {
let len = buf.alloc();
buf.align_mut_to(alignment.in_bytes());
let start = buf.len();
Self { buf, len, start }
}
#[inline]
pub fn as_raw(&mut self) -> Raw<'_> {
Raw::new(self.buf)
}
#[inline]
pub fn finish(self) {}
}
impl Drop for RawArray<'_> {
#[inline]
fn drop(&mut self) {
let len = (self.buf.len() - self.start) as u32;
self.buf.store_at(self.len, len);
}
}