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.pos > 0 {
134 self.buf.copy_within(self.pos..self.len, 0);
135 self.len -= self.pos;
136 self.pos = 0;
137 }
138
139 while self.available() < needed && !self.eof {
140 let spare = self.buf.len() - self.len;
142 if spare < READ_CHUNK {
143 self.buf
144 .resize(self.len + READ_CHUNK.max(needed - self.available()), 0);
145 }
146
147 let n = self.reader.read(&mut self.buf[self.len..])?;
148 if n == 0 {
149 self.eof = true;
150 } else {
151 self.len += n;
152 }
153 }
154
155 Ok(())
156 }
157
158 fn parse<F, T>(&mut self, mut f: F) -> Result<T>
165 where
166 F: FnMut(&[u8]) -> nom::IResult<&[u8], T>,
167 {
168 loop {
169 match f(&self.buf[self.pos..self.len]) {
170 Ok((rest, val)) => {
171 self.pos = self.len - rest.len();
172 return Ok(val);
173 }
174 Err(nom::Err::Incomplete(Needed::Size(n))) => {
175 let need = self.available() + n.get();
176 self.ensure(need)?;
177 if self.eof && self.available() < n.get() {
178 return Err(AbxError::UnexpectedEof("primitive"));
179 }
180 }
181 Err(nom::Err::Incomplete(Needed::Unknown)) => {
182 self.ensure(self.available() + 1)?;
184 if self.eof {
185 return Err(AbxError::UnexpectedEof("primitive"));
186 }
187 }
188 Err(e) => return Err(AbxError::Nom(format!("{e:?}"))),
189 }
190 }
191 }
192
193 fn read_u8(&mut self) -> Result<u8> {
194 self.parse(|i| be_u8(i))
195 }
196 fn read_u16(&mut self) -> Result<u16> {
197 self.parse(|i| be_u16(i))
198 }
199 fn read_i32(&mut self) -> Result<i32> {
200 self.parse(|i| be_i32(i))
201 }
202 fn read_i64(&mut self) -> Result<i64> {
203 self.parse(|i| be_i64(i))
204 }
205 fn read_f32(&mut self) -> Result<f32> {
206 self.parse(|i| be_f32(i))
207 }
208 fn read_f64(&mut self) -> Result<f64> {
209 self.parse(|i| be_f64(i))
210 }
211
212 fn read_utf(&mut self) -> Result<String> {
214 let len = self.read_u16()? as usize;
215 self.ensure(len)?;
217 if self.available() < len {
218 return Err(AbxError::UnexpectedEof("UTF string payload"));
219 }
220 let s = std::str::from_utf8(&self.buf[self.pos..self.pos + len])
221 .map_err(|_| AbxError::InvalidUtf8)?
222 .to_owned();
223 self.pos += len;
224 Ok(s)
225 }
226
227 fn read_bytes_blob(&mut self) -> Result<Vec<u8>> {
229 let len = self.read_u16()? as usize;
230 self.ensure(len)?;
231 if self.available() < len {
232 return Err(AbxError::UnexpectedEof("bytes payload"));
233 }
234 let v = self.buf[self.pos..self.pos + len].to_vec();
235 self.pos += len;
236 Ok(v)
237 }
238
239 fn read_interned(&mut self) -> Result<crate::InternedStr> {
243 let idx = self.read_u16()?;
244 if idx == INTERNED_NEW {
245 let s: crate::InternedStr = self.read_utf()?.into();
246 self.pool.push(s.clone());
247 Ok(s)
248 } else {
249 self.pool
250 .get(idx as usize)
251 .cloned()
252 .ok_or(AbxError::BadInternedIndex(idx))
253 }
254 }
255
256 fn read_attr_value(&mut self, type_nibble: u8) -> Result<AttributeValue> {
261 match type_nibble {
262 TYPE_NULL => Ok(AttributeValue::Null),
263 TYPE_STRING => Ok(AttributeValue::String(self.read_utf()?)),
264 TYPE_STRING_INTERNED => Ok(AttributeValue::String(self.read_interned()?.to_string())),
265 TYPE_BYTES_HEX => Ok(AttributeValue::BytesHex(self.read_bytes_blob()?)),
266 TYPE_BYTES_BASE64 => Ok(AttributeValue::BytesBase64(self.read_bytes_blob()?)),
267 TYPE_INT => Ok(AttributeValue::Int(self.read_i32()?)),
268 TYPE_INT_HEX => Ok(AttributeValue::IntHex(self.read_i32()? as u32)),
269 TYPE_LONG => Ok(AttributeValue::Long(self.read_i64()?)),
270 TYPE_LONG_HEX => Ok(AttributeValue::LongHex(self.read_i64()? as u64)),
271 TYPE_FLOAT => Ok(AttributeValue::Float(self.read_f32()?)),
272 TYPE_DOUBLE => Ok(AttributeValue::Double(self.read_f64()?)),
273 TYPE_BOOLEAN_TRUE => Ok(AttributeValue::Boolean(true)),
274 TYPE_BOOLEAN_FALSE => Ok(AttributeValue::Boolean(false)),
275 other => Err(AbxError::UnknownAttributeType(other)),
276 }
277 }
278
279 fn peek_u8(&mut self) -> Result<Option<u8>> {
285 self.ensure(1)?;
286 Ok(self.buf.get(self.pos).copied())
287 }
288
289 pub fn next_event(&mut self) -> Result<Option<Event>> {
295 self.ensure(1)?;
297 if self.available() == 0 {
298 return Ok(None);
299 }
300
301 let token = self.read_u8()?;
302 let cmd = token & 0x0F;
303 let type_nibble = token & 0xF0;
304
305 let event = match cmd {
306 CMD_START_DOCUMENT => Event::StartDocument,
307 CMD_END_DOCUMENT => return Ok(Some(Event::EndDocument)),
308
309 CMD_START_TAG => {
310 let name = self.read_interned()?;
311 let mut attributes = Vec::new();
312
313 loop {
316 match self.peek_u8()? {
317 Some(next) if (next & 0x0F) == CMD_ATTRIBUTE => {
318 self.pos += 1; let attr_type = next & 0xF0;
320 let attr_name = self.read_interned()?;
321 let attr_value = self.read_attr_value(attr_type)?;
322 attributes.push(Attribute {
323 name: attr_name,
324 value: attr_value,
325 });
326 }
327 _ => break,
328 }
329 }
330
331 Event::StartTag { name, attributes }
332 }
333
334 CMD_END_TAG => Event::EndTag {
335 name: self.read_interned()?,
336 },
337
338 CMD_TEXT => Event::Text(if type_nibble == TYPE_STRING {
339 self.read_utf()?
340 } else {
341 String::new()
342 }),
343 CMD_CDSECT => Event::CdataSection(if type_nibble == TYPE_STRING {
344 self.read_utf()?
345 } else {
346 String::new()
347 }),
348 CMD_ENTITY_REF => Event::EntityReference(if type_nibble == TYPE_STRING {
349 self.read_utf()?
350 } else {
351 String::new()
352 }),
353 CMD_IGNORABLE_WHITESPACE => Event::IgnorableWhitespace(if type_nibble == TYPE_STRING {
354 self.read_utf()?
355 } else {
356 String::new()
357 }),
358 CMD_PROCESSING_INSTRUCTION => {
359 Event::ProcessingInstruction(if type_nibble == TYPE_STRING {
360 self.read_utf()?
361 } else {
362 String::new()
363 })
364 }
365 CMD_COMMENT => Event::Comment(if type_nibble == TYPE_STRING {
366 self.read_utf()?
367 } else {
368 String::new()
369 }),
370 CMD_DOCDECL => Event::DocDecl(if type_nibble == TYPE_STRING {
371 self.read_utf()?
372 } else {
373 String::new()
374 }),
375
376 other => return Err(AbxError::UnknownCommand(other)),
377 };
378
379 Ok(Some(event))
380 }
381
382 pub fn collect_events(&mut self) -> Result<Vec<Event>> {
388 let mut out = Vec::new();
389 while let Some(ev) = self.next_event()? {
390 out.push(ev);
391 }
392 Ok(out)
393 }
394
395 pub fn find_attribute(&mut self, element: &str, attr: &str) -> Option<AttributeValue> {
397 loop {
398 match self.next_event().ok()? {
399 Some(Event::StartTag { name, attributes }) if name == element => {
400 if let Some(a) = attributes.into_iter().find(|a| a.name == attr) {
401 return Some(a.value);
402 }
403 }
404 Some(Event::EndDocument) | None => return None,
405 _ => {}
406 }
407 }
408 }
409
410 pub fn find_all_attributes(
412 &mut self,
413 element: &str,
414 attr: &str,
415 ) -> Result<Vec<AttributeValue>> {
416 let mut out = Vec::new();
417 while let Some(ev) = self.next_event()? {
418 if let Event::StartTag { name, attributes } = ev
419 && name == element
420 {
421 out.extend(
422 attributes
423 .into_iter()
424 .filter(|a| a.name == attr)
425 .map(|a| a.value),
426 );
427 }
428 }
429 Ok(out)
430 }
431
432 pub fn attributes_of(&mut self, element: &str) -> Option<Vec<Attribute>> {
434 loop {
435 match self.next_event().ok()? {
436 Some(Event::StartTag { name, attributes }) if name == element => {
437 return Some(attributes);
438 }
439 Some(Event::EndDocument) | None => return None,
440 _ => {}
441 }
442 }
443 }
444
445 pub fn all_attributes_of(&mut self, element: &str) -> Result<Vec<Vec<Attribute>>> {
447 let mut out = Vec::new();
448 while let Some(ev) = self.next_event()? {
449 if let Event::StartTag { name, attributes } = ev
450 && name == element
451 {
452 out.push(attributes);
453 }
454 }
455 Ok(out)
456 }
457
458 #[cfg(feature = "serialize")]
462 pub fn deserialize_next<T: serde::de::DeserializeOwned>(
463 &mut self,
464 element: &str,
465 ) -> Result<Option<T>> {
466 crate::de::find_and_consume_element(self, element)
467 }
468
469 #[cfg(feature = "serialize")]
471 pub fn deserialize_all<T: serde::de::DeserializeOwned>(
472 &mut self,
473 element: &str,
474 ) -> Result<Vec<T>> {
475 let mut out = Vec::new();
476 while let Some(item) = self.deserialize_next(element)? {
477 out.push(item);
478 }
479 Ok(out)
480 }
481
482 #[cfg(feature = "serialize")]
486 pub fn deserialize_iter<'p, T: serde::de::DeserializeOwned>(
487 &'p mut self,
488 element: &'p str,
489 ) -> DeserializeIter<'p, R, T> {
490 DeserializeIter {
491 parser: self,
492 element,
493 _marker: std::marker::PhantomData,
494 }
495 }
496
497 pub fn to_xml(&mut self) -> Result<String> {
499 let mut buf = String::from(r#"<?xml version="1.0" encoding="UTF-8"?>"#);
500 while let Some(ev) = self.next_event()? {
501 if matches!(ev, Event::EndDocument) {
502 break;
503 }
504 render_event(&ev, &mut buf);
505 }
506 Ok(buf)
507 }
508
509 pub fn write_xml(&mut self, writer: &mut impl std::io::Write) -> Result<()> {
514 writer.write_all(b"<?xml version=\"1.0\" encoding=\"UTF-8\"?>")?;
515 let mut tmp = String::new();
518 while let Some(ev) = self.next_event()? {
519 if matches!(ev, Event::EndDocument) {
520 break;
521 }
522 tmp.clear();
523 render_event(&ev, &mut tmp);
524 writer.write_all(tmp.as_bytes())?;
525 }
526 Ok(())
527 }
528
529 pub fn into_map(mut self) -> Result<HashMap<String, Vec<HashMap<String, String>>>> {
531 let mut map: HashMap<String, Vec<HashMap<String, String>>> = HashMap::new();
532 while let Some(ev) = self.next_event()? {
533 if let Event::StartTag { name, attributes } = ev {
534 let entry = map.entry(name.into()).or_default();
535 let mut attrs = HashMap::new();
536 for attr in attributes {
537 attrs.insert(attr.name.into(), attr.value.as_str().into_owned());
538 }
539 entry.push(attrs);
540 }
541 }
542 Ok(map)
543 }
544
545 pub fn into_inner(self) -> R {
547 self.reader
548 }
549}
550
551impl<R: Read> Iterator for AbxStreamParser<R> {
552 type Item = Result<Event>;
553
554 fn next(&mut self) -> Option<Self::Item> {
555 match self.next_event() {
556 Ok(Some(ev)) => Some(Ok(ev)),
557 Ok(None) => None,
558 Err(e) => Some(Err(e)),
559 }
560 }
561}
562
563#[cfg(feature = "serialize")]
566pub struct DeserializeIter<'p, R: Read, T> {
567 parser: &'p mut AbxStreamParser<R>,
568 element: &'p str,
569 _marker: std::marker::PhantomData<T>,
570}
571
572#[cfg(feature = "serialize")]
573impl<'p, R: Read, T: serde::de::DeserializeOwned> Iterator for DeserializeIter<'p, R, T> {
574 type Item = Result<T>;
575
576 fn next(&mut self) -> Option<Self::Item> {
577 self.parser.deserialize_next(self.element).transpose()
578 }
579}