use crate::read_write::{Read, Write};
use core::marker::PhantomData;
use void::Void;
pub struct SliceReader<'a> {
pos: *const u8,
end: *const u8,
phantom_data: PhantomData<&'a ()>,
}
impl<'a> SliceReader<'a> {
#[inline(always)]
#[must_use]
pub fn new(data: &'a [u8]) -> SliceReader<'a> {
let ptr = data.as_ptr();
SliceReader {
pos: ptr,
end: unsafe { ptr.add(data.len()) },
phantom_data: PhantomData,
}
}
}
impl<'a> Read for SliceReader<'a> {
type Error = Void;
#[inline(always)]
fn read(&mut self) -> Result<Option<u8>, Self::Error> {
if self.pos == self.end {
Ok(None)
} else {
let result = unsafe { self.pos.read() };
self.pos = unsafe { self.pos.add(1) };
Ok(Some(result))
}
}
}
#[derive(Debug, Eq, PartialEq)]
pub struct SliceWriteError;
impl core::fmt::Display for SliceWriteError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("Over- or underflow happened")
}
}
#[cfg(any(test, feature = "std"))]
impl std::error::Error for SliceWriteError {}
pub struct SliceWriter<'a> {
start: *mut u8,
pos: *mut u8,
end: *mut u8,
phantom_data: PhantomData<&'a ()>,
}
impl<'a> SliceWriter<'a> {
#[inline(always)]
#[must_use]
pub fn new(data: &'a mut [u8]) -> SliceWriter<'a> {
let ptr = data.as_mut_ptr();
SliceWriter {
start: ptr,
pos: ptr,
end: unsafe { ptr.add(data.len()) },
phantom_data: PhantomData,
}
}
}
impl<'a> Write for SliceWriter<'a> {
type Output = usize;
type Error = SliceWriteError;
#[inline(always)]
fn write(&mut self, data: u8) -> Result<(), Self::Error> {
if self.pos == self.end {
Err(SliceWriteError)
} else {
unsafe { self.pos.write(data) };
self.pos = unsafe { self.pos.add(1) };
Ok(())
}
}
#[inline(always)]
fn finish(self) -> Result<Self::Output, Self::Error> {
Ok((unsafe { self.pos.offset_from(self.start) }) as usize)
}
}
pub struct SliceWriterExact<'a> {
pos: *mut u8,
end: *mut u8,
phantom_data: PhantomData<&'a ()>,
}
impl<'a> SliceWriterExact<'a> {
#[inline(always)]
#[must_use]
pub fn new(data: &'a mut [u8]) -> SliceWriterExact<'a> {
let ptr = data.as_mut_ptr();
SliceWriterExact {
pos: ptr,
end: unsafe { ptr.add(data.len()) },
phantom_data: PhantomData,
}
}
}
impl<'a> Write for SliceWriterExact<'a> {
type Output = ();
type Error = SliceWriteError;
#[inline(always)]
fn write(&mut self, data: u8) -> Result<(), Self::Error> {
if self.pos == self.end {
Err(SliceWriteError)
} else {
unsafe { self.pos.write(data) };
self.pos = unsafe { self.pos.add(1) };
Ok(())
}
}
#[inline(always)]
fn finish(self) -> Result<Self::Output, Self::Error> {
if self.pos == self.end {
Ok(())
} else {
Err(SliceWriteError)
}
}
}