1use crate::{
2 error::{Error, Result},
3 format::Parser,
4};
5use std::{
6 io::{Read, Seek, SeekFrom},
7 ops::{Deref, DerefMut},
8};
9
10#[derive(Debug)]
12pub struct ReadSeek<R> {
13 reader: R,
14 starting_position: u64,
15}
16
17impl<R> ReadSeek<R>
18where
19 R: Read + Seek,
20{
21 pub(crate) fn read_all_bytes(&mut self) -> Result<Vec<u8>> {
22 let current_position = self.stream_position()?;
23 self.seek_starting_position()?;
24
25 let mut bytes = Vec::new();
26 self.read_to_end(&mut bytes)?;
27
28 self.seek(SeekFrom::Start(current_position))?;
29 Ok(bytes)
30 }
31
32 pub(crate) fn seek_starting_position(&mut self) -> Result<()> {
33 self.reader.seek(SeekFrom::Start(self.starting_position))?;
34 Ok(())
35 }
36
37 pub(crate) fn read_usize_from_u32_le_bytes(&mut self) -> Result<usize> {
38 let u = self.read_u32_from_le_bytes()?;
39 Ok(usize_from_u32!(u))
40 }
41
42 pub(crate) fn read_u32_from_le_bytes(&mut self) -> Result<u32> {
43 let mut bytes = [0_u8; 4];
44 self.reader.read_exact(&mut bytes)?;
45
46 Ok(u32::from_le_bytes(bytes))
47 }
48
49 pub(crate) fn read_i32_from_le_bytes(&mut self) -> Result<i32> {
50 let mut bytes = [0_u8; 4];
51 self.reader.read_exact(&mut bytes)?;
52
53 Ok(i32::from_le_bytes(bytes))
54 }
55
56 pub(crate) fn read_u64_from_le_bytes(&mut self) -> Result<u64> {
57 let mut bytes = [0_u8; 8];
58 self.reader.read_exact(&mut bytes)?;
59 Ok(u64::from_le_bytes(bytes))
60 }
61
62 pub(crate) fn read_u16_from_le_bytes(&mut self) -> Result<u16> {
63 let mut bytes = [0_u8; 2];
64 self.reader.read_exact(&mut bytes)?;
65 Ok(u16::from_le_bytes(bytes))
66 }
67}
68
69impl<R> Deref for ReadSeek<R> {
70 type Target = R;
71
72 fn deref(&self) -> &Self::Target {
73 &self.reader
74 }
75}
76
77impl<R> DerefMut for ReadSeek<R> {
78 fn deref_mut(&mut self) -> &mut Self::Target {
79 &mut self.reader
80 }
81}
82
83pub struct Reader<P, R> {
85 inner: ReadSeek<R>,
86 file: P,
87}
88
89impl<P, R> Reader<P, R>
90where
91 P: Parser,
92 R: Read + Seek,
93{
94 pub fn new(mut reader: R) -> Result<Self> {
96 let starting_position = reader.stream_position()?;
97
98 let mut reader = Self {
99 inner: ReadSeek {
100 reader,
101 starting_position,
102 },
103 file: P::default(),
104 };
105
106 let mut id_bytes = [0_u8; 4];
107 reader.inner.read_exact(&mut id_bytes)?;
108
109 if id_bytes != P::ID_BYTES {
110 return Err(Error::InvalidIdentifier {
111 expected_bytes: P::ID_BYTES,
112 bytes_found: id_bytes,
113 });
114 }
115
116 let version = reader.inner.read_u32_from_le_bytes()?;
117
118 if version < P::MIN_SUPPORTED_VERSION {
119 return Err(Error::UnsupportedVersion {
120 version_number_found: version,
121 });
122 }
123
124 Ok(reader)
125 }
126
127 pub fn read(&mut self) -> Result<P::Output> {
129 self.inner.seek_starting_position()?;
130 self.inner.reader.seek(SeekFrom::Current(8))?;
131 self.file.read(&mut self.inner)
132 }
133}