1use crate::Error;
2
3#[derive(Debug, Clone, Copy)]
5pub struct ByteCursor<'a> {
6 bytes: &'a [u8],
7 position: usize,
8}
9
10impl<'a> ByteCursor<'a> {
11 pub fn new(bytes: &'a [u8]) -> Self {
12 Self { bytes, position: 0 }
13 }
14
15 pub fn position(&self) -> usize {
16 self.position
17 }
18
19 pub fn remaining(&self) -> usize {
20 self.bytes.len().saturating_sub(self.position)
21 }
22
23 pub fn read_u8(&mut self) -> Result<u8, Error> {
24 Ok(self.read_exact(1)?[0])
25 }
26
27 pub fn read_be_u32(&mut self) -> Result<u32, Error> {
28 let offset = self.position;
29 let bytes = self.read_exact(4)?;
30 let mut raw = [0u8; 4];
31 raw.copy_from_slice(bytes);
32 debug_assert_eq!(self.position, offset + 4);
33 Ok(u32::from_be_bytes(raw))
34 }
35
36 pub fn read_be_u64(&mut self) -> Result<u64, Error> {
37 let offset = self.position;
38 let bytes = self.read_exact(8)?;
39 let mut raw = [0u8; 8];
40 raw.copy_from_slice(bytes);
41 debug_assert_eq!(self.position, offset + 8);
42 Ok(u64::from_be_bytes(raw))
43 }
44
45 pub fn read_be_i32(&mut self) -> Result<i32, Error> {
46 let offset = self.position;
47 let bytes = self.read_exact(4)?;
48 let mut raw = [0u8; 4];
49 raw.copy_from_slice(bytes);
50 debug_assert_eq!(self.position, offset + 4);
51 Ok(i32::from_be_bytes(raw))
52 }
53
54 pub fn read_exact(&mut self, len: usize) -> Result<&'a [u8], Error> {
55 let offset = self.position;
56 let end = offset.checked_add(len).ok_or(Error::UnexpectedEof {
57 offset,
58 needed: len,
59 remaining: self.remaining(),
60 })?;
61 if end > self.bytes.len() {
62 return Err(Error::UnexpectedEof {
63 offset,
64 needed: len,
65 remaining: self.remaining(),
66 });
67 }
68 self.position = end;
69 Ok(&self.bytes[offset..end])
70 }
71}