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 fn read_bool(&mut self) -> Result<bool> {
35 Ok(self.read_u8()? == 1)
36 }
37 read_method!(array bool, 1);
38
39 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 fn read_f16(&mut self) -> Result<f32> {
57 Ok(f16::from_bits(self.read_u16()?).to_f32())
58 }
59 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 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 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 fn read_str(&mut self, len: Option<usize>) -> Result<String> {
88 Ok(String::from_utf8(self.read_bytes(len)?).unwrap())
89 }
90 fn read_bytes(&mut self, len: Option<usize>) -> Result<Vec<u8>> {
92 self.read_u8_array(len)
93 }
94
95 fn read_array_len(&mut self) -> Result<usize>;
97
98 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 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 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 fn align(&mut self, alignment: usize) -> Result<usize>;
124 fn align4(&mut self) -> Result<usize> {
126 self.align(4)
127 }
128 fn align8(&mut self) -> Result<usize> {
130 self.align(8)
131 }
132 fn align16(&mut self) -> Result<usize> {
134 self.align(16)
135 }
136}
137
138macro_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
174macro_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
197macro_rules! implement_read_ve_method {
199 ($type:ty) => {
200 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
279pub 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#[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}