diff --git a/src/encoding_type.rs b/src/encoding_type.rs index 4dda319..97a665e 100644 --- a/src/encoding_type.rs +++ b/src/encoding_type.rs @@ -62,6 +62,17 @@ impl EncodingType { } } + pub fn name(&self) -> Option<&'static str> { + match *self { + EncodingType::None => None, + EncodingType::ASCII => None, + EncodingType::ISO_8859_1 => Some(WINDOWS_1252.name()), + EncodingType::EUC_JP => Some(EUC_JP.name()), + EncodingType::SHIFT_JIS => Some(SHIFT_JIS.name()), + EncodingType::UTF_8 => Some(UTF_8.name()), + } + } + fn decode_ascii(input: &[u8]) -> Result { // ASCII only goes up to 0x7F match input.iter().position(|&ch| ch >= 0x80) { diff --git a/src/to_text_xml/mod.rs b/src/to_text_xml/mod.rs index 3c3d506..dbd5bf8 100644 --- a/src/to_text_xml/mod.rs +++ b/src/to_text_xml/mod.rs @@ -1,13 +1,16 @@ use std::io::{Cursor, Write}; use quick_xml::Writer; +use quick_xml::events::{BytesDecl, Event}; +use encoding_type::EncodingType; use error::KbinError; mod node; mod node_collection; pub trait ToTextXml { + fn encoding(&self) -> EncodingType; fn write(&self, writer: &mut Writer) -> Result<(), KbinError>; } @@ -28,6 +31,12 @@ impl TextXmlWriter { pub fn to_text_xml(mut self, value: &T) -> Result, KbinError> where T: ToTextXml { + if let Some(encoding) = value.encoding().name() { + let header = BytesDecl::new(b"1.0", Some(encoding.as_bytes()), None); + + self.xml_writer.write_event(Event::Decl(header))?; + } + value.write(&mut self.xml_writer)?; Ok(self.xml_writer.into_inner().into_inner()) diff --git a/src/to_text_xml/node.rs b/src/to_text_xml/node.rs index 0066902..f84d6a6 100644 --- a/src/to_text_xml/node.rs +++ b/src/to_text_xml/node.rs @@ -5,6 +5,7 @@ use quick_xml::Writer; use quick_xml::events::{BytesEnd, BytesStart, BytesText, Event}; use quick_xml::events::attributes::Attribute; +use encoding_type::EncodingType; use error::KbinError; use node::Node; use node_types::StandardType; @@ -12,6 +13,11 @@ use to_text_xml::ToTextXml; use value::Value; impl ToTextXml for Node { + /// At the moment, a `Node` will always contain UTF-8 data. + fn encoding(&self) -> EncodingType { + EncodingType::UTF_8 + } + fn write(&self, writer: &mut Writer) -> Result<(), KbinError> { let key = self.key(); let mut elem = BytesStart::borrowed(key.as_bytes(), key.as_bytes().len()); diff --git a/src/to_text_xml/node_collection.rs b/src/to_text_xml/node_collection.rs index afca831..d9f78e7 100644 --- a/src/to_text_xml/node_collection.rs +++ b/src/to_text_xml/node_collection.rs @@ -5,12 +5,19 @@ use quick_xml::Writer; use quick_xml::events::{BytesEnd, BytesStart, BytesText, Event}; use quick_xml::events::attributes::Attribute; +use encoding_type::EncodingType; use error::{KbinError, KbinErrorKind}; use node::NodeCollection; use node_types::StandardType; use to_text_xml::ToTextXml; impl ToTextXml for NodeCollection { + /// At the moment, decoding the value of a `NodeDefinition` will decode + /// strings into UTF-8. + fn encoding(&self) -> EncodingType { + EncodingType::UTF_8 + } + fn write(&self, writer: &mut Writer) -> Result<(), KbinError> { let base = self.base(); let key = base.key()?.ok_or(KbinErrorKind::InvalidState)?;