1use crate::{Error, ErrorKind, Result};
2use byteorder::{LittleEndian, ReadBytesExt};
3use std::io::{Read, Seek, SeekFrom};
4
5pub trait SeekExt: Seek {
6 fn seek_to(&mut self, offset: u64) -> Result<()> {
7 track!(self.seek(SeekFrom::Start(offset)).map_err(Error::from))?;
8 Ok(())
9 }
10}
11impl<T: Seek> SeekExt for T {}
12
13pub trait ReadExt: Read {
14 fn assert_signature(&mut self, expected: &[u8]) -> Result<()> {
15 let mut signature = [0; 4];
16 track!(self.read_bytes(&mut signature))?;
17 track_assert_eq!(&signature, expected, ErrorKind::InvalidFile);
18 Ok(())
19 }
20
21 fn read_all(&mut self) -> Result<Vec<u8>> {
22 let mut buf = Vec::new();
23 track!(self.read_to_end(&mut buf).map_err(Error::from))?;
24 Ok(buf)
25 }
26
27 fn skip(&mut self, n: usize) -> Result<()> {
28 for _ in 0..n {
29 track!(self.read_u8())?;
30 }
31 Ok(())
32 }
33
34 fn read_null_terminated_string(&mut self) -> Result<String> {
35 let mut buf = Vec::new();
36 loop {
37 let b = track!(self.read_u8())?;
38 if b == 0 {
39 break;
40 } else {
41 buf.push(b);
42 }
43 }
44 track!(String::from_utf8(buf).map_err(Error::from))
45 }
46
47 fn read_bytes(&mut self, buf: &mut [u8]) -> Result<()> {
48 track!(self.read_exact(buf).map_err(Error::from))
49 }
50
51 fn read_vec(&mut self, n: usize) -> Result<Vec<u8>> {
52 let mut bytes = vec![0; n];
53 track!(self.read_bytes(&mut bytes))?;
54 Ok(bytes)
55 }
56
57 fn read_u8(&mut self) -> Result<u8> {
58 track!(ReadBytesExt::read_u8(self).map_err(Error::from))
59 }
60
61 fn read_u16(&mut self) -> Result<u16> {
62 track!(ReadBytesExt::read_u16::<LittleEndian>(self).map_err(Error::from))
63 }
64
65 fn read_u24(&mut self) -> Result<u32> {
66 track!(ReadBytesExt::read_u24::<LittleEndian>(self).map_err(Error::from))
67 }
68
69 fn read_u32(&mut self) -> Result<u32> {
70 track!(ReadBytesExt::read_u32::<LittleEndian>(self).map_err(Error::from))
71 }
72
73 fn read_u64(&mut self) -> Result<u64> {
74 track!(ReadBytesExt::read_u64::<LittleEndian>(self).map_err(Error::from))
75 }
76
77 fn read_u128(&mut self) -> Result<u128> {
78 track!(ReadBytesExt::read_u128::<LittleEndian>(self).map_err(Error::from))
79 }
80
81 fn read_f32(&mut self) -> Result<f32> {
82 track!(ReadBytesExt::read_f32::<LittleEndian>(self).map_err(Error::from))
83 }
84}
85impl<T: Read> ReadExt for T {}