wasmparser_nostd/
readers.rs1use 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(data: &'a [u8], offset: usize) -> Result<Self> {
87 let mut reader = BinaryReader::new_with_offset(data, offset);
88 let count = reader.read_var_u32()?;
89 Ok(SectionLimited {
90 reader,
91 count,
92 _marker: marker::PhantomData,
93 })
94 }
95
96 pub fn count(&self) -> u32 {
98 self.count
99 }
100
101 pub fn original_position(&self) -> usize {
103 self.reader.original_position()
104 }
105
106 pub fn range(&self) -> Range<usize> {
109 self.reader.range()
110 }
111
112 pub fn into_iter_with_offsets(self) -> SectionLimitedIntoIterWithOffsets<'a, T>
115 where
116 T: FromReader<'a>,
117 {
118 SectionLimitedIntoIterWithOffsets {
119 iter: self.into_iter(),
120 }
121 }
122}
123
124impl<T> Clone for SectionLimited<'_, T> {
125 fn clone(&self) -> Self {
126 SectionLimited {
127 reader: self.reader.clone(),
128 count: self.count,
129 _marker: self._marker,
130 }
131 }
132}
133
134impl<T> fmt::Debug for SectionLimited<'_, T> {
135 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
136 f.debug_struct("SectionLimited")
137 .field("count", &self.count)
138 .field("range", &self.range())
139 .finish()
140 }
141}
142
143impl<'a, T> IntoIterator for SectionLimited<'a, T>
144where
145 T: FromReader<'a>,
146{
147 type Item = Result<T>;
148 type IntoIter = SectionLimitedIntoIter<'a, T>;
149
150 fn into_iter(self) -> Self::IntoIter {
151 SectionLimitedIntoIter {
152 remaining: self.count,
153 section: self,
154 end: false,
155 }
156 }
157}
158
159pub struct SectionLimitedIntoIter<'a, T> {
164 section: SectionLimited<'a, T>,
165 remaining: u32,
166 end: bool,
167}
168
169impl<T> SectionLimitedIntoIter<'_, T> {
170 pub fn original_position(&self) -> usize {
172 self.section.reader.original_position()
173 }
174}
175
176impl<'a, T> Iterator for SectionLimitedIntoIter<'a, T>
177where
178 T: FromReader<'a>,
179{
180 type Item = Result<T>;
181
182 fn next(&mut self) -> Option<Result<T>> {
183 if self.end {
184 return None;
185 }
186 if self.remaining == 0 {
187 self.end = true;
188 if self.section.reader.eof() {
189 return None;
190 }
191 return Some(Err(BinaryReaderError::new(
192 "section size mismatch: unexpected data at the end of the section",
193 self.section.reader.original_position(),
194 )));
195 }
196 let result = self.section.reader.read();
197 self.end = result.is_err();
198 self.remaining -= 1;
199 Some(result)
200 }
201
202 fn size_hint(&self) -> (usize, Option<usize>) {
203 let remaining = self.remaining as usize;
204 (remaining, Some(remaining))
205 }
206}
207
208impl<'a, T> ExactSizeIterator for SectionLimitedIntoIter<'a, T> where T: FromReader<'a> {}
209
210pub struct SectionLimitedIntoIterWithOffsets<'a, T> {
212 iter: SectionLimitedIntoIter<'a, T>,
213}
214
215impl<'a, T> Iterator for SectionLimitedIntoIterWithOffsets<'a, T>
216where
217 T: FromReader<'a>,
218{
219 type Item = Result<(usize, T)>;
220
221 fn next(&mut self) -> Option<Self::Item> {
222 let pos = self.iter.section.reader.original_position();
223 Some(self.iter.next()?.map(|item| (pos, item)))
224 }
225
226 fn size_hint(&self) -> (usize, Option<usize>) {
227 self.iter.size_hint()
228 }
229}
230
231impl<'a, T> ExactSizeIterator for SectionLimitedIntoIterWithOffsets<'a, T> where T: FromReader<'a> {}
232
233pub trait Subsection<'a>: Sized {
240 fn from_reader(id: u8, reader: BinaryReader<'a>) -> Result<Self>;
243}
244
245pub struct Subsections<'a, T> {
251 reader: BinaryReader<'a>,
252 _marker: marker::PhantomData<T>,
253}
254
255impl<'a, T> Subsections<'a, T> {
256 pub fn new(data: &'a [u8], offset: usize) -> Self {
259 Subsections {
260 reader: BinaryReader::new_with_offset(data, offset),
261 _marker: marker::PhantomData,
262 }
263 }
264
265 pub fn original_position(&self) -> usize {
267 self.reader.original_position()
268 }
269
270 pub fn range(&self) -> Range<usize> {
273 self.reader.range()
274 }
275
276 fn read(&mut self) -> Result<T>
277 where
278 T: Subsection<'a>,
279 {
280 let subsection_id = self.reader.read_u7()?;
281 let reader = self.reader.read_reader("unexpected end of section")?;
282 T::from_reader(subsection_id, reader)
283 }
284}
285
286impl<T> Clone for Subsections<'_, T> {
287 fn clone(&self) -> Self {
288 Subsections {
289 reader: self.reader.clone(),
290 _marker: self._marker,
291 }
292 }
293}
294
295impl<T> fmt::Debug for Subsections<'_, T> {
296 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
297 f.debug_struct("Subsections")
298 .field("range", &self.range())
299 .finish()
300 }
301}
302
303impl<'a, T> Iterator for Subsections<'a, T>
304where
305 T: Subsection<'a>,
306{
307 type Item = Result<T>;
308
309 fn next(&mut self) -> Option<Result<T>> {
310 if self.reader.eof() {
311 None
312 } else {
313 Some(self.read())
314 }
315 }
316}