use super::put::*;
use crate::serialize::writer::*;
use core::mem::MaybeUninit;
type Mu8 = MaybeUninit<u8>;
pub struct IntoBufWriter<'a> {
buf: &'a mut [Mu8],
written: usize,
}
impl<'a> IntoBufWriter<'a> {
pub fn new(buf: &'a mut [Mu8]) -> Self {
Self { buf, written: 0 }
}
pub fn written(&self) -> usize {
self.written
}
#[inline]
fn reserve<'s>(&'s mut self, len: usize) -> WriteResult<&'s mut [Mu8]>
where
'a: 's,
{
let extent = self.written + len;
if extent > self.buf.len() {
return Err(WriteError::SpaceExhausted);
}
let start = self.written;
self.written = extent;
let reserved = unsafe { self.buf.get_unchecked_mut(start..extent) };
Ok(reserved)
}
}
impl<'a> Put for IntoBufWriter<'a> {
#[inline]
fn put_bytes(&mut self, bytes: &[u8]) -> WriteResult<()> {
let len = bytes.len();
let buf = self.reserve(len)?;
buf.write_copy_of_slice(bytes);
Ok(())
}
#[inline]
fn put_opaque_variable(&mut self, bytes: &[u8]) -> WriteResult<()> {
debug_assert!(bytes.len() <= u32::MAX as usize);
static PAD: [u8; 3] = [0; 3];
let len = bytes.len();
let rem = if len.is_multiple_of(4) {
0
} else {
4 - len % 4
};
let size = 4 + len + rem;
debug_assert!(size.is_multiple_of(4));
let buf = self.reserve(size)?;
buf[0..4].write_copy_of_slice(&(len as u32).to_be_bytes());
buf[4..4 + len].write_copy_of_slice(bytes);
buf[4 + len..4 + len + rem].write_copy_of_slice(&PAD[0..rem]);
Ok(())
}
#[inline]
fn put_opaque_fixed(&mut self, bytes: &[u8]) -> WriteResult<()> {
static PAD: [u8; 3] = [0; 3];
debug_assert!(bytes.len() <= u32::MAX as usize);
let len = bytes.len();
let rem = if len.is_multiple_of(4) {
0
} else {
4 - len % 4
};
let size = len + rem;
debug_assert!(size.is_multiple_of(4));
let buf = self.reserve(size)?;
buf[0..len].write_copy_of_slice(bytes);
buf[len..size].write_copy_of_slice(&PAD[0..rem]);
Ok(())
}
}