1use crate::serialize::reader::*;
7
8pub struct BufReader<'r> {
14 data: &'r [u8],
15 pos: usize,
16}
17
18macro_rules! read_int {
19 [ $($read:ident($nbytes:expr): $ty:ty),* $(,)? ] => { $(
20 #[inline]
21 fn $read(&mut self) -> ReadResult<$ty> {
22 let input = self.get_input($nbytes)?;
23 let mut bytes = [0u8; $nbytes];
24 unsafe { core::ptr::copy_nonoverlapping(input.as_ptr(), bytes.as_mut_ptr(), $nbytes) };
26 let n = <$ty>::from_be_bytes(bytes);
27 Ok(n)
28 }
29 )* };
30}
31
32impl<'a> BufReader<'a> {
33 pub fn new(data: &'a [u8]) -> Self {
37 let pos = 0;
38 Self { data, pos }
39 }
40
41 pub fn position(&self) -> usize {
43 self.pos
44 }
45
46 pub fn remaining(&self) -> usize {
48 self.data.len() - self.pos
49 }
50
51 pub fn remaining_slice(&self) -> &'a [u8] {
53 &self.data[self.pos..]
54 }
55
56 #[inline]
57 fn get_input(&mut self, requested: usize) -> ReadResult<&'a [u8]> {
58 let Some(extent) = self
59 .pos
60 .checked_add(requested)
61 .filter(|&e| e <= self.data.len())
62 else {
63 let remaining: usize = self.data.len() - self.pos;
64 return Err(ReadError::source_empty(requested, remaining));
65 };
66
67 let buf = unsafe { self.data.get_unchecked(self.pos..extent) };
70
71 self.pos = extent;
72
73 Ok(buf)
74 }
75}
76
77unsafe impl<'r> Reader<'r> for BufReader<'r> {
79 #[inline]
80 fn read_opaque_fixed(&mut self, len: usize) -> ReadResult<&'r [u8]> {
81 let rem = len % 4;
82 if rem == 0 {
83 return self.get_input(len);
84 }
85
86 let padlen = 4 - rem;
87
88 let combined = len.checked_add(padlen).ok_or_else(|| {
92 ReadError::source_empty(usize::MAX, self.data.len() - self.pos)
97 })?;
98 let buf = self.get_input(combined)?;
99 let payload = unsafe { buf.get_unchecked(..len) };
100
101 #[cfg(not(feature = "permissive"))]
102 if unsafe { buf.get_unchecked(len..) }.iter().any(|&b| b != 0) {
103 return Err(ReadError::non_zero_padding());
104 }
105
106 Ok(payload)
107 }
108
109 #[inline]
110 fn read_opaque_variable(&mut self, max: u32) -> ReadResult<&'r [u8]> {
111 let len = self.read_u32()?;
112
113 if len > max {
114 return Err(ReadError::max_length_exceeded());
115 }
116
117 self.read_opaque_fixed(len as usize)
118 }
119
120 #[inline]
121 fn read_i16(&mut self) -> ReadResult<i16> {
122 let n = self.read_i32()?;
127 #[cfg(not(feature = "permissive"))]
128 if n < i16::MIN as i32 || n > i16::MAX as i32 {
129 return Err(ReadError::integer_out_of_range());
130 }
131 Ok(n as i16)
132 }
133
134 #[inline]
135 fn read_u16(&mut self) -> ReadResult<u16> {
136 let n = self.read_u32()?;
140 #[cfg(not(feature = "permissive"))]
141 if n < u16::MIN as u32 || n > u16::MAX as u32 {
142 return Err(ReadError::integer_out_of_range());
143 }
144 Ok(n as u16)
145 }
146
147 read_int! [
148 read_u64(8): u64,
149 read_u32(4): u32,
150
151 read_i64(8): i64,
152 read_i32(4): i32,
153 ];
154
155 #[inline]
156 fn read_f32(&mut self) -> ReadResult<f32> {
157 let input = self.get_input(4)?;
158 let mut bytes = [0u8; 4];
159 unsafe { core::ptr::copy_nonoverlapping(input.as_ptr(), bytes.as_mut_ptr(), 4) };
161 Ok(f32::from_be_bytes(bytes))
162 }
163
164 #[inline]
165 fn read_f64(&mut self) -> ReadResult<f64> {
166 let input = self.get_input(8)?;
167 let mut bytes = [0u8; 8];
168 unsafe { core::ptr::copy_nonoverlapping(input.as_ptr(), bytes.as_mut_ptr(), 8) };
170 Ok(f64::from_be_bytes(bytes))
171 }
172}