urex_binary_io/
reader.rs

1use byteorder::{BigEndian, LittleEndian, ReadBytesExt};
2use half::f16;
3use std::io::{Read, Result, Seek};
4
5use crate::Endian;
6
7macro_rules! read_method{
8    (array $typ:ty, $size:expr) => {
9        paste::item! {
10            #[doc = "Reads an array of [`" $typ "`]s (" $size " byte(s) each). If len is none the reader will determine the length by reading it."]
11            fn [< read_ $typ _array >] (&mut self, len: Option<usize>) -> Result<Vec<$typ>>{
12                let len = len.unwrap_or_else(|| self.read_array_len().unwrap());
13                Ok(
14                    (0..len)
15                        .map(|_| self.[< read_ $typ >]())
16                        .collect::<Result<Vec<$typ>>>()?
17                )
18            }
19        }
20    };
21
22    ($typ:ty, $size:expr) => {
23        paste::item! {
24            #[doc = "Reads a [`" $typ "`] (" $size " byte(s))."]
25            fn [< read_ $typ >] (&mut self) -> Result<$typ>;
26        }
27
28        read_method!(array $typ, $size);
29    };
30}
31
32pub trait BinaryRead {
33    /// Reads a bool (1 byte).
34    fn read_bool(&mut self) -> Result<bool> {
35        Ok(self.read_u8()? == 1)
36    }
37    read_method!(array bool, 1);
38
39    /// Reads a char (1 byte).
40    fn read_char(&mut self) -> Result<char> {
41        Ok(self.read_u8()? as char)
42    }
43    read_method!(array char, 1);
44
45    read_method!(u8, 1);
46    read_method!(u16, 2);
47    read_method!(u32, 4);
48    read_method!(u64, 8);
49
50    read_method!(i8, 1);
51    read_method!(i16, 2);
52    read_method!(i32, 4);
53    read_method!(i64, 8);
54
55    /// Reads a [`f16`] (2 bytes).
56    fn read_f16(&mut self) -> Result<f32> {
57        Ok(f16::from_bits(self.read_u16()?).to_f32())
58    }
59    /// Reads an array of [`f16`]s (2 byte(s) each). If len is none the reader will determine the length by reading it.
60    fn read_f16_array(&mut self, len: Option<usize>) -> Result<Vec<f32>> {
61        let len = len.unwrap_or_else(|| self.read_array_len().unwrap());
62        // use read_u16_array to benefit from the byteorder read optimizations
63        Ok(self
64            .read_u16_array(Some(len))?
65            .iter()
66            .map(|x| f16::from_bits(*x).to_f32())
67            .collect())
68    }
69
70    read_method!(f32, 4);
71    read_method!(f64, 8);
72
73    /// Reads a c-string (null terminated string).
74    fn read_cstr(&mut self) -> Result<String> {
75        let mut bytes = Vec::new();
76        loop {
77            let byte = self.read_u8()?;
78            if byte == 0 {
79                break;
80            }
81            bytes.push(byte);
82        }
83        Ok(String::from_utf8(bytes).unwrap())
84    }
85
86    /// Reads a string. If len is none the reader will determine the length by reading it.
87    fn read_str(&mut self, len: Option<usize>) -> Result<String> {
88        Ok(String::from_utf8(self.read_bytes(len)?).unwrap())
89    }
90    /// Reads bytes as `Vec<u8>`. If len is none the reader will determine the length by reading it.
91    fn read_bytes(&mut self, len: Option<usize>) -> Result<Vec<u8>> {
92        self.read_u8_array(len)
93    }
94
95    /// Reads the length for an array.
96    fn read_array_len(&mut self) -> Result<usize>;
97
98    /// Reads an array of c-strings. If len is none the reader will determine the length by reading it.
99    fn read_cstr_array(&mut self, len: Option<usize>) -> Result<Vec<String>> {
100        let len = len.unwrap_or_else(|| self.read_array_len().unwrap());
101        Ok((0..len)
102            .map(|_| self.read_cstr())
103            .collect::<Result<Vec<String>>>()?)
104    }
105    /// Reads an array of strings. If len is none the reader will determine the length by reading it.
106    fn read_str_array(&mut self, len: Option<usize>) -> Result<Vec<String>> {
107        let len = len.unwrap_or_else(|| self.read_array_len().unwrap());
108        Ok((0..len)
109            .map(|_| self.read_str(None))
110            .collect::<Result<Vec<String>>>()?)
111    }
112    /// Reads an array of bytes. If len is none the reader will determine the length by reading it.
113    fn read_bytes_array(&mut self, len: Option<usize>) -> Result<Vec<Vec<u8>>> {
114        let len = len.unwrap_or_else(|| self.read_array_len().unwrap());
115        Ok((0..len)
116            .map(|_| self.read_bytes(None))
117            .collect::<Result<Vec<Vec<u8>>>>()?)
118    }
119}
120
121pub trait BinaryReadAlign: BinaryRead + Seek {
122    /// Align the reader to the given alignment and return the aligned position.
123    fn align(&mut self, alignment: usize) -> Result<usize>;
124    /// Align the reader to 4 bytes.
125    fn align4(&mut self) -> Result<usize> {
126        self.align(4)
127    }
128    /// Align the reader to 8 bytes.
129    fn align8(&mut self) -> Result<usize> {
130        self.align(8)
131    }
132    /// Align the reader to 16 bytes.
133    fn align16(&mut self) -> Result<usize> {
134        self.align(16)
135    }
136}
137
138// =================================================================================================
139//
140// Method implementation macros for BinaryReader structs
141//
142// =================================================================================================
143
144macro_rules! implement_generic_methods {
145    () => {
146        fn read_u8(&mut self) -> Result<u8> {
147            self.inner.read_u8()
148        }
149
150        fn read_u8_array(&mut self, len: Option<usize>) -> Result<Vec<u8>> {
151            let len = len.unwrap_or_else(|| self.read_array_len().unwrap());
152            let mut buf = vec![0u8; len];
153            self.inner.read_exact(&mut buf)?;
154            Ok(buf)
155        }
156
157        fn read_i8(&mut self) -> Result<i8> {
158            self.inner.read_i8()
159        }
160
161        fn read_i8_array(&mut self, len: Option<usize>) -> Result<Vec<i8>> {
162            let len = len.unwrap_or_else(|| self.read_array_len().unwrap());
163            let mut buf = vec![0i8; len];
164            self.inner.read_i8_into(&mut buf)?;
165            Ok(buf)
166        }
167
168        fn read_array_len(&mut self) -> Result<usize> {
169            Ok(self.read_u32()? as usize)
170        }
171    };
172}
173
174/// Implement a read and read_array method for a type with the given from_(b/l)e_bytes method.
175macro_rules! implement_read_e_method {
176    ($endian:expr, $type:ty) => {
177        paste::item! {
178            fn [< read_ $type >] (&mut self) -> Result<$type> {
179                self.inner.[<read_ $type>]::<$endian>()
180            }
181        }
182        paste::item! {
183            fn [< read_ $type _array >] (&mut self, len: Option<usize>) -> Result<Vec<$type>> {
184                let len = len.unwrap_or_else(|| self.read_array_len().unwrap());
185                let mut ret: Vec<$type> = Vec::with_capacity(len);
186                self.inner.[<read_ $type _into>]::<$endian>(ret.as_mut_slice()).unwrap();
187                Ok(ret)
188            }
189        }
190    };
191
192    ($endian:expr, $($typ:ty),+) => (
193        $(implement_read_e_method!($endian, $typ);)+
194    )
195}
196
197/// Implement a read and read_array method for a type with a variable endian.
198macro_rules! implement_read_ve_method {
199    ($type:ty) => {
200        // implement read_$type
201        paste::item! {
202            fn [< read_ $type >] (&mut self) -> Result<$type> {
203                match self.endian {
204                    Endian::Little => self.inner.[<read_ $type>]::<LittleEndian>(),
205                    Endian::Big => self.inner.[<read_ $type>]::<BigEndian>(),
206                }
207            }
208        }
209        paste::item! {
210            fn [< read_ $type _array >] (&mut self, len: Option<usize>) -> Result<Vec<$type>> {
211                let len = len.unwrap_or_else(|| self.read_array_len().unwrap());
212                let mut ret: Vec<$type> = Vec::with_capacity(len);
213                match self.endian {
214                    Endian::Little => {
215                        self.inner.[<read_ $type _into>]::<LittleEndian>(ret.as_mut_slice()).unwrap();
216                    }
217                    Endian::Big => {
218                        self.inner.[<read_ $type _into>]::<BigEndian>(ret.as_mut_slice()).unwrap();
219                    }
220                }
221                Ok(ret)
222            }
223        }
224    };
225
226    ($($typ:ty),+) => (
227        $(implement_read_ve_method!($typ);)+
228    )
229}
230
231macro_rules! generate_BinaryReaderE {
232    ($name: ident, $byteorder: ident) => {
233        pub struct $name<R> {
234            pub inner: R,
235        }
236
237        impl<R: Read> $name<R> {
238            pub fn new(inner: R) -> Self {
239                Self { inner }
240            }
241        }
242
243        impl<R: Read> BinaryRead for $name<R> {
244            implement_generic_methods!();
245            implement_read_e_method!($byteorder, u16, u32, u64, i16, i32, i64, f32, f64);
246        }
247    };
248}
249
250macro_rules! implement_align_method {
251    ($struct_:ident) => {
252        impl<R: Seek> $struct_<R> {
253            pub fn align(&mut self, alignment: usize) -> Result<()> {
254                let pos = self.inner.seek(std::io::SeekFrom::Current(0))?;
255                let rem = pos % alignment as u64;
256                if rem != 0 {
257                    self.inner.seek(std::io::SeekFrom::Current(rem as i64))?;
258                }
259                Ok(())
260            }
261        }
262
263        impl<R: Seek> Seek for $struct_<R> {
264            fn seek(&mut self, pos: std::io::SeekFrom) -> Result<u64> {
265                self.inner.seek(pos)
266            }
267
268            fn stream_position(&mut self) -> Result<u64> {
269                self.inner.stream_position()
270            }
271        }
272    };
273
274    ($($typ:ident),+) => (
275        $(implement_align_method!($typ);)+
276    )
277}
278
279// =================================================================================================
280//
281// BinaryReader implementations
282//
283// =================================================================================================
284
285pub struct BinaryReaderVE<R> {
286    pub inner: R,
287    pub endian: Endian,
288}
289
290impl<R: Read> BinaryReaderVE<R> {
291    pub fn new(inner: R, endian: Endian) -> Self {
292        Self { inner, endian }
293    }
294}
295
296impl<R: Read> BinaryRead for BinaryReaderVE<R> {
297    implement_generic_methods!();
298    implement_read_ve_method!(u16, u32, u64, i16, i32, i64, f32, f64);
299}
300
301generate_BinaryReaderE!(BinaryReaderLE, LittleEndian);
302generate_BinaryReaderE!(BinaryReaderBE, BigEndian);
303implement_align_method!(BinaryReaderLE, BinaryReaderBE, BinaryReaderVE);
304
305// =================================================================================================
306//
307// Tests
308//
309// =================================================================================================
310
311#[cfg(test)]
312mod tests {
313    use super::*;
314    use std::io::Cursor;
315    fn test_read_unsigned(reader: &mut impl (BinaryRead)) -> Result<()> {
316        assert_eq!(reader.read_u8()?, 0x1);
317        assert_eq!(reader.read_u16()?, 0x1234);
318        assert_eq!(reader.read_u32()?, 0x12345678);
319        assert_eq!(reader.read_u64()?, 0x1234567890123456);
320        Ok(())
321    }
322
323    fn test_read_signed(reader: &mut dyn BinaryRead) -> Result<()> {
324        assert_eq!(reader.read_i8()?, 0x1);
325        assert_eq!(reader.read_i16()?, -0x1234);
326        assert_eq!(reader.read_i32()?, 0x12345678);
327        assert_eq!(reader.read_i64()?, -0x1234567890123456);
328        Ok(())
329    }
330
331    fn test_read_float(reader: &mut dyn BinaryRead) -> Result<()> {
332        assert_eq!(reader.read_f16()?, f16::from_f32(0.16).to_f32());
333        assert_eq!(reader.read_f32()?, -0.32);
334        assert_eq!(reader.read_f64()?, 0.64);
335        Ok(())
336    }
337
338    #[test]
339    pub fn test_binary_reader() {
340        let mut reader = BinaryReaderVE::new(
341            Cursor::new(&b"\x014\x12xV4\x12V4\x12\x90xV4\x12"[..]),
342            Endian::Little,
343        );
344        test_read_unsigned(&mut reader).unwrap();
345
346        let mut reader = BinaryReaderVE::new(
347            Cursor::new(&b"\x01\xcc\xedxV4\x12\xaa\xcb\xedo\x87\xa9\xcb\xed"[..]),
348            Endian::Little,
349        );
350        test_read_signed(&mut reader).unwrap();
351
352        let mut reader = BinaryReaderVE::new(
353            Cursor::new(&b"\x1f1\n\xd7\xa3\xbe{\x14\xaeG\xe1z\xe4?"[..]),
354            Endian::Little,
355        );
356        test_read_float(&mut reader).unwrap();
357
358        let mut reader = BinaryReaderVE::new(
359            Cursor::new(&b"\x01\x124\x124Vx\x124Vx\x90\x124V"[..]),
360            Endian::Big,
361        );
362        test_read_unsigned(&mut reader).unwrap();
363
364        let mut reader = BinaryReaderVE::new(
365            Cursor::new(&b"\x01\xed\xcc\x124Vx\xed\xcb\xa9\x87o\xed\xcb\xaa"[..]),
366            Endian::Big,
367        );
368        test_read_signed(&mut reader).unwrap();
369
370        let mut reader = BinaryReaderVE::new(
371            Cursor::new(&b"1\x1f\xbe\xa3\xd7\n?\xe4z\xe1G\xae\x14{"[..]),
372            Endian::Big,
373        );
374        test_read_float(&mut reader).unwrap();
375    }
376
377    #[test]
378    pub fn test_binary_reader_le() {
379        let mut reader =
380            BinaryReaderLE::new(Cursor::new(&b"\x014\x12xV4\x12V4\x12\x90xV4\x12"[..]));
381        test_read_unsigned(&mut reader).unwrap();
382
383        let mut reader = BinaryReaderLE::new(Cursor::new(
384            &b"\x01\xcc\xedxV4\x12\xaa\xcb\xedo\x87\xa9\xcb\xed"[..],
385        ));
386        test_read_signed(&mut reader).unwrap();
387
388        let mut reader =
389            BinaryReaderLE::new(Cursor::new(&b"\x1f1\n\xd7\xa3\xbe{\x14\xaeG\xe1z\xe4?"[..]));
390        test_read_float(&mut reader).unwrap();
391    }
392
393    #[test]
394    pub fn test_binary_reader_be() {
395        let mut reader =
396            BinaryReaderBE::new(Cursor::new(&b"\x01\x124\x124Vx\x124Vx\x90\x124V"[..]));
397        test_read_unsigned(&mut reader).unwrap();
398
399        let mut reader = BinaryReaderBE::new(Cursor::new(
400            &b"\x01\xed\xcc\x124Vx\xed\xcb\xa9\x87o\xed\xcb\xaa"[..],
401        ));
402        test_read_signed(&mut reader).unwrap();
403
404        let mut reader =
405            BinaryReaderBE::new(Cursor::new(&b"1\x1f\xbe\xa3\xd7\n?\xe4z\xe1G\xae\x14{"[..]));
406        test_read_float(&mut reader).unwrap();
407    }
408}