1use super::error::Error;
2use std::mem;
3
4pub struct Reader<'a> {
6 data: &'a [u8],
7 offset: usize,
8}
9
10impl<'a> Reader<'a> {
11 pub fn new(data: &'a [u8]) -> Reader<'a> {
13 Reader { data, offset: 0 }
14 }
15
16 pub fn read_bytes(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
18 if self.data.len() - self.offset < buffer.len() {
19 return Err(Error::Overflow);
20 }
21
22 buffer.copy_from_slice(&self.data[self.offset..self.offset + buffer.len()]);
23 self.offset += buffer.len();
24
25 Ok(())
26 }
27
28 pub fn read<T>(&mut self) -> Result<T, Error>
30 where
31 T: Decode,
32 {
33 T::decode(self)
34 }
35
36 pub fn read_at<T>(&self, offset: usize) -> Result<T, Error>
38 where
39 T: Decode,
40 {
41 if offset >= self.data.len() {
42 return Err(Error::Overflow);
43 }
44
45 Reader {
46 data: self.data,
47 offset,
48 }
49 .read()
50 }
51}
52
53pub trait Decode: Sized {
55 fn decode(reader: &mut Reader) -> Result<Self, Error>;
56
57 fn decode_in_place(data: &[u8]) -> Result<Self, Error> {
61 let mut reader = Reader::new(data);
62 reader.read()
63 }
64}
65
66macro_rules! impl_decode_number {
67 ($($ty:ty)*) => {
68 $(impl Decode for $ty {
69 fn decode(reader: &mut Reader) -> Result<$ty, Error> {
70 let mut bytes = [0u8; mem::size_of::<$ty>()];
71 reader.read_bytes(&mut bytes)?;
72
73 Ok(<$ty>::from_le_bytes(bytes))
74 }
75 })*
76 };
77}
78
79impl_decode_number!(i8 u8 i16 u16 i32 u32 i64 u64 f32 f64);
80
81macro_rules! impl_decode_array {
82 ($($length:expr)*) => {
83 $(impl<T> Decode for [T; $length]
84 where
85 T: Default + Clone + Copy + Decode
86 {
87 fn decode(reader: &mut Reader) -> Result<[T; $length], Error> {
88 let mut data = [Default::default(); $length];
89 for elem in &mut data {
90 *elem = reader.read()?;
91 }
92
93 Ok(data)
94 }
95 })*
96 };
97}
98
99impl_decode_array!(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32);