1use crate::{
2 CpIndex,
3 error::{Error, Result},
4};
5
6#[derive(Debug, Clone, Copy)]
8pub struct Cursor<'a>(&'a [u8]);
9
10impl<'a> Cursor<'a> {
11 pub fn new(bytes: &'a [u8]) -> Self {
13 Self(bytes)
14 }
15
16 pub fn remaining(&self) -> &'a [u8] {
18 self.0
19 }
20
21 pub fn len(&self) -> usize {
23 self.0.len()
24 }
25
26 pub fn is_empty(&self) -> bool {
28 self.0.is_empty()
29 }
30}
31
32impl<'a> From<&'a [u8]> for Cursor<'a> {
33 fn from(value: &'a [u8]) -> Self {
34 Self::new(value)
35 }
36}
37
38macro_rules! read_int {
40 ($($name:ident -> $type:ty),* $(,)?) => {$(
41 fn $name(&mut self) -> Result<$type> {
43 let mut buf = [0u8; size_of::<$type>()];
44 buf.copy_from_slice(self.read_bytes(size_of::<$type>())?);
45
46 Ok(<$type>::from_be_bytes(buf))
47 }
48 )*};
49}
50
51pub trait ReadBytes<'a> {
53 fn read_bytes(&mut self, len: usize) -> Result<&'a [u8]>;
55
56 fn read_rest(&mut self) -> &'a [u8];
58
59 read_int! {
60 read_u8 -> u8,
61 read_u16 -> u16,
62 read_u32 -> u32,
63 read_u64 -> u64,
64 read_i32 -> i32,
65 read_i64 -> i64,
66 }
67
68 fn read_f32(&mut self) -> Result<f32> {
70 Ok(f32::from_bits(self.read_u32()?))
71 }
72
73 fn read_f64(&mut self) -> Result<f64> {
75 Ok(f64::from_bits(self.read_u64()?))
76 }
77
78 fn repeat_by_u16<T>(&mut self, mut fun: impl FnMut(&mut Self) -> Result<T>) -> Result<Vec<T>>
80 where
81 Self: Sized,
82 {
83 let count = self.read_u16()?;
84 let mut items = Vec::with_capacity(count as usize);
85
86 for _ in 0..count {
87 items.push(fun(self)?);
88 }
89
90 Ok(items)
91 }
92
93 fn repeat_by_u8<T>(&mut self, mut fun: impl FnMut(&mut Self) -> Result<T>) -> Result<Vec<T>>
95 where
96 Self: Sized,
97 {
98 let count = self.read_u8()?;
99 let mut items = Vec::with_capacity(count as usize);
100
101 for _ in 0..count {
102 items.push(fun(self)?);
103 }
104
105 Ok(items)
106 }
107
108 fn read_indices(&mut self) -> Result<Vec<CpIndex>>
110 where
111 Self: Sized,
112 {
113 self.repeat_by_u16(|cursor| cursor.read_u16())
114 }
115
116 fn read_optional_index(&mut self) -> Result<Option<CpIndex>> {
118 let index = self.read_u16()?;
119
120 Ok((index != 0).then_some(index))
121 }
122}
123
124impl<'a> ReadBytes<'a> for Cursor<'a> {
125 fn read_bytes(&mut self, len: usize) -> Result<&'a [u8]> {
126 match self.0.split_at_checked(len) {
127 Some((head, tail)) => {
128 self.0 = tail;
129
130 Ok(head)
131 }
132 None => Err(Error::UnexpectedEof {
133 needed: len,
134 available: self.0.len(),
135 }),
136 }
137 }
138
139 fn read_rest(&mut self) -> &'a [u8] {
140 std::mem::take(&mut self.0)
141 }
142}