rustbac_core/encoding/
reader.rs1use crate::DecodeError;
2
3#[derive(Debug, Clone, Copy)]
8pub struct Reader<'a> {
9 buf: &'a [u8],
10 pos: usize,
11}
12
13impl<'a> Reader<'a> {
14 pub const fn new(buf: &'a [u8]) -> Self {
15 Self { buf, pos: 0 }
16 }
17
18 pub const fn position(&self) -> usize {
19 self.pos
20 }
21
22 pub fn remaining(&self) -> usize {
23 self.buf.len().saturating_sub(self.pos)
24 }
25
26 pub fn is_empty(&self) -> bool {
27 self.remaining() == 0
28 }
29
30 pub fn peek_u8(&self) -> Result<u8, DecodeError> {
31 self.buf
32 .get(self.pos)
33 .copied()
34 .ok_or(DecodeError::UnexpectedEof)
35 }
36
37 pub fn read_u8(&mut self) -> Result<u8, DecodeError> {
38 let byte = self.peek_u8()?;
39 self.pos += 1;
40 Ok(byte)
41 }
42
43 pub fn read_exact(&mut self, len: usize) -> Result<&'a [u8], DecodeError> {
44 if self.remaining() < len {
45 return Err(DecodeError::UnexpectedEof);
46 }
47 let start = self.pos;
48 self.pos += len;
49 Ok(&self.buf[start..start + len])
50 }
51
52 pub fn read_be_u16(&mut self) -> Result<u16, DecodeError> {
53 let bytes = self.read_exact(2)?;
54 Ok(u16::from_be_bytes([bytes[0], bytes[1]]))
55 }
56
57 pub fn read_be_u32(&mut self) -> Result<u32, DecodeError> {
58 let bytes = self.read_exact(4)?;
59 Ok(u32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]))
60 }
61}
62
63#[cfg(test)]
64mod tests {
65 use super::Reader;
66 use crate::DecodeError;
67
68 #[test]
69 fn reader_reads_values() {
70 let mut r = Reader::new(&[1, 2, 3, 4, 5]);
71 assert_eq!(r.read_u8().unwrap(), 1);
72 assert_eq!(r.read_exact(2).unwrap(), &[2, 3]);
73 assert_eq!(r.remaining(), 2);
74 }
75
76 #[test]
77 fn reader_bounds() {
78 let mut r = Reader::new(&[1]);
79 assert_eq!(r.read_u8().unwrap(), 1);
80 assert_eq!(r.read_u8().unwrap_err(), DecodeError::UnexpectedEof);
81 }
82}