use crate::error::DecodeError;
pub trait Reader {
fn read(&mut self, bytes: &mut [u8]) -> Result<(), DecodeError>;
#[inline]
fn peek_read(&mut self, _: usize) -> Option<&[u8]> {
None
}
#[inline]
fn consume(&mut self, _: usize) {}
}
impl<T> Reader for &mut T
where
T: Reader,
{
#[inline]
fn read(&mut self, bytes: &mut [u8]) -> Result<(), DecodeError> {
(**self).read(bytes)
}
#[inline]
fn peek_read(&mut self, n: usize) -> Option<&[u8]> {
(**self).peek_read(n)
}
#[inline]
fn consume(&mut self, n: usize) {
(*self).consume(n)
}
}
pub trait BorrowReader<'storage>: Reader {
fn take_bytes(&mut self, length: usize) -> Result<&'storage [u8], DecodeError>;
}
pub struct SliceReader<'storage> {
pub(crate) slice: &'storage [u8],
}
impl<'storage> SliceReader<'storage> {
pub fn new(bytes: &'storage [u8]) -> SliceReader<'storage> {
SliceReader { slice: bytes }
}
}
impl<'storage> Reader for SliceReader<'storage> {
#[inline(always)]
fn read(&mut self, bytes: &mut [u8]) -> Result<(), DecodeError> {
if bytes.len() > self.slice.len() {
return Err(DecodeError::UnexpectedEnd {
additional: bytes.len() - self.slice.len(),
});
}
let (read_slice, remaining) = self.slice.split_at(bytes.len());
bytes.copy_from_slice(read_slice);
self.slice = remaining;
Ok(())
}
#[inline]
fn peek_read(&mut self, n: usize) -> Option<&'storage [u8]> {
self.slice.get(..n)
}
#[inline]
fn consume(&mut self, n: usize) {
self.slice = self.slice.get(n..).unwrap_or_default();
}
}
impl<'storage> BorrowReader<'storage> for SliceReader<'storage> {
#[inline(always)]
fn take_bytes(&mut self, length: usize) -> Result<&'storage [u8], DecodeError> {
if length > self.slice.len() {
return Err(DecodeError::UnexpectedEnd {
additional: length - self.slice.len(),
});
}
let (read_slice, remaining) = self.slice.split_at(length);
self.slice = remaining;
Ok(read_slice)
}
}