use super::*;
use crate::prelude::*;
#[derive(Debug, Clone)]
#[cfg_attr(feature = "mem_dbg", derive(mem_dbg::MemDbg, mem_dbg::MemSize))]
pub struct SliceWithPos<'a> {
pub(crate) data: &'a [u8],
pub(crate) pos: usize,
}
impl<'a> SliceWithPos<'a> {
pub const fn new(backend: &'a [u8]) -> Self {
Self {
data: backend,
pos: 0,
}
}
#[inline(always)]
pub const fn data(&self) -> &'a [u8] {
self.data
}
#[inline(always)]
pub const fn pos(&self) -> usize {
self.pos
}
pub fn skip(&mut self, bytes: usize) -> deser::Result<()> {
self.data = self.data.get(bytes..).ok_or(Error::ReadError)?;
self.pos += bytes;
Ok(())
}
}
impl ReadNoStd for SliceWithPos<'_> {
fn read_exact(&mut self, buf: &mut [u8]) -> deser::Result<()> {
let len = buf.len();
if len > self.data.len() {
return Err(Error::ReadError);
}
buf.copy_from_slice(&self.data[..len]);
self.data = &self.data[len..];
self.pos += len;
Ok(())
}
}
impl ReadWithPos for SliceWithPos<'_> {
fn pos(&self) -> usize {
self.pos
}
fn align<T: PadTo>(&mut self) -> deser::Result<()> {
let pad_to = T::pad_to();
if pad_to == 0 {
return Ok(());
}
let padding = crate::pad_align_to(self.pos, pad_to);
self.skip(padding)?;
if self.data.as_ptr() as usize % pad_to != 0 {
Err(Error::AlignmentError)
} else {
Ok(())
}
}
}