aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml2
-rw-r--r--src/xml/reader.rs25
-rw-r--r--src/xml/writer.rs53
3 files changed, 42 insertions, 38 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 038507e..5c1ea19 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -10,6 +10,6 @@ keywords = ["plist", "parser"]
[dependencies]
rustc-serialize = "0.3.16"
-xml-rs = "0.1.26"
+xml-rs = "0.2.2"
byteorder = "0.3.13"
chrono = "0.2.16" \ No newline at end of file
diff --git a/src/xml/reader.rs b/src/xml/reader.rs
index b372e8e..abf671d 100644
--- a/src/xml/reader.rs
+++ b/src/xml/reader.rs
@@ -2,8 +2,7 @@ use chrono::{DateTime, UTC};
use rustc_serialize::base64::FromBase64;
use std::io::Read;
use std::str::FromStr;
-use xml_rs::reader::{EventReader, ParserConfig};
-use xml_rs::reader::events::XmlEvent;
+use xml_rs::reader::{EventReader, ParserConfig, XmlEvent};
use super::super::{ParserError, ParserResult, PlistEvent};
@@ -25,7 +24,7 @@ impl<R: Read> StreamingParser<R> {
};
StreamingParser {
- xml_reader: EventReader::with_config(reader, config),
+ xml_reader: EventReader::new_with_config(reader, config),
queued_event: None,
element_stack: Vec::new(),
finished: false
@@ -34,8 +33,8 @@ impl<R: Read> StreamingParser<R> {
fn read_content<F>(&mut self, f: F) -> ParserResult<PlistEvent> where F:FnOnce(String) -> ParserResult<PlistEvent> {
match self.xml_reader.next() {
- XmlEvent::Characters(s) => f(s),
- event @ XmlEvent::EndElement{..} => {
+ Ok(XmlEvent::Characters(s)) => f(s),
+ Ok(event @ XmlEvent::EndElement{..}) => {
self.queued_event = Some(event);
f("".to_owned())
},
@@ -43,18 +42,18 @@ impl<R: Read> StreamingParser<R> {
}
}
- fn next_event(&mut self) -> XmlEvent {
+ fn next_event(&mut self) -> Result<XmlEvent, ()> {
if let Some(event) = self.queued_event.take() {
- event
+ Ok(event)
} else {
- self.xml_reader.next()
+ self.xml_reader.next().map_err(|_| ())
}
}
fn read_next(&mut self) -> Option<ParserResult<PlistEvent>> {
loop {
match self.next_event() {
- XmlEvent::StartElement { name, .. } => {
+ Ok(XmlEvent::StartElement { name, .. }) => {
// Add the current element to the element stack
self.element_stack.push(name.local_name.clone());
@@ -92,7 +91,7 @@ impl<R: Read> StreamingParser<R> {
_ => return Some(Err(ParserError::InvalidData))
}
},
- XmlEvent::EndElement { name, .. } => {
+ Ok(XmlEvent::EndElement { name, .. }) => {
// Check the corrent element is being closed
match self.element_stack.pop() {
Some(ref open_name) if &name.local_name == open_name => (),
@@ -107,13 +106,13 @@ impl<R: Read> StreamingParser<R> {
_ => ()
}
},
- XmlEvent::EndDocument => {
+ Ok(XmlEvent::EndDocument) => {
match self.element_stack.is_empty() {
true => return None,
false => return Some(Err(ParserError::UnexpectedEof))
}
},
- XmlEvent::Error(_) => return Some(Err(ParserError::InvalidData)),
+ Err(_) => return Some(Err(ParserError::InvalidData)),
_ => ()
}
}
@@ -188,8 +187,6 @@ mod tests {
#[test]
fn bad_data() {
- use PlistEvent::*;
-
let reader = File::open(&Path::new("./tests/data/xml_error.plist")).unwrap();
let streaming_parser = StreamingParser::new(reader);
let events: Vec<_> = streaming_parser.collect();
diff --git a/src/xml/writer.rs b/src/xml/writer.rs
index 1b3eb5f..bd73b1e 100644
--- a/src/xml/writer.rs
+++ b/src/xml/writer.rs
@@ -1,4 +1,5 @@
use rustc_serialize::base64::{MIME, ToBase64};
+use std::borrow::Cow;
use std::io::Write;
use xml_rs::attribute::Attribute;
use xml_rs::name::Name;
@@ -29,12 +30,15 @@ pub struct Writer<W: Write> {
impl<W: Write> Writer<W> {
pub fn new(writer: W) -> Writer<W> {
let config = EmitterConfig {
- line_separator: "\n".to_owned(),
- indent_string: " ".to_owned(),
+ line_separator: "\n".into(),
+ indent_string: " ".into(),
perform_indent: true,
+ perform_escaping: true,
write_document_declaration: true,
normalize_empty_elements: true,
cdata_to_characters: true,
+ keep_element_names_stack: false,
+ autopad_comments: true
};
Writer {
@@ -54,8 +58,8 @@ impl<W: Write> Writer<W> {
fn start_element(&mut self, name: &str) -> Result<(), ()> {
let result = self.xml_writer.write(WriteXmlEvent::StartElement {
name: Name::local(name),
- attributes: Vec::new(),
- namespace: &self.empty_namespace
+ attributes: Cow::Borrowed(&[]),
+ namespace: Cow::Borrowed(&self.empty_namespace)
});
match result {
@@ -66,7 +70,7 @@ impl<W: Write> Writer<W> {
fn end_element(&mut self, name: &str) -> Result<(), ()> {
let result = self.xml_writer.write(WriteXmlEvent::EndElement {
- name: Name::local(name)
+ name: Some(Name::local(name))
});
match result {
@@ -106,8 +110,8 @@ impl<W: Write> Writer<W> {
let result = self.xml_writer.write(WriteXmlEvent::StartElement {
name: Name::local("plist"),
- attributes: vec!(version_attr),
- namespace: &self.empty_namespace
+ attributes: Cow::Borrowed(&[version_attr]),
+ namespace: Cow::Borrowed(&self.empty_namespace)
});
match result {
@@ -175,11 +179,8 @@ impl<W: Write> Writer<W> {
mod tests {
use chrono::{TimeZone, UTC};
use std::io::Cursor;
- use std::fs::File;
- use std::path::Path;
use super::*;
- use PlistEvent;
#[test]
fn streaming_parser() {
@@ -218,19 +219,25 @@ mod tests {
}
let comparison = "<?xml version=\"1.0\" encoding=\"utf-8\"?>
-<plist version=\"1.0\"><dict><key>Author</key>
-<string>William Shakespeare</string>
-<key>Lines</key>
-<array><string>It is a tale told by an idiot,</string>
-<string>Full of sound and fury, signifying nothing.</string></array>
-<key>Death</key>
-<integer>1564</integer>
-<key>Height</key>
-<real>1.6</real>
-<key>Data</key>
-<data>AAAAvgAAAAMAAAAeAAAA</data>
-<key>Birthdate</key>
-<date>1981-05-16T11:32:06+00:00</date></dict></plist>";
+<plist version=\"1.0\">
+ <dict>
+ <key>Author</key>
+ <string>William Shakespeare</string>
+ <key>Lines</key>
+ <array>
+ <string>It is a tale told by an idiot,</string>
+ <string>Full of sound and fury, signifying nothing.</string>
+ </array>
+ <key>Death</key>
+ <integer>1564</integer>
+ <key>Height</key>
+ <real>1.6</real>
+ <key>Data</key>
+ <data>AAAAvgAAAAMAAAAeAAAA</data>
+ <key>Birthdate</key>
+ <date>1981-05-16T11:32:06+00:00</date>
+ </dict>
+</plist>";
let s = String::from_utf8(cursor.into_inner()).unwrap();