1use crate::config::Config;
4use crate::error::{JustcodeError, Result};
5
6pub struct Reader<'a> {
8 data: &'a [u8],
9 position: usize,
10 config: Config,
11}
12
13impl<'a> Reader<'a> {
14 pub fn new(data: &'a [u8], config: Config) -> Self {
16 Self {
17 data,
18 position: 0,
19 config,
20 }
21 }
22
23 pub fn read_u8(&mut self) -> Result<u8> {
25 self.check_size(1)?;
26 let value = self.data[self.position];
27 self.position += 1;
28 Ok(value)
29 }
30
31 pub fn read_u16(&mut self) -> Result<u16> {
33 self.check_size(2)?;
34 let bytes = &self.data[self.position..self.position + 2];
35 self.position += 2;
36 Ok(u16::from_le_bytes([bytes[0], bytes[1]]))
37 }
38
39 pub fn read_u32(&mut self) -> Result<u32> {
41 self.check_size(4)?;
42 let bytes = &self.data[self.position..self.position + 4];
43 self.position += 4;
44 Ok(u32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]))
45 }
46
47 pub fn read_u64(&mut self) -> Result<u64> {
49 self.check_size(8)?;
50 let bytes = &self.data[self.position..self.position + 8];
51 self.position += 8;
52 Ok(u64::from_le_bytes([
53 bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
54 ]))
55 }
56
57 pub fn read_i8(&mut self) -> Result<i8> {
59 Ok(self.read_u8()? as i8)
60 }
61
62 pub fn read_i16(&mut self) -> Result<i16> {
64 Ok(self.read_u16()? as i16)
65 }
66
67 pub fn read_i32(&mut self) -> Result<i32> {
69 Ok(self.read_u32()? as i32)
70 }
71
72 pub fn read_i64(&mut self) -> Result<i64> {
74 Ok(self.read_u64()? as i64)
75 }
76
77 pub fn read_f32(&mut self) -> Result<f32> {
79 let bits = self.read_u32()?;
80 Ok(f32::from_bits(bits))
81 }
82
83 pub fn read_f64(&mut self) -> Result<f64> {
85 let bits = self.read_u64()?;
86 Ok(f64::from_bits(bits))
87 }
88
89 pub fn read_bool(&mut self) -> Result<bool> {
91 let value = self.read_u8()?;
92 Ok(value != 0)
93 }
94
95 pub fn read_bytes(&mut self, len: usize) -> Result<&'a [u8]> {
97 self.check_size(len)?;
98 let bytes = &self.data[self.position..self.position + len];
99 self.position += len;
100 Ok(bytes)
101 }
102
103 pub fn config(&self) -> Config {
105 self.config
106 }
107
108 pub fn bytes_read(&self) -> usize {
110 self.position
111 }
112
113 pub fn remaining(&self) -> &'a [u8] {
115 &self.data[self.position..]
116 }
117
118 fn check_size(&self, needed: usize) -> Result<()> {
120 let available = self.data.len().saturating_sub(self.position);
121 if available < needed {
122 return Err(JustcodeError::UnexpectedEndOfInput {
123 expected: needed,
124 got: available,
125 });
126 }
127
128 if let Some(limit) = self.config.limit {
130 let new_size = self.position + needed;
131 if new_size > limit {
132 return Err(JustcodeError::SizeLimitExceeded {
133 limit,
134 requested: new_size,
135 });
136 }
137 }
138
139 Ok(())
140 }
141}
142
143#[cfg(test)]
144mod tests {
145 use super::*;
146 use crate::config;
147
148 #[test]
149 fn test_read_primitives() {
150 let config = config::standard();
151 let data = vec![
152 42u8, 0xE8, 0x03, 0xA0, 0x86, 0x01, 0x00, 0x00, 0xCA, 0x9A, 0x3B, 0x00, 0x00, 0x00, 0x00, 1, 0, ];
159
160 let mut reader = Reader::new(&data, config);
161 assert_eq!(reader.read_u8().unwrap(), 42);
162 assert_eq!(reader.read_u16().unwrap(), 1000);
163 assert_eq!(reader.read_u32().unwrap(), 100000);
164 assert_eq!(reader.read_u64().unwrap(), 1000000000);
165 assert_eq!(reader.read_bool().unwrap(), true);
166 assert_eq!(reader.read_bool().unwrap(), false);
167 }
168
169 #[test]
170 fn test_read_floats() {
171 let config = config::standard();
172 let mut writer = crate::writer::Writer::new(config);
173 writer.write_f32(3.14).unwrap();
174 writer.write_f64(2.718).unwrap();
175 let data = writer.into_bytes();
176
177 let mut reader = Reader::new(&data, config);
178 assert!((reader.read_f32().unwrap() - 3.14).abs() < 0.01);
179 assert!((reader.read_f64().unwrap() - 2.718).abs() < 0.001);
180 }
181
182 #[test]
183 fn test_unexpected_end_of_input() {
184 let config = config::standard();
185 let data = vec![42u8];
186 let mut reader = Reader::new(&data, config);
187 assert!(reader.read_u32().is_err());
188 }
189
190 #[test]
191 fn test_size_limit() {
192 let config = config::standard().with_limit(10);
193 let data = vec![0u8; 20];
194 let mut reader = Reader::new(&data, config);
195 assert!(reader.read_bytes(15).is_err());
196 }
197
198 #[test]
199 fn test_read_signed_integers() {
200 let config = config::standard();
201 let mut writer = crate::writer::Writer::new(config);
202 writer.write_i8(-42).unwrap();
203 writer.write_i16(-1000).unwrap();
204 writer.write_i32(-100000).unwrap();
205 writer.write_i64(-1000000000).unwrap();
206 let data = writer.into_bytes();
207
208 let mut reader = Reader::new(&data, config);
209 assert_eq!(reader.read_i8().unwrap(), -42);
210 assert_eq!(reader.read_i16().unwrap(), -1000);
211 assert_eq!(reader.read_i32().unwrap(), -100000);
212 assert_eq!(reader.read_i64().unwrap(), -1000000000);
213 }
214
215 #[test]
216 fn test_read_bytes() {
217 let config = config::standard();
218 let data = vec![1, 2, 3, 4, 5, 6, 7, 8];
219 let mut reader = Reader::new(&data, config);
220 let bytes = reader.read_bytes(4).unwrap();
221 assert_eq!(bytes, &[1, 2, 3, 4]);
222 assert_eq!(reader.bytes_read(), 4);
223 }
224
225 #[test]
226 fn test_remaining() {
227 let config = config::standard();
228 let data = vec![1, 2, 3, 4, 5];
229 let mut reader = Reader::new(&data, config);
230 reader.read_u8().unwrap();
231 assert_eq!(reader.remaining(), &[2, 3, 4, 5]);
232 }
233
234 #[test]
235 fn test_config() {
236 let config = config::standard().with_limit(100);
237 let data = vec![1, 2, 3];
238 let reader = Reader::new(&data, config);
239 assert_eq!(reader.config().limit, Some(100));
240 }
241
242 #[test]
243 fn test_bytes_read() {
244 let config = config::standard();
245 let data = vec![1, 2, 3, 4, 5];
246 let mut reader = Reader::new(&data, config);
247 assert_eq!(reader.bytes_read(), 0);
248 reader.read_u8().unwrap();
249 assert_eq!(reader.bytes_read(), 1);
250 reader.read_u16().unwrap();
251 assert_eq!(reader.bytes_read(), 3);
252 }
253
254 #[test]
255 fn test_size_limit_edge_cases() {
256 let config = config::standard().with_limit(5);
257 let data = vec![0u8; 10];
258 let mut reader = Reader::new(&data, config);
259
260 reader.read_bytes(5).unwrap();
262
263 assert!(reader.read_bytes(1).is_err());
265 }
266
267 #[test]
268 fn test_read_bool_edge_cases() {
269 let config = config::standard();
270 let data = vec![0, 1, 2, 255];
271 let mut reader = Reader::new(&data, config);
272 assert_eq!(reader.read_bool().unwrap(), false);
273 assert_eq!(reader.read_bool().unwrap(), true);
274 assert_eq!(reader.read_bool().unwrap(), true); assert_eq!(reader.read_bool().unwrap(), true); }
277
278 #[test]
279 fn test_check_size_error_message() {
280 let config = config::standard();
281 let data = vec![1u8, 2];
282 let mut reader = Reader::new(&data, config);
283 let err = reader.read_u32().unwrap_err();
284 match err {
285 JustcodeError::UnexpectedEndOfInput { expected, got } => {
286 assert_eq!(expected, 4);
287 assert_eq!(got, 2);
288 }
289 _ => panic!("Expected UnexpectedEndOfInput error"),
290 }
291 }
292
293 #[test]
294 fn test_size_limit_exceeded_error() {
295 let config = config::standard().with_limit(5);
296 let data = vec![0u8; 10];
297 let mut reader = Reader::new(&data, config);
298 reader.read_bytes(5).unwrap();
300 let err = reader.read_bytes(1).unwrap_err();
302 match err {
303 JustcodeError::SizeLimitExceeded { limit, requested } => {
304 assert_eq!(limit, 5);
305 assert_eq!(requested, 6);
306 }
307 _ => panic!("Expected SizeLimitExceeded error"),
308 }
309 }
310
311 #[test]
312 fn test_size_limit_at_boundary() {
313 let config = config::standard().with_limit(5);
314 let data = vec![0u8; 10];
315 let mut reader = Reader::new(&data, config);
316 reader.read_bytes(5).unwrap();
318 assert!(reader.read_bytes(1).is_err());
320 }
321
322 #[test]
323 fn test_check_size_with_limit_none() {
324 let config = config::standard(); let data = vec![1u8, 2, 3, 4, 5];
326 let mut reader = Reader::new(&data, config);
327 reader.read_bytes(5).unwrap();
329 }
330
331 #[test]
332 fn test_check_size_with_limit_success() {
333 let config = config::standard().with_limit(10);
334 let data = vec![0u8; 20];
335 let mut reader = Reader::new(&data, config);
336 reader.read_bytes(5).unwrap();
338 assert_eq!(reader.bytes_read(), 5);
339 }
340
341 #[test]
342 fn test_check_size_exact_error_paths() {
343 let config = config::standard();
344 let data = vec![1u8];
346 let mut reader = Reader::new(&data, config);
347 let err = reader.read_u16().unwrap_err();
348 if let JustcodeError::UnexpectedEndOfInput { expected, got } = err {
349 assert_eq!(expected, 2);
350 assert_eq!(got, 1);
351 } else {
352 panic!("Expected UnexpectedEndOfInput");
353 }
354
355 let config = config::standard().with_limit(3);
357 let data = vec![0u8; 10];
358 let mut reader = Reader::new(&data, config);
359 reader.read_bytes(2).unwrap(); let err = reader.read_bytes(2).unwrap_err(); if let JustcodeError::SizeLimitExceeded { limit, requested } = err {
362 assert_eq!(limit, 3);
363 assert_eq!(requested, 4);
364 } else {
365 panic!("Expected SizeLimitExceeded");
366 }
367 }
368}
369