1use crate::{BinaryReader, BinaryReaderError, Result};
17use ::core::fmt;
18use ::core::marker;
19use ::core::ops::Range;
20
21mod component;
22mod core;
23
24pub use self::component::*;
25pub use self::core::*;
26
27pub trait FromReader<'a>: Sized {
33 fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self>;
36}
37
38impl<'a> FromReader<'a> for u32 {
39 fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
40 reader.read_var_u32()
41 }
42}
43
44impl<'a> FromReader<'a> for &'a str {
45 fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
46 reader.read_string()
47 }
48}
49
50impl<'a, T, U> FromReader<'a> for (T, U)
51where
52 T: FromReader<'a>,
53 U: FromReader<'a>,
54{
55 fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
56 Ok((reader.read()?, reader.read()?))
57 }
58}
59
60pub struct SectionLimited<'a, T> {
70 reader: BinaryReader<'a>,
71 count: u32,
72 _marker: marker::PhantomData<T>,
73}
74
75impl<'a, T> SectionLimited<'a, T> {
76 pub fn new(mut reader: BinaryReader<'a>) -> Result<Self> {
87 let count = reader.read_var_u32()?;
88 Ok(SectionLimited {
89 reader,
90 count,
91 _marker: marker::PhantomData,
92 })
93 }
94
95 pub fn count(&self) -> u32 {
97 self.count
98 }
99
100 pub fn original_position(&self) -> usize {
102 self.reader.original_position()
103 }
104
105 pub fn range(&self) -> Range<usize> {
108 self.reader.range()
109 }
110
111 pub fn into_iter_with_offsets(self) -> SectionLimitedIntoIterWithOffsets<'a, T>
114 where
115 T: FromReader<'a>,
116 {
117 SectionLimitedIntoIterWithOffsets {
118 iter: self.into_iter(),
119 }
120 }
121}
122
123impl<T> Clone for SectionLimited<'_, T> {
124 fn clone(&self) -> Self {
125 SectionLimited {
126 reader: self.reader.clone(),
127 count: self.count,
128 _marker: self._marker,
129 }
130 }
131}
132
133impl<T> fmt::Debug for SectionLimited<'_, T> {
134 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
135 f.debug_struct("SectionLimited")
136 .field("count", &self.count)
137 .field("range", &self.range())
138 .finish()
139 }
140}
141
142impl<'a, T> IntoIterator for SectionLimited<'a, T>
143where
144 T: FromReader<'a>,
145{
146 type Item = Result<T>;
147 type IntoIter = SectionLimitedIntoIter<'a, T>;
148
149 fn into_iter(self) -> Self::IntoIter {
150 SectionLimitedIntoIter {
151 remaining: self.count,
152 section: self,
153 end: false,
154 }
155 }
156}
157
158pub struct SectionLimitedIntoIter<'a, T> {
163 section: SectionLimited<'a, T>,
164 remaining: u32,
165 end: bool,
166}
167
168impl<T> SectionLimitedIntoIter<'_, T> {
169 pub fn original_position(&self) -> usize {
171 self.section.reader.original_position()
172 }
173}
174
175impl<'a, T> Iterator for SectionLimitedIntoIter<'a, T>
176where
177 T: FromReader<'a>,
178{
179 type Item = Result<T>;
180
181 fn next(&mut self) -> Option<Result<T>> {
182 if self.end {
183 return None;
184 }
185 if self.remaining == 0 {
186 self.end = true;
187 if self.section.reader.eof() {
188 return None;
189 }
190 return Some(Err(BinaryReaderError::new(
191 "section size mismatch: unexpected data at the end of the section",
192 self.section.reader.original_position(),
193 )));
194 }
195 let result = self.section.reader.read();
196 self.end = result.is_err();
197 self.remaining -= 1;
198 Some(result)
199 }
200
201 fn size_hint(&self) -> (usize, Option<usize>) {
202 let remaining = self.remaining as usize;
203 (remaining, Some(remaining))
204 }
205}
206
207impl<'a, T> ExactSizeIterator for SectionLimitedIntoIter<'a, T> where T: FromReader<'a> {}
208
209pub struct SectionLimitedIntoIterWithOffsets<'a, T> {
211 iter: SectionLimitedIntoIter<'a, T>,
212}
213
214impl<'a, T> Iterator for SectionLimitedIntoIterWithOffsets<'a, T>
215where
216 T: FromReader<'a>,
217{
218 type Item = Result<(usize, T)>;
219
220 fn next(&mut self) -> Option<Self::Item> {
221 let pos = self.iter.section.reader.original_position();
222 Some(self.iter.next()?.map(|item| (pos, item)))
223 }
224
225 fn size_hint(&self) -> (usize, Option<usize>) {
226 self.iter.size_hint()
227 }
228}
229
230impl<'a, T> ExactSizeIterator for SectionLimitedIntoIterWithOffsets<'a, T> where T: FromReader<'a> {}
231
232pub trait Subsection<'a>: Sized {
239 fn from_reader(id: u8, reader: BinaryReader<'a>) -> Result<Self>;
242}
243
244pub struct Subsections<'a, T> {
250 reader: BinaryReader<'a>,
251 _marker: marker::PhantomData<T>,
252}
253
254impl<'a, T> Subsections<'a, T> {
255 pub fn new(reader: BinaryReader<'a>) -> Self {
258 Subsections {
259 reader,
260 _marker: marker::PhantomData,
261 }
262 }
263
264 pub fn original_position(&self) -> usize {
266 self.reader.original_position()
267 }
268
269 pub fn range(&self) -> Range<usize> {
272 self.reader.range()
273 }
274
275 fn read(&mut self) -> Result<T>
276 where
277 T: Subsection<'a>,
278 {
279 let subsection_id = self.reader.read_u7()?;
280 let reader = self.reader.read_reader()?;
281 T::from_reader(subsection_id, reader)
282 }
283}
284
285impl<T> Clone for Subsections<'_, T> {
286 fn clone(&self) -> Self {
287 Subsections {
288 reader: self.reader.clone(),
289 _marker: self._marker,
290 }
291 }
292}
293
294impl<T> fmt::Debug for Subsections<'_, T> {
295 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
296 f.debug_struct("Subsections")
297 .field("range", &self.range())
298 .finish()
299 }
300}
301
302impl<'a, T> Iterator for Subsections<'a, T>
303where
304 T: Subsection<'a>,
305{
306 type Item = Result<T>;
307
308 fn next(&mut self) -> Option<Result<T>> {
309 if self.reader.eof() {
310 None
311 } else {
312 Some(self.read())
313 }
314 }
315}