use crate::error::Error;
#[derive(Debug, Clone, Copy)]
pub(crate) struct SliceReader<'a> {
setup1: &'a [u8],
}
impl<'a> SliceReader<'a> {
pub(crate) fn embedded(input: &'a [u8], offset_setup1: u64) -> Result<Self, Error> {
if offset_setup1 == 0 {
return Ok(Self { setup1: &[] });
}
let start = usize::try_from(offset_setup1).map_err(|_| Error::Overflow {
what: "offset_setup1",
})?;
let setup1 = input.get(start..).ok_or(Error::Truncated {
what: "setup-1 region",
})?;
Ok(Self { setup1 })
}
pub(crate) fn read_at(&self, slice_idx: u32, offset: u32, len: u64) -> Result<&'a [u8], Error> {
if slice_idx != 0 {
return Err(Error::ExternalSlice);
}
if self.setup1.is_empty() {
return Err(Error::ExternalSlice);
}
let off = usize::try_from(offset).map_err(|_| Error::Overflow {
what: "slice offset",
})?;
let len_us = usize::try_from(len).map_err(|_| Error::Overflow {
what: "slice length",
})?;
let end = off
.checked_add(len_us)
.ok_or(Error::Overflow { what: "slice end" })?;
self.setup1.get(off..end).ok_or(Error::Truncated {
what: "setup-1 chunk bytes",
})
}
}