1#[cfg(not(feature = "permissive"))]
7use super::limits::*;
8
9use crate::serialize::reader::*;
10
11pub struct BufReader<'r> {
17 data: &'r [u8],
18 pos: usize,
19}
20
21impl<'a> BufReader<'a> {
22 pub fn new(data: &'a [u8]) -> Self {
26 let pos = 0;
27 Self { data, pos }
28 }
29
30 pub fn position(&self) -> usize {
32 self.pos
33 }
34
35 pub fn remaining(&self) -> usize {
37 self.data.len() - self.pos
38 }
39
40 pub fn remaining_slice(&self) -> &'a [u8] {
42 &self.data[self.pos..]
43 }
44
45 #[inline]
46 fn get_input(&mut self, requested: u32) -> ReadResult<&'a [u8]> {
47 let requested = requested as usize;
48 let remaining = self.data.len() - self.pos;
49 if requested > remaining {
50 #[cfg(all(target_arch = "riscv32", target_os = "none"))]
54 core::hint::cold_path();
55 return Err(ReadError::source_empty(requested, remaining));
56 }
57 let extent = self.pos + requested;
60
61 let buf = unsafe { self.data.get_unchecked(self.pos..extent) };
63
64 self.pos = extent;
65
66 Ok(buf)
67 }
68
69 #[inline]
70 fn read_byte(&mut self) -> ReadResult<u8> {
71 let byte = self.get_input(1)?;
72
73 Ok(unsafe { *byte.get_unchecked(0) })
75 }
76
77 #[cfg_attr(
78 any(
79 target_family = "wasm",
80 all(target_arch = "riscv32", target_os = "none"),
81 ),
82 inline(never)
83 )]
84 #[cfg_attr(
85 not(any(
86 target_family = "wasm",
87 all(target_arch = "riscv32", target_os = "none"),
88 )),
89 inline(always)
90 )]
91 fn read_signed(&mut self) -> ReadResult<i64> {
92 let h = self.read_byte()?;
93 let s = (h & 0xc0) >> 6;
94 let v = h & !0xc0;
95 let n: i64;
96
97 if v == 63 {
98 n = match s {
104 0 => self.read_byte()? as i8 as i64,
105 1 => i16::from_le(unsafe {
106 core::ptr::read_unaligned(self.get_input(2)?.as_ptr().cast::<i16>())
107 }) as i64,
108 2 => i32::from_le(unsafe {
109 core::ptr::read_unaligned(self.get_input(4)?.as_ptr().cast::<i32>())
110 }) as i64,
111 3 => i64::from_le(unsafe {
112 core::ptr::read_unaligned(self.get_input(8)?.as_ptr().cast::<i64>())
113 }),
114 _ => unreachable!(),
115 };
116
117 #[cfg(not(feature = "permissive"))]
118 {
119 const N_BYTE_REPR_MINMAX: [(i64, i64); 4] = [
122 (IH_MAX as i64 + 1, IH_MIN as i64 - 1),
123 (i8::MAX as i64 + 1, i8::MIN as i64 - 1),
124 (i16::MAX as i64 + 1, i16::MIN as i64 - 1),
125 (i32::MAX as i64 + 1, i32::MIN as i64 - 1),
126 ];
127 let (repr_min, repr_max) = N_BYTE_REPR_MINMAX[s as usize];
128
129 if n > 0 {
130 if n < repr_min {
131 return Err(ReadError::not_minimal_encoding());
132 }
133 } else if n > repr_max {
134 return Err(ReadError::not_minimal_encoding());
135 }
136 }
137 } else {
138 if s != 0 {
141 return Err(ReadError::invalid_header_byte(h));
142 }
143
144 if v & 0b10_0000 != 0 {
145 n = -(((!v) & 0b11_1111) as i64);
148 } else {
149 n = v as i64;
150 }
151 }
152
153 Ok(n)
154 }
155
156 #[cfg_attr(
157 any(
158 target_family = "wasm",
159 all(target_arch = "riscv32", target_os = "none"),
160 ),
161 inline(never)
162 )]
163 #[cfg_attr(
164 not(any(
165 target_family = "wasm",
166 all(target_arch = "riscv32", target_os = "none"),
167 )),
168 inline(always)
169 )]
170 fn read_unsigned(&mut self) -> ReadResult<u64> {
171 let h = self.read_byte()?;
172 let s = (h & 0xc0) >> 6;
173 let v = h & !0xc0;
174
175 if v == 63 {
176 let uint = match s {
182 0 => self.read_byte()? as u64,
183 1 => u16::from_le(unsafe {
184 core::ptr::read_unaligned(self.get_input(2)?.as_ptr().cast::<u16>())
185 }) as u64,
186 2 => u32::from_le(unsafe {
187 core::ptr::read_unaligned(self.get_input(4)?.as_ptr().cast::<u32>())
188 }) as u64,
189 3 => u64::from_le(unsafe {
190 core::ptr::read_unaligned(self.get_input(8)?.as_ptr().cast::<u64>())
191 }),
192 _ => unreachable!(),
193 };
194
195 #[cfg(not(feature = "permissive"))]
196 {
197 const N_BYTE_REPR_MIN: [u64; 4] = [
200 63,
201 u8::MAX as u64 + 1,
202 u16::MAX as u64 + 1,
203 u32::MAX as u64 + 1,
204 ];
205 let repr_min = N_BYTE_REPR_MIN[s as usize];
206
207 if uint < repr_min {
208 return Err(ReadError::not_minimal_encoding());
209 }
210 }
211
212 Ok(uint)
213 } else {
214 if s != 0 {
217 return Err(ReadError::invalid_header_byte(h));
218 }
219
220 Ok(v as u64)
221 }
222 }
223}
224
225macro_rules! read_signed {
226 { $( [$f:ident, $ty:ty] ),* $(,)? } => { $(
227
228 #[inline]
229 fn $f(&mut self) -> ReadResult<$ty> {
230 let n = self.read_signed()?;
231 let n = n
232 .try_into()
233 .map_err(|_| ReadError::integer_out_of_range())?;
234 Ok(n)
235 }
236
237 )* };
238}
239
240macro_rules! read_unsigned {
241 { $( [$f:ident, $ty:ty] ),* $(,)? } => { $(
242
243 #[inline]
244 fn $f(&mut self) -> ReadResult<$ty> {
245 let n = self.read_unsigned()?;
246 let n = n
247 .try_into()
248 .map_err(|_| ReadError::integer_out_of_range())?;
249 Ok(n)
250 }
251
252 )* };
253}
254
255unsafe impl<'r> Reader<'r> for BufReader<'r> {
257 read_signed! {
258 [read_i64, i64],
259 [read_i32, i32],
260 [read_i16, i16],
261 }
262
263 read_unsigned! {
264 [read_u64, u64],
265 [read_u32, u32],
266 [read_u16, u16],
267 }
268
269 #[inline]
275 fn read_f32(&mut self) -> ReadResult<f32> {
276 let input = self.read_opaque_fixed(4)?;
277 let mut bytes = [0u8; 4];
278 unsafe { core::ptr::copy_nonoverlapping(input.as_ptr(), bytes.as_mut_ptr(), 4) };
280 Ok(f32::from_le_bytes(bytes))
281 }
282
283 #[inline]
289 fn read_f64(&mut self) -> ReadResult<f64> {
290 let input = self.read_opaque_fixed(8)?;
291 let mut bytes = [0u8; 8];
292 unsafe { core::ptr::copy_nonoverlapping(input.as_ptr(), bytes.as_mut_ptr(), 8) };
294 Ok(f64::from_le_bytes(bytes))
295 }
296
297 #[inline]
298 fn read_opaque_fixed(&mut self, len: usize) -> ReadResult<&'r [u8]> {
299 debug_assert!(len <= u32::MAX as usize);
302 self.get_input(len as u32)
303 }
304
305 #[inline(always)]
306 fn read_opaque_variable(&mut self, max: u32) -> ReadResult<&'r [u8]> {
307 let len = self.read_u32()?;
308
309 if len > max {
310 return Err(ReadError::max_length_exceeded());
311 }
312
313 self.read_opaque_fixed(len as usize)
314 }
315}