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