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> {
95 let mut p = AbxStreamParser {
96 reader,
97 buf: vec![0u8; INITIAL_BUF],
98 pos: 0,
99 len: 0,
100 eof: false,
101 pool: Vec::with_capacity(32),
102 };
103
104 p.ensure(4)?;
106
107 let magic: [u8; 4] = p.buf[p.pos..p.pos + 4].try_into().unwrap();
108 if magic != MAGIC {
109 return Err(AbxError::InvalidMagic {
110 expected: MAGIC,
111 actual: magic,
112 });
113 }
114 p.pos += 4;
115 Ok(p)
116 }
117
118 #[inline]
124 fn available(&self) -> usize {
125 self.len - self.pos
126 }
127
128 fn ensure(&mut self, needed: usize) -> Result<()> {
132 if self.available() >= needed || self.eof {
138 return Ok(());
139 }
140
141 if self.pos > 0 {
143 self.buf.copy_within(self.pos..self.len, 0);
144 self.len -= self.pos;
145 self.pos = 0;
146 }
147
148 while self.available() < needed && !self.eof {
149 let spare = self.buf.len() - self.len;
151 if spare < READ_CHUNK {
152 self.buf
153 .resize(self.len + READ_CHUNK.max(needed - self.available()), 0);
154 }
155
156 let n = self.reader.read(&mut self.buf[self.len..])?;
157 if n == 0 {
158 self.eof = true;
159 } else {
160 self.len += n;
161 }
162 }
163
164 Ok(())
165 }
166
167 fn parse<F, T>(&mut self, mut f: F) -> Result<T>
174 where
175 F: FnMut(&[u8]) -> nom::IResult<&[u8], T>,
176 {
177 loop {
178 match f(&self.buf[self.pos..self.len]) {
179 Ok((rest, val)) => {
180 self.pos = self.len - rest.len();
181 return Ok(val);
182 }
183 Err(nom::Err::Incomplete(Needed::Size(n))) => {
184 let need = self.available() + n.get();
185 self.ensure(need)?;
186 if self.eof && self.available() < n.get() {
187 return Err(AbxError::UnexpectedEof("primitive"));
188 }
189 }
190 Err(nom::Err::Incomplete(Needed::Unknown)) => {
191 self.ensure(self.available() + 1)?;
193 if self.eof {
194 return Err(AbxError::UnexpectedEof("primitive"));
195 }
196 }
197 Err(e) => return Err(AbxError::Nom(format!("{e:?}"))),
198 }
199 }
200 }
201
202 fn read_u8(&mut self) -> Result<u8> {
203 self.parse(|i| be_u8(i))
204 }
205 fn read_u16(&mut self) -> Result<u16> {
206 self.parse(|i| be_u16(i))
207 }
208 fn read_i32(&mut self) -> Result<i32> {
209 self.parse(|i| be_i32(i))
210 }
211 fn read_i64(&mut self) -> Result<i64> {
212 self.parse(|i| be_i64(i))
213 }
214 fn read_f32(&mut self) -> Result<f32> {
215 self.parse(|i| be_f32(i))
216 }
217 fn read_f64(&mut self) -> Result<f64> {
218 self.parse(|i| be_f64(i))
219 }
220
221 fn read_utf(&mut self) -> Result<String> {
223 let len = self.read_u16()? as usize;
224 self.ensure(len)?;
226 if self.available() < len {
227 return Err(AbxError::UnexpectedEof("UTF string payload"));
228 }
229 let s = std::str::from_utf8(&self.buf[self.pos..self.pos + len])
230 .map_err(|_| AbxError::InvalidUtf8)?
231 .to_owned();
232 self.pos += len;
233 Ok(s)
234 }
235
236 fn read_bytes_blob(&mut self) -> Result<Vec<u8>> {
238 let len = self.read_u16()? as usize;
239 self.ensure(len)?;
240 if self.available() < len {
241 return Err(AbxError::UnexpectedEof("bytes payload"));
242 }
243 let v = self.buf[self.pos..self.pos + len].to_vec();
244 self.pos += len;
245 Ok(v)
246 }
247
248 fn read_interned(&mut self) -> Result<crate::InternedStr> {
252 let idx = self.read_u16()?;
253 if idx == INTERNED_NEW {
254 let s: crate::InternedStr = self.read_utf()?.into();
255 self.pool.push(s.clone());
256 Ok(s)
257 } else {
258 self.pool
259 .get(idx as usize)
260 .cloned()
261 .ok_or(AbxError::BadInternedIndex(idx))
262 }
263 }
264
265 fn read_attr_value(&mut self, type_nibble: u8) -> Result<AttributeValue> {
270 match type_nibble {
271 TYPE_NULL => Ok(AttributeValue::Null),
272 TYPE_STRING => Ok(AttributeValue::String(self.read_utf()?)),
273 TYPE_STRING_INTERNED => Ok(AttributeValue::String(String::from(self.read_interned()?))),
274 TYPE_BYTES_HEX => Ok(AttributeValue::BytesHex(self.read_bytes_blob()?)),
275 TYPE_BYTES_BASE64 => Ok(AttributeValue::BytesBase64(self.read_bytes_blob()?)),
276 TYPE_INT => Ok(AttributeValue::Int(self.read_i32()?)),
277 TYPE_INT_HEX => Ok(AttributeValue::IntHex(self.read_i32()? as u32)),
278 TYPE_LONG => Ok(AttributeValue::Long(self.read_i64()?)),
279 TYPE_LONG_HEX => Ok(AttributeValue::LongHex(self.read_i64()? as u64)),
280 TYPE_FLOAT => Ok(AttributeValue::Float(self.read_f32()?)),
281 TYPE_DOUBLE => Ok(AttributeValue::Double(self.read_f64()?)),
282 TYPE_BOOLEAN_TRUE => Ok(AttributeValue::Boolean(true)),
283 TYPE_BOOLEAN_FALSE => Ok(AttributeValue::Boolean(false)),
284 other => Err(AbxError::UnknownAttributeType(other)),
285 }
286 }
287
288 fn peek_u8(&mut self) -> Result<Option<u8>> {
294 self.ensure(1)?;
295 Ok(self.buf.get(self.pos).copied())
296 }
297
298 pub fn next_event(&mut self) -> Result<Option<Event>> {
304 self.ensure(1)?;
306 if self.available() == 0 {
307 return Ok(None);
308 }
309
310 let token = self.read_u8()?;
311 let cmd = token & 0x0F;
312 let type_nibble = token & 0xF0;
313
314 let event = match cmd {
315 CMD_START_DOCUMENT => Event::StartDocument,
316 CMD_END_DOCUMENT => return Ok(Some(Event::EndDocument)),
317
318 CMD_START_TAG => {
319 let name = self.read_interned()?;
320 let mut attributes = Vec::with_capacity(4);
321
322 loop {
325 match self.peek_u8()? {
326 Some(next) if (next & 0x0F) == CMD_ATTRIBUTE => {
327 self.pos += 1; let attr_type = next & 0xF0;
329 let attr_name = self.read_interned()?;
330 let attr_value = self.read_attr_value(attr_type)?;
331 attributes.push(Attribute {
332 name: attr_name,
333 value: attr_value,
334 });
335 }
336 _ => break,
337 }
338 }
339
340 Event::StartTag { name, attributes }
341 }
342
343 CMD_END_TAG => Event::EndTag {
344 name: self.read_interned()?,
345 },
346
347 CMD_TEXT => Event::Text(if type_nibble == TYPE_STRING {
348 self.read_utf()?
349 } else {
350 String::new()
351 }),
352 CMD_CDSECT => Event::CdataSection(if type_nibble == TYPE_STRING {
353 self.read_utf()?
354 } else {
355 String::new()
356 }),
357 CMD_ENTITY_REF => Event::EntityReference(if type_nibble == TYPE_STRING {
358 self.read_utf()?
359 } else {
360 String::new()
361 }),
362 CMD_IGNORABLE_WHITESPACE => Event::IgnorableWhitespace(if type_nibble == TYPE_STRING {
363 self.read_utf()?
364 } else {
365 String::new()
366 }),
367 CMD_PROCESSING_INSTRUCTION => {
368 Event::ProcessingInstruction(if type_nibble == TYPE_STRING {
369 self.read_utf()?
370 } else {
371 String::new()
372 })
373 }
374 CMD_COMMENT => Event::Comment(if type_nibble == TYPE_STRING {
375 self.read_utf()?
376 } else {
377 String::new()
378 }),
379 CMD_DOCDECL => Event::DocDecl(if type_nibble == TYPE_STRING {
380 self.read_utf()?
381 } else {
382 String::new()
383 }),
384
385 other => return Err(AbxError::UnknownCommand(other)),
386 };
387
388 Ok(Some(event))
389 }
390
391 pub fn collect_events(&mut self) -> Result<Vec<Event>> {
397 let mut out = Vec::new();
398 while let Some(ev) = self.next_event()? {
399 out.push(ev);
400 }
401 Ok(out)
402 }
403
404 pub fn find_attribute(&mut self, element: &str, attr: &str) -> Result<Option<AttributeValue>> {
410 loop {
411 match self.next_event()? {
412 Some(Event::StartTag { name, attributes }) if name == element => {
413 if let Some(a) = attributes.into_iter().find(|a| a.name == attr) {
414 return Ok(Some(a.value));
415 }
416 }
417 Some(Event::EndDocument) | None => return Ok(None),
418 _ => {}
419 }
420 }
421 }
422
423 pub fn find_all_attributes(
425 &mut self,
426 element: &str,
427 attr: &str,
428 ) -> Result<Vec<AttributeValue>> {
429 let mut out = Vec::new();
430 while let Some(ev) = self.next_event()? {
431 if let Event::StartTag { name, attributes } = ev
432 && name == element
433 {
434 out.extend(
435 attributes
436 .into_iter()
437 .filter(|a| a.name == attr)
438 .map(|a| a.value),
439 );
440 }
441 }
442 Ok(out)
443 }
444
445 pub fn attributes_of(&mut self, element: &str) -> Result<Option<Vec<Attribute>>> {
451 loop {
452 match self.next_event()? {
453 Some(Event::StartTag { name, attributes }) if name == element => {
454 return Ok(Some(attributes));
455 }
456 Some(Event::EndDocument) | None => return Ok(None),
457 _ => {}
458 }
459 }
460 }
461
462 pub fn all_attributes_of(&mut self, element: &str) -> Result<Vec<Vec<Attribute>>> {
464 let mut out = Vec::new();
465 while let Some(ev) = self.next_event()? {
466 if let Event::StartTag { name, attributes } = ev
467 && name == element
468 {
469 out.push(attributes);
470 }
471 }
472 Ok(out)
473 }
474
475 #[cfg(feature = "serialize")]
479 pub fn deserialize_next<T: serde::de::DeserializeOwned>(
480 &mut self,
481 element: &str,
482 ) -> Result<Option<T>> {
483 crate::de::find_and_consume_element(self, element)
484 }
485
486 #[cfg(feature = "serialize")]
488 pub fn deserialize_all<T: serde::de::DeserializeOwned>(
489 &mut self,
490 element: &str,
491 ) -> Result<Vec<T>> {
492 let mut out = Vec::new();
493 while let Some(item) = self.deserialize_next(element)? {
494 out.push(item);
495 }
496 Ok(out)
497 }
498
499 #[cfg(feature = "serialize")]
503 pub fn deserialize_iter<'p, T: serde::de::DeserializeOwned>(
504 &'p mut self,
505 element: &'p str,
506 ) -> DeserializeIter<'p, R, T> {
507 DeserializeIter {
508 parser: self,
509 element,
510 _marker: std::marker::PhantomData,
511 }
512 }
513
514 pub fn to_xml(&mut self) -> Result<String> {
516 let mut buf = String::from(r#"<?xml version="1.0" encoding="UTF-8"?>"#);
517 while let Some(ev) = self.next_event()? {
518 if matches!(ev, Event::EndDocument) {
519 break;
520 }
521 render_event(&ev, &mut buf);
522 }
523 Ok(buf)
524 }
525
526 pub fn write_xml(&mut self, writer: &mut impl std::io::Write) -> Result<()> {
531 writer.write_all(b"<?xml version=\"1.0\" encoding=\"UTF-8\"?>")?;
532 let mut tmp = String::new();
535 while let Some(ev) = self.next_event()? {
536 if matches!(ev, Event::EndDocument) {
537 break;
538 }
539 tmp.clear();
540 render_event(&ev, &mut tmp);
541 writer.write_all(tmp.as_bytes())?;
542 }
543 Ok(())
544 }
545
546 pub fn into_map(mut self) -> Result<HashMap<String, Vec<HashMap<String, String>>>> {
548 let mut map: HashMap<String, Vec<HashMap<String, String>>> = HashMap::new();
549 while let Some(ev) = self.next_event()? {
550 if let Event::StartTag { name, attributes } = ev {
551 let entry = map.entry(name.into()).or_default();
552 let mut attrs = HashMap::new();
553 for attr in attributes {
554 attrs.insert(attr.name.into(), attr.value.as_str().into_owned());
555 }
556 entry.push(attrs);
557 }
558 }
559 Ok(map)
560 }
561
562 pub fn into_inner(self) -> R {
564 self.reader
565 }
566}
567
568impl<R: Read> Iterator for AbxStreamParser<R> {
569 type Item = Result<Event>;
570
571 fn next(&mut self) -> Option<Self::Item> {
572 match self.next_event() {
573 Ok(Some(ev)) => Some(Ok(ev)),
574 Ok(None) => None,
575 Err(e) => Some(Err(e)),
576 }
577 }
578}
579
580#[cfg(feature = "serialize")]
583pub struct DeserializeIter<'p, R: Read, T> {
584 parser: &'p mut AbxStreamParser<R>,
585 element: &'p str,
586 _marker: std::marker::PhantomData<T>,
587}
588
589#[cfg(feature = "serialize")]
590impl<'p, R: Read, T: serde::de::DeserializeOwned> Iterator for DeserializeIter<'p, R, T> {
591 type Item = Result<T>;
592
593 fn next(&mut self) -> Option<Self::Item> {
594 self.parser.deserialize_next(self.element).transpose()
595 }
596}