use crate::bytestream::{ZByteIoError, ZByteWriterTrait};
mod no_std_writer;
mod std_writer;
enum Mode {
BE,
LE
}
pub struct ZWriter<T: ZByteWriterTrait> {
buffer: T,
bytes_written: usize
}
impl<T: ZByteWriterTrait> ZWriter<T> {
#[inline]
pub fn write(&mut self, buf: &[u8]) -> Result<usize, ZByteIoError> {
let bytes_written = self.buffer.write_bytes(buf)?;
self.bytes_written += bytes_written;
Ok(bytes_written)
}
pub fn write_all(&mut self, buf: &[u8]) -> Result<(), ZByteIoError> {
self.buffer.write_all_bytes(buf)?;
self.bytes_written += buf.len();
Ok(())
}
pub fn new(data: T) -> ZWriter<T> {
ZWriter {
buffer: data,
bytes_written: 0
}
}
#[inline]
pub fn write_u8_err(&mut self, byte: u8) -> Result<(), ZByteIoError> {
self.write_const_bytes(&[byte])
}
#[inline]
pub fn write_const_bytes<const N: usize>(
&mut self, byte: &[u8; N]
) -> Result<(), ZByteIoError> {
self.buffer.write_const_bytes(byte)?;
self.bytes_written += N;
Ok(())
}
#[inline]
pub fn write_u8(&mut self, byte: u8) {
let _ = self.write_const_bytes(&[byte]);
}
pub fn bytes_written(&self) -> usize {
self.bytes_written
}
pub fn reserve(&mut self, additional: usize) -> Result<(), ZByteIoError> {
self.buffer.reserve_capacity(additional)
}
pub fn inner(self) -> T {
self.buffer
}
pub fn inner_ref(&self) -> &T {
&self.buffer
}
pub fn inner_mut(&mut self) -> &mut T {
&mut self.buffer
}
}
macro_rules! write_single_type {
($name:tt,$name2:tt,$name3:tt,$name4:tt,$name5:tt,$name6:tt,$int_type:tt) => {
impl<T:ZByteWriterTrait> ZWriter<T>
{
#[inline(always)]
fn $name(&mut self, byte: $int_type, mode: Mode) -> Result<(), ZByteIoError>
{
let bytes = match mode
{
Mode::BE => byte.to_be_bytes(),
Mode::LE => byte.to_le_bytes()
};
self.write_const_bytes(&bytes)
}
#[inline(always)]
fn $name2(&mut self, byte: $int_type, mode: Mode)
{
let bytes = match mode
{
Mode::BE => byte.to_be_bytes(),
Mode::LE => byte.to_le_bytes()
};
let _ = self.write_const_bytes(&bytes);
}
#[doc=concat!("Write ",stringify!($int_type)," as a big endian integer")]
#[doc=concat!("Returning an error if the underlying buffer cannot support a ",stringify!($int_type)," write.")]
#[inline]
pub fn $name3(&mut self, byte: $int_type) -> Result<(), ZByteIoError>
{
self.$name(byte, Mode::BE)
}
#[doc=concat!("Write ",stringify!($int_type)," as a little endian integer")]
#[doc=concat!("Returning an error if the underlying buffer cannot support a ",stringify!($int_type)," write.")]
#[inline]
pub fn $name4(&mut self, byte: $int_type) -> Result<(), ZByteIoError>
{
self.$name(byte, Mode::LE)
}
#[doc=concat!("Write ",stringify!($int_type)," as a big endian integer")]
#[doc=concat!("Or don't write anything if the reader cannot support a ",stringify!($int_type)," write.")]
#[inline]
pub fn $name5(&mut self, byte: $int_type)
{
self.$name2(byte, Mode::BE)
}
#[doc=concat!("Write ",stringify!($int_type)," as a little endian integer")]
#[doc=concat!("Or don't write anything if the reader cannot support a ",stringify!($int_type)," write.")]
#[inline]
pub fn $name6(&mut self, byte: $int_type)
{
self.$name2(byte, Mode::LE)
}
}
};
}
write_single_type!(
write_u64_inner_or_die,
write_u64_inner_or_none,
write_u64_be_err,
write_u64_le_err,
write_u64_be,
write_u64_le,
u64
);
write_single_type!(
write_u32_inner_or_die,
write_u32_inner_or_none,
write_u32_be_err,
write_u32_le_err,
write_u32_be,
write_u32_le,
u32
);
write_single_type!(
write_u16_inner_or_die,
write_u16_inner_or_none,
write_u16_be_err,
write_u16_le_err,
write_u16_be,
write_u16_le,
u16
);