1use std::io::Read;
24
25use nom::{
26 Needed,
27 number::streaming::{be_f32, be_f64, be_i32, be_i64, be_u8, be_u16},
28};
29
30use crate::{
31 AbxError, Attribute, AttributeValue, CMD_ATTRIBUTE, CMD_CDSECT, CMD_COMMENT, CMD_DOCDECL,
32 CMD_END_DOCUMENT, CMD_END_TAG, CMD_ENTITY_REF, CMD_IGNORABLE_WHITESPACE,
33 CMD_PROCESSING_INSTRUCTION, CMD_START_DOCUMENT, CMD_START_TAG, CMD_TEXT, Event, MAGIC, Result,
34 TYPE_BOOLEAN_FALSE, TYPE_BOOLEAN_TRUE, TYPE_BYTES_BASE64, TYPE_BYTES_HEX, TYPE_DOUBLE,
35 TYPE_FLOAT, TYPE_INT, TYPE_INT_HEX, TYPE_LONG, TYPE_LONG_HEX, TYPE_NULL, TYPE_STRING,
36 TYPE_STRING_INTERNED, render_event,
37};
38
39use crate::INTERNED_NEW;
40use std::collections::HashMap;
41
42const INITIAL_BUF: usize = 4096;
44const READ_CHUNK: usize = 4096;
46
47#[derive(Debug)]
71pub struct AbxStreamParser<R: Read> {
72 reader: R,
73 buf: Vec<u8>,
75 pos: usize,
77 len: usize,
79 eof: bool,
81 pool: Vec<crate::InternedStr>,
83}
84
85impl<R: Read> AbxStreamParser<R> {
86 pub fn new(reader: R) -> Result<Self> {
91 let mut p = AbxStreamParser {
92 reader,
93 buf: vec![0u8; INITIAL_BUF],
94 pos: 0,
95 len: 0,
96 eof: false,
97 pool: Vec::with_capacity(32),
98 };
99
100 p.ensure(4)?;
102
103 let magic: [u8; 4] = p.buf[p.pos..p.pos + 4].try_into().unwrap();
104 if magic != MAGIC {
105 return Err(AbxError::InvalidMagic {
106 expected: MAGIC,
107 actual: magic,
108 });
109 }
110 p.pos += 4;
111 Ok(p)
112 }
113
114 #[inline]
116 fn available(&self) -> usize {
117 self.len - self.pos
118 }
119
120 fn ensure(&mut self, needed: usize) -> Result<()> {
124 if self.available() >= needed || self.eof {
130 return Ok(());
131 }
132
133 if self.pos > 0 {
135 self.buf.copy_within(self.pos..self.len, 0);
136 self.len -= self.pos;
137 self.pos = 0;
138 }
139
140 while self.available() < needed && !self.eof {
141 let spare = self.buf.len() - self.len;
143 if spare < READ_CHUNK {
144 self.buf
145 .resize(self.len + READ_CHUNK.max(needed - self.available()), 0);
146 }
147
148 let n = self.reader.read(&mut self.buf[self.len..])?;
149 if n == 0 {
150 self.eof = true;
151 } else {
152 self.len += n;
153 }
154 }
155
156 Ok(())
157 }
158
159 fn parse<F, T>(&mut self, mut f: F) -> Result<T>
162 where
163 F: FnMut(&[u8]) -> nom::IResult<&[u8], T>,
164 {
165 loop {
166 match f(&self.buf[self.pos..self.len]) {
167 Ok((rest, val)) => {
168 self.pos = self.len - rest.len();
169 return Ok(val);
170 }
171 Err(nom::Err::Incomplete(Needed::Size(n))) => {
172 let need = self.available() + n.get();
173 self.ensure(need)?;
174 if self.eof && self.available() < n.get() {
175 return Err(AbxError::UnexpectedEof("primitive"));
176 }
177 }
178 Err(nom::Err::Incomplete(Needed::Unknown)) => {
179 self.ensure(self.available() + 1)?;
181 if self.eof {
182 return Err(AbxError::UnexpectedEof("primitive"));
183 }
184 }
185 Err(e) => return Err(AbxError::Nom(format!("{e:?}"))),
186 }
187 }
188 }
189
190 fn read_u8(&mut self) -> Result<u8> {
191 self.parse(|i| be_u8(i))
192 }
193 fn read_u16(&mut self) -> Result<u16> {
194 self.parse(|i| be_u16(i))
195 }
196 fn read_i32(&mut self) -> Result<i32> {
197 self.parse(|i| be_i32(i))
198 }
199 fn read_i64(&mut self) -> Result<i64> {
200 self.parse(|i| be_i64(i))
201 }
202 fn read_f32(&mut self) -> Result<f32> {
203 self.parse(|i| be_f32(i))
204 }
205 fn read_f64(&mut self) -> Result<f64> {
206 self.parse(|i| be_f64(i))
207 }
208
209 fn read_utf(&mut self) -> Result<String> {
211 let len = self.read_u16()? as usize;
212 self.ensure(len)?;
214 if self.available() < len {
215 return Err(AbxError::UnexpectedEof("UTF string payload"));
216 }
217 let s = std::str::from_utf8(&self.buf[self.pos..self.pos + len])
218 .map_err(|_| AbxError::InvalidUtf8)?
219 .to_owned();
220 self.pos += len;
221 Ok(s)
222 }
223
224 fn read_bytes_blob(&mut self) -> Result<Vec<u8>> {
226 let len = self.read_u16()? as usize;
227 self.ensure(len)?;
228 if self.available() < len {
229 return Err(AbxError::UnexpectedEof("bytes payload"));
230 }
231 let v = self.buf[self.pos..self.pos + len].to_vec();
232 self.pos += len;
233 Ok(v)
234 }
235
236 fn read_interned(&mut self) -> Result<crate::InternedStr> {
240 let idx = self.read_u16()?;
241 if idx == INTERNED_NEW {
242 let s: crate::InternedStr = self.read_utf()?.into();
243 self.pool.push(s.clone());
244 Ok(s)
245 } else {
246 self.pool
247 .get(idx as usize)
248 .cloned()
249 .ok_or(AbxError::BadInternedIndex(idx))
250 }
251 }
252
253 fn read_attr_value(&mut self, type_nibble: u8) -> Result<AttributeValue> {
254 match type_nibble {
255 TYPE_NULL => Ok(AttributeValue::Null),
256 TYPE_STRING => Ok(AttributeValue::String(self.read_utf()?)),
257 TYPE_STRING_INTERNED => Ok(AttributeValue::String(String::from(self.read_interned()?))),
258 TYPE_BYTES_HEX => Ok(AttributeValue::BytesHex(self.read_bytes_blob()?)),
259 TYPE_BYTES_BASE64 => Ok(AttributeValue::BytesBase64(self.read_bytes_blob()?)),
260 TYPE_INT => Ok(AttributeValue::Int(self.read_i32()?)),
261 TYPE_INT_HEX => Ok(AttributeValue::IntHex(self.read_i32()? as u32)),
262 TYPE_LONG => Ok(AttributeValue::Long(self.read_i64()?)),
263 TYPE_LONG_HEX => Ok(AttributeValue::LongHex(self.read_i64()? as u64)),
264 TYPE_FLOAT => Ok(AttributeValue::Float(self.read_f32()?)),
265 TYPE_DOUBLE => Ok(AttributeValue::Double(self.read_f64()?)),
266 TYPE_BOOLEAN_TRUE => Ok(AttributeValue::Boolean(true)),
267 TYPE_BOOLEAN_FALSE => Ok(AttributeValue::Boolean(false)),
268 other => Err(AbxError::UnknownAttributeType(other)),
269 }
270 }
271
272 fn peek_u8(&mut self) -> Result<Option<u8>> {
274 self.ensure(1)?;
275 Ok(self.buf.get(self.pos).copied())
276 }
277
278 pub fn next_event(&mut self) -> Result<Option<Event>> {
280 self.ensure(1)?;
282 if self.available() == 0 {
283 return Ok(None);
284 }
285
286 let token = self.read_u8()?;
287 let cmd = token & 0x0F;
288 let type_nibble = token & 0xF0;
289
290 let event = match cmd {
291 CMD_START_DOCUMENT => Event::StartDocument,
292 CMD_END_DOCUMENT => return Ok(Some(Event::EndDocument)),
293
294 CMD_START_TAG => {
295 let name = self.read_interned()?;
296 let mut attributes = Vec::with_capacity(4);
297
298 loop {
301 match self.peek_u8()? {
302 Some(next) if (next & 0x0F) == CMD_ATTRIBUTE => {
303 self.pos += 1; let attr_type = next & 0xF0;
305 let attr_name = self.read_interned()?;
306 let attr_value = self.read_attr_value(attr_type)?;
307 attributes.push(Attribute {
308 name: attr_name,
309 value: attr_value,
310 });
311 }
312 _ => break,
313 }
314 }
315
316 Event::StartTag { name, attributes }
317 }
318
319 CMD_END_TAG => Event::EndTag {
320 name: self.read_interned()?,
321 },
322
323 CMD_TEXT => Event::Text(if type_nibble == TYPE_STRING {
324 self.read_utf()?
325 } else {
326 String::new()
327 }),
328 CMD_CDSECT => Event::CdataSection(if type_nibble == TYPE_STRING {
329 self.read_utf()?
330 } else {
331 String::new()
332 }),
333 CMD_ENTITY_REF => Event::EntityReference(if type_nibble == TYPE_STRING {
334 self.read_utf()?
335 } else {
336 String::new()
337 }),
338 CMD_IGNORABLE_WHITESPACE => Event::IgnorableWhitespace(if type_nibble == TYPE_STRING {
339 self.read_utf()?
340 } else {
341 String::new()
342 }),
343 CMD_PROCESSING_INSTRUCTION => {
344 Event::ProcessingInstruction(if type_nibble == TYPE_STRING {
345 self.read_utf()?
346 } else {
347 String::new()
348 })
349 }
350 CMD_COMMENT => Event::Comment(if type_nibble == TYPE_STRING {
351 self.read_utf()?
352 } else {
353 String::new()
354 }),
355 CMD_DOCDECL => Event::DocDecl(if type_nibble == TYPE_STRING {
356 self.read_utf()?
357 } else {
358 String::new()
359 }),
360
361 other => return Err(AbxError::UnknownCommand(other)),
362 };
363
364 Ok(Some(event))
365 }
366
367 pub fn collect_events(&mut self) -> Result<Vec<Event>> {
369 let mut out = Vec::new();
370 while let Some(ev) = self.next_event()? {
371 out.push(ev);
372 }
373 Ok(out)
374 }
375
376 pub fn find_attribute(&mut self, element: &str, attr: &str) -> Result<Option<AttributeValue>> {
382 loop {
383 match self.next_event()? {
384 Some(Event::StartTag { name, attributes }) if name == element => {
385 if let Some(a) = attributes.into_iter().find(|a| a.name == attr) {
386 return Ok(Some(a.value));
387 }
388 }
389 Some(Event::EndDocument) | None => return Ok(None),
390 _ => {}
391 }
392 }
393 }
394
395 pub fn find_all_attributes(
397 &mut self,
398 element: &str,
399 attr: &str,
400 ) -> Result<Vec<AttributeValue>> {
401 let mut out = Vec::new();
402 while let Some(ev) = self.next_event()? {
403 if let Event::StartTag { name, attributes } = ev
404 && name == element
405 {
406 out.extend(
407 attributes
408 .into_iter()
409 .filter(|a| a.name == attr)
410 .map(|a| a.value),
411 );
412 }
413 }
414 Ok(out)
415 }
416
417 pub fn attributes_of(&mut self, element: &str) -> Result<Option<Vec<Attribute>>> {
423 loop {
424 match self.next_event()? {
425 Some(Event::StartTag { name, attributes }) if name == element => {
426 return Ok(Some(attributes));
427 }
428 Some(Event::EndDocument) | None => return Ok(None),
429 _ => {}
430 }
431 }
432 }
433
434 pub fn all_attributes_of(&mut self, element: &str) -> Result<Vec<Vec<Attribute>>> {
436 let mut out = Vec::new();
437 while let Some(ev) = self.next_event()? {
438 if let Event::StartTag { name, attributes } = ev
439 && name == element
440 {
441 out.push(attributes);
442 }
443 }
444 Ok(out)
445 }
446
447 #[cfg(feature = "serialize")]
451 pub fn deserialize_next<T: serde::de::DeserializeOwned>(
452 &mut self,
453 element: &str,
454 ) -> Result<Option<T>> {
455 crate::de::find_and_consume_element(self, element)
456 }
457
458 #[cfg(feature = "serialize")]
460 pub fn deserialize_all<T: serde::de::DeserializeOwned>(
461 &mut self,
462 element: &str,
463 ) -> Result<Vec<T>> {
464 let mut out = Vec::new();
465 while let Some(item) = self.deserialize_next(element)? {
466 out.push(item);
467 }
468 Ok(out)
469 }
470
471 #[cfg(feature = "serialize")]
475 pub fn deserialize_iter<'p, T: serde::de::DeserializeOwned>(
476 &'p mut self,
477 element: &'p str,
478 ) -> DeserializeIter<'p, R, T> {
479 DeserializeIter {
480 parser: self,
481 element,
482 _marker: std::marker::PhantomData,
483 }
484 }
485
486 pub fn to_xml(&mut self) -> Result<String> {
488 let mut buf = String::from(r#"<?xml version="1.0" encoding="UTF-8"?>"#);
489 while let Some(ev) = self.next_event()? {
490 if matches!(ev, Event::EndDocument) {
491 break;
492 }
493 render_event(&ev, &mut buf);
494 }
495 Ok(buf)
496 }
497
498 pub fn write_xml(&mut self, writer: &mut impl std::io::Write) -> Result<()> {
503 writer.write_all(b"<?xml version=\"1.0\" encoding=\"UTF-8\"?>")?;
504 let mut tmp = String::new();
507 while let Some(ev) = self.next_event()? {
508 if matches!(ev, Event::EndDocument) {
509 break;
510 }
511 tmp.clear();
512 render_event(&ev, &mut tmp);
513 writer.write_all(tmp.as_bytes())?;
514 }
515 Ok(())
516 }
517
518 pub fn into_map(mut self) -> Result<HashMap<String, Vec<HashMap<String, String>>>> {
520 let mut map: HashMap<String, Vec<HashMap<String, String>>> = HashMap::new();
521 while let Some(ev) = self.next_event()? {
522 if let Event::StartTag { name, attributes } = ev {
523 let entry = map.entry(name.into()).or_default();
524 let mut attrs = HashMap::new();
525 for attr in attributes {
526 attrs.insert(attr.name.into(), attr.value.as_str().into_owned());
527 }
528 entry.push(attrs);
529 }
530 }
531 Ok(map)
532 }
533
534 pub fn into_inner(self) -> R {
536 self.reader
537 }
538}
539
540impl<R: Read> Iterator for AbxStreamParser<R> {
541 type Item = Result<Event>;
542
543 fn next(&mut self) -> Option<Self::Item> {
544 match self.next_event() {
545 Ok(Some(ev)) => Some(Ok(ev)),
546 Ok(None) => None,
547 Err(e) => Some(Err(e)),
548 }
549 }
550}
551
552#[cfg(feature = "serialize")]
555pub struct DeserializeIter<'p, R: Read, T> {
556 parser: &'p mut AbxStreamParser<R>,
557 element: &'p str,
558 _marker: std::marker::PhantomData<T>,
559}
560
561#[cfg(feature = "serialize")]
562impl<'p, R: Read, T: serde::de::DeserializeOwned> Iterator for DeserializeIter<'p, R, T> {
563 type Item = Result<T>;
564
565 fn next(&mut self) -> Option<Self::Item> {
566 self.parser.deserialize_next(self.element).transpose()
567 }
568}