mirror of
https://github.com/mbilker/kbinxml-rs.git
synced 2026-04-25 07:27:01 -05:00
commit
7f0e5d0152
|
|
@ -10,9 +10,9 @@ edition = "2018"
|
|||
byteorder = "1.3.2"
|
||||
bytes = "1.0.1"
|
||||
encoding_rs = "0.8.6"
|
||||
indexmap = "1.0.1"
|
||||
indexmap = "2.0.0"
|
||||
lazy_static = "1.0.0"
|
||||
log = "0.4.6"
|
||||
quick-xml = "0.22.0"
|
||||
quick-xml = "0.29.0"
|
||||
rustc-hex = "2.0.1"
|
||||
snafu = "0.7.0"
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
use std::borrow::Cow;
|
||||
use std::num::ParseIntError;
|
||||
use std::str::{self, Utf8Error};
|
||||
|
||||
use bytes::{BufMut, Bytes, BytesMut};
|
||||
use quick_xml::events::attributes::Attributes;
|
||||
use quick_xml::events::{BytesStart, BytesText, Event};
|
||||
use quick_xml::name::QName;
|
||||
use quick_xml::Error as QuickXmlError;
|
||||
use quick_xml::Reader;
|
||||
use snafu::{ResultExt, Snafu};
|
||||
|
|
@ -137,32 +139,28 @@ impl<'a> TextXmlReader<'a> {
|
|||
for attr in attrs {
|
||||
match attr {
|
||||
Ok(attr) => {
|
||||
let value = match attr.unescaped_value() {
|
||||
let value = match attr.unescape_value() {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
error!("Error decoding attribute value: {:?}", e);
|
||||
attr.value.clone()
|
||||
Cow::Borrowed(str::from_utf8(&attr.value)?)
|
||||
},
|
||||
};
|
||||
|
||||
if attr.key == b"__type" {
|
||||
let value = str::from_utf8(&*value)?;
|
||||
|
||||
if attr.key == QName(b"__type") {
|
||||
node_type =
|
||||
Some(StandardType::from_name(value).context(InvalidKbinTypeSnafu)?);
|
||||
} else if attr.key == b"__count" {
|
||||
let value = str::from_utf8(&*value)?;
|
||||
Some(StandardType::from_name(&value).context(InvalidKbinTypeSnafu)?);
|
||||
} else if attr.key == QName(b"__count") {
|
||||
let num_count = value.parse::<u32>().context(ParseArrayCountSnafu)?;
|
||||
|
||||
count = num_count as usize;
|
||||
} else if attr.key == b"__size" {
|
||||
let value = str::from_utf8(&*value)?
|
||||
.parse::<usize>()
|
||||
.context(ParseBinarySizeSnafu)?;
|
||||
} else if attr.key == QName(b"__size") {
|
||||
let value = value.parse::<usize>().context(ParseBinarySizeSnafu)?;
|
||||
|
||||
size = Some(value);
|
||||
} else {
|
||||
let definition = self.parse_attribute(attr.key, &value)?;
|
||||
let definition =
|
||||
self.parse_attribute(attr.key.into_inner(), &value.as_bytes())?;
|
||||
attributes.push(definition);
|
||||
}
|
||||
},
|
||||
|
|
@ -199,7 +197,7 @@ impl<'a> TextXmlReader<'a> {
|
|||
let data = NodeData::Some {
|
||||
key: Key::Uncompressed {
|
||||
encoding: self.encoding,
|
||||
data: Bytes::from(e.name().to_vec()),
|
||||
data: Bytes::from(e.name().0.to_owned()),
|
||||
},
|
||||
value_data,
|
||||
};
|
||||
|
|
@ -216,7 +214,7 @@ impl<'a> TextXmlReader<'a> {
|
|||
count: usize,
|
||||
size: Option<usize>,
|
||||
) -> Result<(), TextReaderError> {
|
||||
let data = event.unescaped()?;
|
||||
let data = event.unescape()?;
|
||||
let data = match definition.node_type {
|
||||
StandardType::String | StandardType::NodeStart => {
|
||||
let mut data = BytesMut::from(&*data);
|
||||
|
|
@ -228,8 +226,7 @@ impl<'a> TextXmlReader<'a> {
|
|||
data.freeze()
|
||||
},
|
||||
node_type => {
|
||||
let text = str::from_utf8(&*data)?;
|
||||
let value = Value::from_string(node_type, text, definition.is_array, count)
|
||||
let value = Value::from_string(node_type, &data, definition.is_array, count)
|
||||
.context(ValueDecodeSnafu { node_type })?;
|
||||
|
||||
// The read number of bytes must match the size attribute, if set
|
||||
|
|
@ -268,12 +265,8 @@ impl<'a> TextXmlReader<'a> {
|
|||
}
|
||||
|
||||
pub fn as_node_collection(&mut self) -> Result<Option<NodeCollection>, TextReaderError> {
|
||||
// A buffer size for reading a `quick_xml::events::Event` that I pulled
|
||||
// out of my head.
|
||||
let mut buf = Vec::with_capacity(1024);
|
||||
|
||||
loop {
|
||||
match self.xml_reader.read_event(&mut buf)? {
|
||||
match self.xml_reader.read_event()? {
|
||||
Event::Start(e) => {
|
||||
let start = self.handle_start(e)?;
|
||||
self.stack.push(start);
|
||||
|
|
@ -316,8 +309,6 @@ impl<'a> TextXmlReader<'a> {
|
|||
Event::Eof => break,
|
||||
_ => {},
|
||||
};
|
||||
|
||||
buf.clear();
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ impl TextXmlWriter {
|
|||
T: ToTextXml,
|
||||
{
|
||||
if let Some(encoding) = value.encoding().name() {
|
||||
let header = BytesDecl::new(b"1.0", Some(encoding.as_bytes()), None);
|
||||
let header = BytesDecl::new("1.0", Some(encoding), None);
|
||||
|
||||
self.xml_writer.write_event(Event::Decl(header))?;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ use std::io::Write;
|
|||
|
||||
use quick_xml::events::attributes::Attribute;
|
||||
use quick_xml::events::{BytesEnd, BytesStart, BytesText, Event};
|
||||
use quick_xml::name::QName;
|
||||
use quick_xml::Writer;
|
||||
|
||||
use crate::encoding_type::EncodingType;
|
||||
|
|
@ -20,7 +21,7 @@ impl ToTextXml for Node {
|
|||
|
||||
fn write<W: Write>(&self, writer: &mut Writer<W>) -> Result<(), KbinError> {
|
||||
let key = self.key();
|
||||
let mut elem = BytesStart::borrowed(key.as_bytes(), key.as_bytes().len());
|
||||
let mut elem = BytesStart::new(key);
|
||||
|
||||
// Write the attributes for the value, but not the value contents.
|
||||
if let Some(value) = self.value() {
|
||||
|
|
@ -29,13 +30,13 @@ impl ToTextXml for Node {
|
|||
match value {
|
||||
Value::Binary(ref data) => {
|
||||
elem.push_attribute(Attribute {
|
||||
key: b"__size",
|
||||
key: QName(b"__size"),
|
||||
value: Cow::Owned(data.len().to_string().into_bytes()),
|
||||
});
|
||||
},
|
||||
Value::Array(ref values) => {
|
||||
elem.push_attribute(Attribute {
|
||||
key: b"__count",
|
||||
key: QName(b"__count"),
|
||||
value: Cow::Owned(values.len().to_string().into_bytes()),
|
||||
});
|
||||
},
|
||||
|
|
@ -45,18 +46,18 @@ impl ToTextXml for Node {
|
|||
// Only add a `__type` attribute if this is not a `NodeStart` node
|
||||
if node_type != StandardType::NodeStart {
|
||||
elem.push_attribute(Attribute {
|
||||
key: b"__type",
|
||||
key: QName(b"__type"),
|
||||
value: Cow::Borrowed(node_type.name.as_bytes()),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
for (key, value) in self.attributes() {
|
||||
let value = BytesText::from_plain_str(value);
|
||||
// let value = BytesText::new(value);
|
||||
|
||||
elem.push_attribute(Attribute {
|
||||
key: key.as_bytes(),
|
||||
value: Cow::Borrowed(value.escaped()),
|
||||
key: QName(key.as_bytes()),
|
||||
value: Cow::Borrowed(value.as_bytes()),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -65,7 +66,7 @@ impl ToTextXml for Node {
|
|||
writer.write_event(Event::Start(elem))?;
|
||||
|
||||
let value = value.to_string();
|
||||
let elem = BytesText::from_plain_str(&value);
|
||||
let elem = BytesText::new(&value);
|
||||
writer.write_event(Event::Text(elem))?;
|
||||
|
||||
None
|
||||
|
|
@ -90,7 +91,7 @@ impl ToTextXml for Node {
|
|||
}
|
||||
|
||||
if has_value || has_children {
|
||||
let end_elem = BytesEnd::borrowed(key.as_bytes());
|
||||
let end_elem = BytesEnd::new(key);
|
||||
writer.write_event(Event::End(end_elem))?;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ use std::io::Write;
|
|||
|
||||
use quick_xml::events::attributes::Attribute;
|
||||
use quick_xml::events::{BytesEnd, BytesStart, BytesText, Event};
|
||||
use quick_xml::name::QName;
|
||||
use quick_xml::Writer;
|
||||
|
||||
use crate::encoding_type::EncodingType;
|
||||
|
|
@ -29,13 +30,13 @@ impl ToTextXml for NodeCollection {
|
|||
},
|
||||
};
|
||||
|
||||
let mut elem = BytesStart::borrowed(key.as_bytes(), key.as_bytes().len());
|
||||
let mut elem = BytesStart::new(key.clone());
|
||||
|
||||
if base.is_array {
|
||||
let values = value.as_ref().ok_or(KbinError::InvalidState)?.as_array()?;
|
||||
|
||||
elem.push_attribute(Attribute {
|
||||
key: b"__count",
|
||||
key: QName(b"__count"),
|
||||
value: Cow::Owned(values.len().to_string().into_bytes()),
|
||||
});
|
||||
}
|
||||
|
|
@ -44,7 +45,7 @@ impl ToTextXml for NodeCollection {
|
|||
let value = value.as_ref().ok_or(KbinError::InvalidState)?.as_slice()?;
|
||||
|
||||
elem.push_attribute(Attribute {
|
||||
key: b"__size",
|
||||
key: QName(b"__size"),
|
||||
value: Cow::Owned(value.len().to_string().into_bytes()),
|
||||
});
|
||||
}
|
||||
|
|
@ -52,7 +53,7 @@ impl ToTextXml for NodeCollection {
|
|||
// Only add a `__type` attribute if this is not a `NodeStart` node
|
||||
if base.node_type != StandardType::NodeStart {
|
||||
elem.push_attribute(Attribute {
|
||||
key: b"__type",
|
||||
key: QName(b"__type"),
|
||||
value: Cow::Borrowed(base.node_type.name.as_bytes()),
|
||||
});
|
||||
}
|
||||
|
|
@ -63,11 +64,10 @@ impl ToTextXml for NodeCollection {
|
|||
.ok_or(KbinError::InvalidState)?
|
||||
.into_bytes();
|
||||
let value = attribute.value()?.to_string();
|
||||
let value = BytesText::from_plain_str(&value);
|
||||
|
||||
elem.push_attribute(Attribute {
|
||||
key: &key,
|
||||
value: Cow::Borrowed(value.escaped()),
|
||||
key: QName(&key),
|
||||
value: Cow::Borrowed(value.as_bytes()),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -76,7 +76,7 @@ impl ToTextXml for NodeCollection {
|
|||
writer.write_event(Event::Start(elem))?;
|
||||
|
||||
let value = value.to_string();
|
||||
let elem = BytesText::from_plain_str(&value);
|
||||
let elem = BytesText::new(&value);
|
||||
writer.write_event(Event::Text(elem))?;
|
||||
|
||||
None
|
||||
|
|
@ -101,7 +101,7 @@ impl ToTextXml for NodeCollection {
|
|||
}
|
||||
|
||||
if has_value || has_children {
|
||||
let end_elem = BytesEnd::borrowed(key.as_bytes());
|
||||
let end_elem = BytesEnd::new(key);
|
||||
writer.write_event(Event::End(end_elem))?;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user