1use std::collections::HashMap;
9
10use nom::{
11 IResult, Parser,
12 bytes::complete::take,
13 number::complete::{be_f32, be_f64, be_i32, be_i64, be_u8, be_u16},
14};
15
16use crate::{
17 AbxError, Attribute, AttributeValue, CMD_ATTRIBUTE, CMD_CDSECT, CMD_COMMENT, CMD_DOCDECL,
18 CMD_END_DOCUMENT, CMD_END_TAG, CMD_ENTITY_REF, CMD_IGNORABLE_WHITESPACE,
19 CMD_PROCESSING_INSTRUCTION, CMD_START_DOCUMENT, CMD_START_TAG, CMD_TEXT, Event, MAGIC, Result,
20 TYPE_BOOLEAN_FALSE, TYPE_BOOLEAN_TRUE, TYPE_BYTES_BASE64, TYPE_BYTES_HEX, TYPE_DOUBLE,
21 TYPE_FLOAT, TYPE_INT, TYPE_INT_HEX, TYPE_LONG, TYPE_LONG_HEX, TYPE_NULL, TYPE_STRING,
22 TYPE_STRING_INTERNED, render_event,
23};
24
25use crate::INTERNED_NEW;
26use crate::InternedStr;
27
28fn parse_utf_string(input: &[u8]) -> IResult<&[u8], String> {
29 let (input, len) = be_u16(input)?;
30 let (input, bytes) = take(len).parse(input)?;
31 let s = std::str::from_utf8(bytes)
32 .map_err(|_| {
33 nom::Err::Failure(nom::error::Error::new(input, nom::error::ErrorKind::Verify))
34 })?
35 .to_owned();
36 Ok((input, s))
37}
38
39fn parse_bytes_blob(input: &[u8]) -> IResult<&[u8], Vec<u8>> {
40 let (input, len) = be_u16(input)?;
41 let (input, bytes) = take(len).parse(input)?;
42 Ok((input, bytes.to_vec()))
43}
44
45#[derive(Debug)]
50pub struct AbxParser<'a> {
51 rest: &'a [u8],
52 pool: Vec<InternedStr>,
53}
54
55impl<'a> AbxParser<'a> {
56 pub fn new(input: &'a [u8]) -> Result<Self> {
58 if input.len() < 4 {
59 return Err(AbxError::UnexpectedEof("magic header"));
60 }
61 let magic: [u8; 4] = input[..4].try_into().unwrap();
62 if magic != MAGIC {
63 return Err(AbxError::InvalidMagic {
64 expected: MAGIC,
65 actual: magic,
66 });
67 }
68 Ok(AbxParser {
69 rest: &input[4..],
70 pool: Vec::with_capacity(32),
71 })
72 }
73
74 pub fn is_empty(&self) -> bool {
76 self.rest.is_empty()
77 }
78
79 fn run<F, T>(&mut self, f: F) -> Result<T>
82 where
83 F: Fn(&'a [u8]) -> IResult<&'a [u8], T>,
84 {
85 let (rest, val) = f(self.rest).map_err(|e| AbxError::Nom(format!("{e:?}")))?;
86 self.rest = rest;
87 Ok(val)
88 }
89
90 fn read_u8(&mut self) -> Result<u8> {
91 self.run(be_u8)
92 }
93 fn read_u16(&mut self) -> Result<u16> {
94 self.run(be_u16)
95 }
96 fn read_i32(&mut self) -> Result<i32> {
97 self.run(be_i32)
98 }
99 fn read_i64(&mut self) -> Result<i64> {
100 self.run(be_i64)
101 }
102 fn read_f32(&mut self) -> Result<f32> {
103 self.run(be_f32)
104 }
105 fn read_f64(&mut self) -> Result<f64> {
106 self.run(be_f64)
107 }
108
109 fn read_utf(&mut self) -> Result<String> {
110 self.run(parse_utf_string)
111 }
112 fn read_bytes_blob(&mut self) -> Result<Vec<u8>> {
113 self.run(parse_bytes_blob)
114 }
115
116 fn read_interned(&mut self) -> Result<InternedStr> {
120 let idx = self.read_u16()?;
121 if idx == INTERNED_NEW {
122 let s: InternedStr = self.read_utf()?.into();
123 self.pool.push(s.clone());
124 Ok(s)
125 } else {
126 self.pool
127 .get(idx as usize)
128 .cloned()
129 .ok_or(AbxError::BadInternedIndex(idx))
130 }
131 }
132
133 fn read_attr_value(&mut self, type_nibble: u8) -> Result<AttributeValue> {
134 match type_nibble {
135 TYPE_NULL => Ok(AttributeValue::Null),
136 TYPE_STRING => Ok(AttributeValue::String(self.read_utf()?)),
137 TYPE_STRING_INTERNED => Ok(AttributeValue::String(String::from(self.read_interned()?))),
138 TYPE_BYTES_HEX => Ok(AttributeValue::BytesHex(self.read_bytes_blob()?)),
139 TYPE_BYTES_BASE64 => Ok(AttributeValue::BytesBase64(self.read_bytes_blob()?)),
140 TYPE_INT => Ok(AttributeValue::Int(self.read_i32()?)),
141 TYPE_INT_HEX => Ok(AttributeValue::IntHex(self.read_i32()? as u32)),
142 TYPE_LONG => Ok(AttributeValue::Long(self.read_i64()?)),
143 TYPE_LONG_HEX => Ok(AttributeValue::LongHex(self.read_i64()? as u64)),
144 TYPE_FLOAT => Ok(AttributeValue::Float(self.read_f32()?)),
145 TYPE_DOUBLE => Ok(AttributeValue::Double(self.read_f64()?)),
146 TYPE_BOOLEAN_TRUE => Ok(AttributeValue::Boolean(true)),
147 TYPE_BOOLEAN_FALSE => Ok(AttributeValue::Boolean(false)),
148 other => Err(AbxError::UnknownAttributeType(other)),
149 }
150 }
151
152 pub fn next_event(&mut self) -> Result<Option<Event>> {
156 if self.rest.is_empty() {
157 return Ok(None);
158 }
159
160 let token = self.read_u8()?;
161 let cmd = token & 0x0F;
162 let type_nibble = token & 0xF0;
163
164 let event = match cmd {
165 CMD_START_DOCUMENT => Event::StartDocument,
166 CMD_END_DOCUMENT => return Ok(Some(Event::EndDocument)),
167
168 CMD_START_TAG => {
169 let name = self.read_interned()?;
170 let mut attributes = Vec::with_capacity(4);
171 loop {
172 if self.rest.is_empty() {
173 break;
174 }
175 let next = self.rest[0];
176 if (next & 0x0F) != CMD_ATTRIBUTE {
177 break;
178 }
179 self.rest = &self.rest[1..];
180 let attr_type = next & 0xF0;
181 let attr_name = self.read_interned()?;
182 let attr_value = self.read_attr_value(attr_type)?;
183 attributes.push(Attribute {
184 name: attr_name,
185 value: attr_value,
186 });
187 }
188 Event::StartTag { name, attributes }
189 }
190
191 CMD_END_TAG => Event::EndTag {
192 name: self.read_interned()?,
193 },
194
195 CMD_TEXT => Event::Text(if type_nibble == TYPE_STRING {
196 self.read_utf()?
197 } else {
198 String::new()
199 }),
200 CMD_CDSECT => Event::CdataSection(if type_nibble == TYPE_STRING {
201 self.read_utf()?
202 } else {
203 String::new()
204 }),
205 CMD_ENTITY_REF => Event::EntityReference(if type_nibble == TYPE_STRING {
206 self.read_utf()?
207 } else {
208 String::new()
209 }),
210 CMD_IGNORABLE_WHITESPACE => Event::IgnorableWhitespace(if type_nibble == TYPE_STRING {
211 self.read_utf()?
212 } else {
213 String::new()
214 }),
215 CMD_PROCESSING_INSTRUCTION => {
216 Event::ProcessingInstruction(if type_nibble == TYPE_STRING {
217 self.read_utf()?
218 } else {
219 String::new()
220 })
221 }
222 CMD_COMMENT => Event::Comment(if type_nibble == TYPE_STRING {
223 self.read_utf()?
224 } else {
225 String::new()
226 }),
227 CMD_DOCDECL => Event::DocDecl(if type_nibble == TYPE_STRING {
228 self.read_utf()?
229 } else {
230 String::new()
231 }),
232
233 other => return Err(AbxError::UnknownCommand(other)),
234 };
235
236 Ok(Some(event))
237 }
238
239 pub fn collect_events(&mut self) -> Result<Vec<Event>> {
243 let mut events = Vec::new();
244 while let Some(ev) = self.next_event()? {
245 events.push(ev);
246 }
247 Ok(events)
248 }
249
250 pub fn find_attribute(&mut self, element: &str, attr: &str) -> Result<Option<AttributeValue>> {
257 loop {
258 match self.next_event()? {
259 Some(Event::StartTag { name, attributes }) if name == element => {
260 if let Some(a) = attributes.into_iter().find(|a| a.name == attr) {
261 return Ok(Some(a.value));
262 }
263 }
264 Some(Event::EndDocument) | None => return Ok(None),
265 _ => {}
266 }
267 }
268 }
269
270 pub fn find_all_attributes(
272 &mut self,
273 element: &str,
274 attr: &str,
275 ) -> Result<Vec<AttributeValue>> {
276 let mut out = Vec::new();
277 while let Some(ev) = self.next_event()? {
278 if let Event::StartTag { name, attributes } = ev
279 && name == element
280 {
281 out.extend(
282 attributes
283 .into_iter()
284 .filter(|a| a.name == attr)
285 .map(|a| a.value),
286 );
287 }
288 }
289 Ok(out)
290 }
291
292 pub fn attributes_of(&mut self, element: &str) -> Result<Option<Vec<Attribute>>> {
298 loop {
299 match self.next_event()? {
300 Some(Event::StartTag { name, attributes }) if name == element => {
301 return Ok(Some(attributes));
302 }
303 Some(Event::EndDocument) | None => return Ok(None),
304 _ => {}
305 }
306 }
307 }
308
309 pub fn all_attributes_of(&mut self, element: &str) -> Result<Vec<Vec<Attribute>>> {
311 let mut out = Vec::new();
312 while let Some(ev) = self.next_event()? {
313 if let Event::StartTag { name, attributes } = ev
314 && name == element
315 {
316 out.push(attributes);
317 }
318 }
319 Ok(out)
320 }
321
322 pub fn to_xml(&mut self) -> Result<String> {
324 let mut buf = String::from(r#"<?xml version="1.0" encoding="UTF-8"?>"#);
325 while let Some(ev) = self.next_event()? {
326 if matches!(ev, Event::EndDocument) {
327 break;
328 }
329 render_event(&ev, &mut buf);
330 }
331 Ok(buf)
332 }
333
334 pub fn write_xml(&mut self, writer: &mut impl std::io::Write) -> Result<()> {
340 writer.write_all(b"<?xml version=\"1.0\" encoding=\"UTF-8\"?>")?;
341 let mut tmp = String::new();
344 while let Some(ev) = self.next_event()? {
345 if matches!(ev, Event::EndDocument) {
346 break;
347 }
348 tmp.clear();
349 render_event(&ev, &mut tmp);
350 writer.write_all(tmp.as_bytes())?;
351 }
352 Ok(())
353 }
354
355 #[cfg(feature = "serialize")]
359 pub fn deserialize_next<T: serde::de::DeserializeOwned>(
360 &mut self,
361 element: &str,
362 ) -> Result<Option<T>> {
363 crate::de::find_and_consume_element(self, element)
364 }
365
366 #[cfg(feature = "serialize")]
368 pub fn deserialize_all<T: serde::de::DeserializeOwned>(
369 &mut self,
370 element: &str,
371 ) -> Result<Vec<T>> {
372 let mut out = Vec::new();
373 while let Some(item) = self.deserialize_next(element)? {
374 out.push(item);
375 }
376 Ok(out)
377 }
378
379 pub fn into_map(mut self) -> Result<HashMap<String, Vec<HashMap<String, String>>>> {
381 let mut map: HashMap<String, Vec<HashMap<String, String>>> = HashMap::new();
382 while let Some(ev) = self.next_event()? {
383 if let Event::StartTag { name, attributes } = ev {
384 let entry = map.entry(name.into()).or_default();
385 let mut attrs = HashMap::new();
386 for attr in attributes {
387 attrs.insert(attr.name.into(), attr.value.as_str().into_owned());
388 }
389 entry.push(attrs);
390 }
391 }
392 Ok(map)
393 }
394}
395
396#[derive(Debug)]
404pub struct AbxParserOwned {
405 data: Vec<u8>,
406}
407
408impl AbxParserOwned {
409 pub fn new(data: Vec<u8>) -> Result<Self> {
411 if data.len() < 4 {
412 return Err(AbxError::UnexpectedEof("magic header"));
413 }
414 let magic: [u8; 4] = data[..4].try_into().unwrap();
415 if magic != MAGIC {
416 return Err(AbxError::InvalidMagic {
417 expected: MAGIC,
418 actual: magic,
419 });
420 }
421 Ok(Self { data })
422 }
423
424 pub fn parser(&self) -> Result<AbxParser<'_>> {
426 AbxParser::new(&self.data)
427 }
428}