use super::error::Error;
pub type ParseResult<T> = Result<T, Error>;
pub trait ByteReader {
fn read_u8(&mut self) -> ParseResult<u8>;
fn read_u32_le(&mut self) -> ParseResult<u32>;
fn read_bytes(&mut self, n: usize) -> ParseResult<Vec<u8>>;
fn read_into(&mut self, buf: &mut [u8]) -> ParseResult<()>;
}
pub struct Cursor<'a> {
data: &'a [u8],
position: usize,
}
impl<'a> Cursor<'a> {
pub fn new(data: &'a [u8]) -> Self {
Self { data, position: 0 }
}
}
impl ByteReader for Cursor<'_> {
fn read_u8(&mut self) -> ParseResult<u8> {
if self.position >= self.data.len() {
return Err(Error::UnexpectedEof);
}
let value = self.data[self.position];
self.position += 1;
Ok(value)
}
fn read_u32_le(&mut self) -> ParseResult<u32> {
if self.position + 4 > self.data.len() {
return Err(Error::UnexpectedEof);
}
let bytes = [
self.data[self.position],
self.data[self.position + 1],
self.data[self.position + 2],
self.data[self.position + 3],
];
self.position += 4;
Ok(u32::from_le_bytes(bytes))
}
fn read_bytes(&mut self, n: usize) -> ParseResult<Vec<u8>> {
if self.position + n > self.data.len() {
return Err(Error::UnexpectedEof);
}
let bytes = self.data[self.position..self.position + n].to_vec();
self.position += n;
Ok(bytes)
}
fn read_into(&mut self, buf: &mut [u8]) -> ParseResult<()> {
let n = buf.len();
if self.position + n > self.data.len() {
return Err(Error::UnexpectedEof);
}
buf.copy_from_slice(&self.data[self.position..self.position + n]);
self.position += n;
Ok(())
}
}
pub fn read_u32_array(reader: &mut impl ByteReader, count: usize) -> ParseResult<Vec<u32>> {
let mut values = Vec::with_capacity(count);
for _ in 0..count {
values.push(reader.read_u32_le()?);
}
Ok(values)
}