diff --git a/Cargo.toml b/Cargo.toml index e3ca40d..1bf81e4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "kbinxml" -version = "0.9.2" +version = "0.10.1" authors = ["Matt Bilker "] [dependencies] diff --git a/src/bin/kbinxml.rs b/src/bin/kbinxml.rs index 900b1c1..a112376 100644 --- a/src/bin/kbinxml.rs +++ b/src/bin/kbinxml.rs @@ -15,7 +15,7 @@ use std::net::Ipv4Addr; use std::str; use failure::Fail; -use kbinxml::{ExtraNodes, Ip4Addr, KbinXml, Node, Options, Printer, from_bytes, to_bytes}; +use kbinxml::{ExtraNodes, KbinXml, Node, Options, Printer, from_bytes, to_bytes}; use minidom::Element; use quick_xml::Writer; @@ -27,7 +27,7 @@ pub struct Testing2 { vu: Vec, opt: Option, opt2: Option, - ip: Ip4Addr, + ip: Ipv4Addr, #[serde(flatten)] extra: ExtraNodes, @@ -140,7 +140,9 @@ fn main() -> std::io::Result<()> { let value = from_bytes::(&contents); match &value { - Ok(obj2) => eprintln!("obj2: {:#?}", obj2), + Ok(obj2) => { + eprintln!("obj2: {:#?}", obj2); + }, Err(e) => eprintln!("Unable to parse generated kbin back to `Value`: {:#?}", e), }; } else { @@ -169,7 +171,7 @@ fn main() -> std::io::Result<()> { vu: vec![33, 255, 254], opt: None, opt2: Some(111), - ip: Ip4Addr::new(Ipv4Addr::new(127, 0, 0, 1)), + ip: Ipv4Addr::new(127, 0, 0, 1), extra: ExtraNodes::new(), }, }; diff --git a/src/byte_buffer.rs b/src/byte_buffer.rs index c79bfd3..a445752 100644 --- a/src/byte_buffer.rs +++ b/src/byte_buffer.rs @@ -85,6 +85,7 @@ impl<'buf> ByteBufferRead<'buf> { Ok(data) } + /* pub fn read_str(&mut self, encoding: EncodingType) -> Result { let data = self.buf_read()?; let data = strip_trailing_null_bytes(data); @@ -92,6 +93,7 @@ impl<'buf> ByteBufferRead<'buf> { encoding.decode_bytes(data) } + */ pub fn get(&mut self, size: u32) -> Result<&'buf [u8]> { let data = self.buf_read_size(size as usize)?; diff --git a/src/de/collection.rs b/src/de/collection.rs new file mode 100644 index 0000000..bf6abbd --- /dev/null +++ b/src/de/collection.rs @@ -0,0 +1,247 @@ +use serde::de::{self, IntoDeserializer, Visitor}; + +use de::custom::Custom; +use de::definition::NodeDefinitionDeserializer; +use de::node_contents::NodeContents; +use de::seq::Seq; +use de::structure::Struct; +use error::{Error, KbinErrorKind}; +use node::{Marshal, NodeCollection}; +use node_types::StandardType; + +fn warn_attributes<'de>(value: &NodeCollection<'de>) -> Result<(), Error> { + for attr in value.attributes() { + let key = attr.key()?.ok_or(KbinErrorKind::InvalidState)?; + let value = attr.value()?; + warn!("Ignoring Attribute {} = {}", key, value); + } + + Ok(()) +} + +pub struct NodeCollectionDeserializer<'a, 'de: 'a> { + pub(crate) collection: &'a mut NodeCollection<'de>, +} + +impl<'de, 'a> NodeCollectionDeserializer<'a, 'de> { + pub fn new(collection: &'a mut NodeCollection<'de>) -> Self { + trace!("NodeCollectionDeserializer::new() => attributes len: {}, children len: {}, base: {}", + collection.attributes().len(), + collection.children().len(), + collection.base()); + + Self { collection } + } + + fn pop_node(&mut self) -> Result, Error> { + self.collection.children_mut().pop_front().ok_or(KbinErrorKind::InvalidState.into()) + } + + fn pop_node_warn(&mut self) -> Result, Error> { + let value = self.pop_node()?; + warn_attributes(&value)?; + + Ok(value) + } +} + +macro_rules! forward_to_definition_deserializer { + ($($method:ident)*) => { + $( + #[inline] + fn $method(mut self, visitor: V) -> Result + where V: Visitor<'de> + { + trace!(concat!("NodeCollectionDeserializer::", stringify!($method), "()")); + let collection = self.pop_node()?; + NodeDefinitionDeserializer::new(collection.base()).$method(visitor) + } + )* + }; +} + +impl<'de, 'a> de::Deserializer<'de> for NodeCollectionDeserializer<'a, 'de> { + type Error = Error; + + fn is_human_readable(&self) -> bool { + false + } + + fn deserialize_any(mut self, visitor: V) -> Result + where V: Visitor<'de> + { + let collection = self.pop_node()?; + + let base = collection.base(); + let node_type = base.node_type; + let is_array = base.is_array; + + if is_array { + warn_attributes(&collection)?; + + trace!("NodeCollectionDeserializer::deserialize_any(node_type: {:?}, is_array: {})", node_type, is_array); + return visitor.visit_seq(Seq::new(&mut self.collection, is_array)?); + } + + match node_type { + StandardType::NodeStart => { + debug!("NodeCollectionDeserializer::deserialize_any(node_type: {:?}, is_array: {}) => deserializing node", node_type, is_array); + + let node = self.collection.as_node(); + debug!("NodeCollectionDeserializer::deserialize_any(node_type: {:?}, is_array: {}) => node: {:?}", node_type, is_array, node); + + let marshal = Marshal::with_node(StandardType::NodeStart, node?); + visitor.visit_newtype_struct(marshal.into_deserializer()) + }, + _ => { + warn_attributes(&collection)?; + + let value = base.value()?; + debug!("NodeCollectionDeserializer::deserialize_any(node_type: {:?}, is_array: {}) => value: {:?}", node_type, is_array, value); + let marshal = Marshal::with_value(node_type, value); + visitor.visit_newtype_struct(marshal.into_deserializer()) + }, + } + } + + forward_to_deserialize_any! { + ignored_any + } + + forward_to_definition_deserializer! { + deserialize_bool + deserialize_i8 + deserialize_i16 + deserialize_i32 + deserialize_i64 + deserialize_i128 + deserialize_u8 + deserialize_u16 + deserialize_u32 + deserialize_u64 + deserialize_u128 + deserialize_f32 + deserialize_f64 + deserialize_char + deserialize_str + deserialize_string + deserialize_bytes + deserialize_byte_buf + } + + fn deserialize_option(self, visitor: V) -> Result + where V: Visitor<'de> + { + trace!("NodeCollectionDeserializer::deserialize_option()"); + visitor.visit_some(self) + } + + fn deserialize_unit(self, _visitor: V) -> Result + where V: Visitor<'de> + { + trace!("NodeCollectionDeserializer::deserialize_unit()"); + Err(Error::StaticMessage("unit deserialization is not supported")) + } + + fn deserialize_unit_struct(self, name: &'static str, _visitor: V) -> Result + where V: Visitor<'de> + { + trace!("NodeCollectionDeserializer::deserialize_unit_struct(name: {:?})", name); + Err(Error::StaticMessage("unit struct deserialization is not supported")) + } + + fn deserialize_newtype_struct(self, name: &'static str, _visitor: V) -> Result + where V: Visitor<'de> + { + trace!("NodeCollectionDeserializer::deserialize_newtype_struct(name: {:?})", name); + Err(Error::StaticMessage("newtype struct deserialization is not supported")) + } + + fn deserialize_seq(mut self, visitor: V) -> Result + where V: Visitor<'de> + { + let base = self.collection.base(); + let node_type = base.node_type; + let is_array = base.is_array; + debug!("NodeCollectionDeserializer::deserialize_seq(node_type: {:?}, is_array: {})", node_type, is_array); + + visitor.visit_seq(Seq::new(&mut self.collection, false)?) + } + + fn deserialize_tuple(mut self, len: usize, visitor: V) -> Result + where V: Visitor<'de> + { + trace!("NodeCollectionDeserializer::deserialize_tuple(len: {})", len); + + let collection = self.pop_node_warn()?; + NodeDefinitionDeserializer::new(collection.base()).deserialize_tuple(len, visitor) + } + + fn deserialize_tuple_struct(mut self, name: &'static str, len: usize, visitor: V) -> Result + where V: Visitor<'de> + { + trace!("NodeCollectionDeserializer::deserialize_tuple_struct(name: {:?}, len: {})", name, len); + + let base = self.collection.base(); + let node_type = base.node_type; + + match name { + "__key" => { + let key = base.key()?.ok_or(KbinErrorKind::InvalidState)?; + let de = key.into_deserializer(); + visitor.visit_enum(Custom::new(de, node_type)) + }, + "__value" => { + debug!("NodeCollectionDeserializer::deserialize_tuple_struct(name: {:?}) => node_type: {:?}", name, node_type); + + let mut collection = self.pop_node()?; + visitor.visit_map(NodeContents::new(&mut collection)) + }, + _ => { + let collection = self.pop_node_warn()?; + NodeDefinitionDeserializer::new(collection.base()).deserialize_tuple_struct(name, len, visitor) + }, + } + } + + fn deserialize_map(mut self, visitor: V) -> Result + where V: Visitor<'de> + { + trace!("NodeCollectionDeserializer::deserialize_map()"); + + let mut collection = self.pop_node()?; + visitor.visit_map(Struct::new(&mut collection)) + } + + fn deserialize_struct(mut self, name: &'static str, fields: &'static [&'static str], visitor: V) -> Result + where V: Visitor<'de> + { + trace!("NodeCollectionDeserializer::deserialize_struct(name: {:?}, fields: {:?})", name, fields); + + let mut collection = self.pop_node()?; + let value = visitor.visit_map(Struct::new(&mut collection))?; + + let keys: Vec<_> = self.collection.children().iter() + .filter_map(|x| x.base().key().ok()) + .collect(); + trace!("NodeCollectionDeserializer::deserialize_struct(name: {:?}) => end, keys: {:?}", name, keys); + + Ok(value) + } + + fn deserialize_enum(self, name: &'static str, variants: &'static [&'static str], _visitor: V) -> Result + where V: Visitor<'de> + { + trace!("NodeCollectionDeserializer::deserialize_enum(name: {:?}, variants: {:?})", name, variants); + Err(Error::StaticMessage("enum deserialization not supported")) + } + + fn deserialize_identifier(self, visitor: V) -> Result + where V: Visitor<'de> + { + trace!("NodeCollectionDeserializer::deserialize_identifier()"); + + // Delegate identifier deserialization to `NodeDefinitionDeserializer` + NodeDefinitionDeserializer::new(self.collection.base()).deserialize_identifier(visitor) + } +} diff --git a/src/de/custom.rs b/src/de/custom.rs index d04b193..e5a7900 100644 --- a/src/de/custom.rs +++ b/src/de/custom.rs @@ -73,9 +73,18 @@ impl<'de, D> Deserializer<'de> for Custom visitor.visit_enum(self) } + /// Passthrough identifier deserialization so regular deserialization still works + #[inline] + fn deserialize_identifier(self, visitor: V) -> Result + where V: Visitor<'de> + { + trace!("::deserialize_identifier(node_type: {:?})", self.node_type); + self.de.deserialize_identifier(visitor) + } + forward_to_deserialize_any! { bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string bytes byte_buf option unit unit_struct newtype_struct seq - tuple tuple_struct map struct enum identifier ignored_any + tuple tuple_struct map struct enum ignored_any } } diff --git a/src/de/definition.rs b/src/de/definition.rs new file mode 100644 index 0000000..5a26879 --- /dev/null +++ b/src/de/definition.rs @@ -0,0 +1,228 @@ +use serde::de::{self, IntoDeserializer, Visitor}; + +use de::custom::Custom; +use de::seq::Seq; +use error::{Error, KbinErrorKind}; +use node::{Marshal, NodeCollection, NodeDefinition}; +use node_types::StandardType; +use value::Value; + +pub struct NodeDefinitionDeserializer<'de> { + definition: NodeDefinition<'de>, +} + +impl<'de> NodeDefinitionDeserializer<'de> { + pub fn new(definition: NodeDefinition<'de>) -> Self { + trace!("NodeDefinitionDeserializer::new(definition: {})", definition); + + Self { definition } + } +} + +macro_rules! auto_deserialize { + ($($method:ident $konst:ident $visit_method:ident)*) => { + $( + #[inline] + fn $method(self, visitor: V) -> Result + where V: Visitor<'de> + { + trace!(concat!("NodeDefinitionDeserializer::", stringify!($method), "()")); + + match self.definition.value() { + Ok(Value::$konst(value)) => visitor.$visit_method(value), + Ok(_) => Err(KbinErrorKind::InvalidNodeType(self.definition.node_type).into()), + Err(e) => Err(e.into()), + } + } + )* + }; +} + +impl<'de> de::Deserializer<'de> for NodeDefinitionDeserializer<'de> { + type Error = Error; + + fn is_human_readable(&self) -> bool { + false + } + + fn deserialize_any(self, visitor: V) -> Result + where V: Visitor<'de> + { + let node_type = self.definition.node_type; + let is_array = self.definition.is_array; + trace!("NodeDefinitionDeserializer::deserialize_any(node_type: {:?}, is_array: {})", node_type, is_array); + + // Construct a shim `NodeCollection` for `Seq` if we are deserializing an + // array value + if is_array { + let mut collection = NodeCollection::new(self.definition); + return visitor.visit_seq(Seq::new(&mut collection, true)?); + } + + let value = match node_type { + StandardType::NodeStart => { + debug!("NodeDefinitionDeserializer::deserialize_any(unode_type: {:?}, is_array: {})", node_type, is_array); + Err(KbinErrorKind::InvalidNodeType(node_type).into()) + }, + _ => { + let value = self.definition.value()?; + debug!("NodeDefinitionDeserializer::deserialize_any(node_type: {:?}, is_array: {}) => value: {:?}", node_type, is_array, value); + let marshal = Marshal::with_value(node_type, value); + visitor.visit_newtype_struct(marshal.into_deserializer()) + }, + }; + value + } + + forward_to_deserialize_any! { + i128 u128 char str + seq + map struct enum ignored_any + } + + fn deserialize_bool(self, visitor: V) -> Result + where V: Visitor<'de> + { + trace!("NodeDefinitionDeserializer::deserialize_bool()"); + + match self.definition.value() { + Ok(Value::Boolean(b)) => visitor.visit_bool(b), + Ok(_) => Err(KbinErrorKind::InvalidNodeType(self.definition.node_type).into()), + Err(e) => Err(e.into()), + } + } + + auto_deserialize! { + deserialize_i8 S8 visit_i8 + deserialize_i16 S16 visit_i16 + deserialize_i32 S32 visit_i32 + deserialize_i64 S64 visit_i64 + deserialize_u8 U8 visit_u8 + deserialize_u16 U16 visit_u16 + deserialize_u32 U32 visit_u32 + deserialize_u64 U64 visit_u64 + deserialize_f32 Float visit_f32 + deserialize_f64 Double visit_f64 + deserialize_byte_buf Binary visit_byte_buf + } + + fn deserialize_string(self, visitor: V) -> Result + where V: Visitor<'de> + { + trace!("NodeDefinitionDeserializer::deserialize_string()"); + + match self.definition.value() { + Ok(Value::String(s)) | + Ok(Value::Attribute(s)) => visitor.visit_string(s), + Ok(_) => Err(KbinErrorKind::InvalidNodeType(self.definition.node_type).into()), + Err(e) => Err(e.into()), + } + } + + fn deserialize_bytes(self, visitor: V) -> Result + where V: Visitor<'de> + { + trace!("NodeDefinitionDeserializer::deserialize_bytes()"); + + if self.definition.node_type == StandardType::Binary { + match self.definition.value_bytes() { + Some(data) => visitor.visit_bytes(data), + None => Err(KbinErrorKind::InvalidState.into()), + } + } else { + Err(KbinErrorKind::InvalidNodeType(self.definition.node_type).into()) + } + } + + fn deserialize_option(self, visitor: V) -> Result + where V: Visitor<'de> + { + trace!("NodeDefinitionDeserializer::deserialize_option()"); + visitor.visit_some(self) + } + + fn deserialize_unit(self, _visitor: V) -> Result + where V: Visitor<'de> + { + trace!("NodeDefinitionDeserializer::deserialize_unit()"); + Err(Error::StaticMessage("unit deserialization is not supported")) + } + + fn deserialize_unit_struct(self, name: &'static str, _visitor: V) -> Result + where V: Visitor<'de> + { + trace!("NodeDefinitionDeserializer::deserialize_unit_struct(name: {:?})", name); + Err(Error::StaticMessage("unit struct deserialization is not supported")) + } + + fn deserialize_newtype_struct(self, name: &'static str, _visitor: V) -> Result + where V: Visitor<'de> + { + trace!("NodeDefinitionDeserializer::deserialize_newtype_struct(name: {:?})", name); + Err(Error::StaticMessage("newtype struct deserialization is not supported")) + } + + fn deserialize_tuple_struct(self, name: &'static str, len: usize, visitor: V) -> Result + where V: Visitor<'de> + { + trace!("NodeDefinitionDeserializer::deserialize_tuple_struct(name: {:?}, len: {})", name, len); + + let node_type = self.definition.node_type; + + match name { + "__key" => { + let key = self.definition.key()?.ok_or(KbinErrorKind::InvalidState)?; + let de = key.into_deserializer(); + visitor.visit_enum(Custom::new(de, node_type)) + }, + "__value" => { + debug!("NodeDefinitionDeserializer::deserialize_tuple_struct(name: {:?}) => node_type: {:?}", name, node_type); + self.deserialize_any(visitor) + }, + _ => { + Err(KbinErrorKind::InvalidNodeType(self.definition.node_type).into()) + }, + } + } + + fn deserialize_tuple(self, len: usize, visitor: V) -> Result + where V: Visitor<'de> + { + trace!("NodeDefinitionDeserialize::deserialize_tuple(len: {})", len); + + macro_rules! tuple { + ($($konst:ident),*) => { + match self.definition.value() { + $( + Ok(value @ Value::$konst(_)) | + )* + Ok(value @ Value::Ip4(_)) => value.into_deserializer().deserialize_any(visitor), + Ok(_) => Err(KbinErrorKind::InvalidNodeType(self.definition.node_type).into()), + Err(e) => Err(e.into()), + } + }; + } + + tuple! { + S8_2, U8_2, S16_2, U16_2, S32_2, U32_2, S64_2, U64_2, Float2, Double2, Boolean2, + S8_3, U8_3, S16_3, U16_3, S32_3, U32_3, S64_3, U64_3, Float3, Double3, Boolean3, + S8_4, U8_4, S16_4, U16_4, S32_4, U32_4, S64_4, U64_4, Float4, Double4, Boolean4, + Vs16, Vu16, + Vs8, Vu8, Vb + } + } + + fn deserialize_identifier(self, visitor: V) -> Result + where V: Visitor<'de> + { + trace!("NodeDefinitionDeserializer::deserialize_identifier()"); + + let key = self.definition.key()?.ok_or(KbinErrorKind::InvalidState)?; + let key = match self.definition.node_type { + StandardType::Attribute => format!("attr_{}", key), + _ => key, + }; + + visitor.visit_string(key) + } +} diff --git a/src/de/mod.rs b/src/de/mod.rs index 1e59ffe..67c98d0 100644 --- a/src/de/mod.rs +++ b/src/de/mod.rs @@ -1,42 +1,25 @@ use std::result::Result as StdResult; -use byteorder::{BigEndian, ByteOrder, ReadBytesExt}; -use failure::ResultExt; -use serde::de::{self, Deserialize, DeserializeSeed, IntoDeserializer, Visitor}; +use serde::de::{self, Deserialize, Visitor}; use error::{Error, KbinErrorKind}; -use node::{Marshal, Node}; -use node_types::StandardType; +use node::NodeCollection; use reader::Reader; +mod collection; mod custom; +mod definition; mod node_contents; mod seq; mod structure; -mod tuple; use self::custom::Custom; -use self::node_contents::NodeContents; -use self::seq::Seq; use self::structure::Struct; -use self::tuple::TupleBytesDeserializer; pub type Result = StdResult; -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -enum ReadMode { - Key, - Single, - Array, -} - pub struct Deserializer<'de> { - read_mode: ReadMode, - node_stack: Vec<(StandardType, bool)>, - first_struct: bool, - ignore_attributes: bool, - - reader: Reader<'de>, + collection: NodeCollection<'de>, } pub fn from_bytes<'a, T>(input: &'a [u8]) -> Result @@ -49,77 +32,10 @@ pub fn from_bytes<'a, T>(input: &'a [u8]) -> Result impl<'de> Deserializer<'de> { pub fn new(input: &'de [u8]) -> Result { - let reader = Reader::new(input)?; + let mut reader = Reader::new(input)?; + let collection = NodeCollection::from_iter(&mut reader).ok_or(KbinErrorKind::InvalidState)?; - Ok(Self { - read_mode: ReadMode::Single, - node_stack: Vec::new(), - first_struct: true, - ignore_attributes: true, - reader, - }) - } - - #[inline] - fn node_stack_last(&self) -> Result<&(StandardType, bool)> { - self.node_stack.last() - .ok_or(KbinErrorKind::InvalidState.into()) - } - - #[inline] - fn set_read_mode(&mut self, read_mode: ReadMode) -> ReadMode { - let old_read_mode = self.read_mode; - self.read_mode = read_mode; - - old_read_mode - } - - fn read_node_with_name(&mut self) -> Result<(StandardType, bool, String)> { - let (node_type, is_array) = self.reader.read_node_type()?; - let name = self.reader.read_node_identifier()?; - debug!("name: {}", name); - - Ok((node_type, is_array, name)) - } -} - -macro_rules! de_type { - (byte; $method:ident, $visit_method:ident, $standard_type:ident $($cast:tt)*) => { - fn $method(self, visitor: V) -> Result - where V: Visitor<'de> - { - let value = match self.read_mode { - ReadMode::Key => return Err(KbinErrorKind::InvalidState.into()), - ReadMode::Single => { - self.reader.data_buf.get_aligned(*StandardType::$standard_type)?[0] $($cast)* - }, - ReadMode::Array => { - self.reader.read_u8().context(KbinErrorKind::DataRead(1))? $($cast)* - }, - }; - trace!(concat!("Deserializer::", stringify!($method), "() => value: {:?}"), value); - - visitor.$visit_method(value) - } - }; - (large; $method:ident, $visit_method:ident, $read_method:ident, $standard_type:ident) => { - fn $method(self, visitor: V) -> Result - where V: Visitor<'de> - { - let value = match self.read_mode { - ReadMode::Key => return Err(KbinErrorKind::InvalidState.into()), - ReadMode::Single => { - let value = self.reader.data_buf.get_aligned(*StandardType::$standard_type)?; - BigEndian::$read_method(&value) - }, - ReadMode::Array => { - self.reader.data_buf.$read_method::().context(KbinErrorKind::DataRead(StandardType::$standard_type.size as usize))? - }, - }; - trace!(concat!("Deserializer::", stringify!($method), "() => value: {:?}"), value); - - visitor.$visit_method(value) - } + Ok(Self { collection }) } } @@ -133,279 +49,14 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { fn deserialize_any(self, visitor: V) -> Result where V: Visitor<'de> { - let (node_type, is_array) = self.node_stack_last() - .map(|x| *x) - .or_else(|_| -> Result<_> { - let node = self.reader.peek_node_type()?; - self.node_stack.push(node); - Ok(node) - })?; - trace!("Deserializer::deserialize_any(node_type: {:?}, is_array: {})", node_type, is_array); - - // Handle arrays if we are not in array reading mode - if is_array { - // `Ip4` handling handled by `deserialize_seq` - match self.read_mode { - ReadMode::Array => {}, - _ => return self.deserialize_seq(visitor), - }; - } - - // Only deserialize identifiers in `Key` mode - if self.read_mode == ReadMode::Key { - return self.deserialize_identifier(visitor); - } - - let value = match node_type { - /* - StandardType::Attribute => self.deserialize_string(visitor), - StandardType::String => self.deserialize_string(visitor), - StandardType::Binary => visitor.visit_bytes(self.reader.read_bytes()?), - StandardType::U8 => self.deserialize_u8(visitor), - StandardType::U16 => self.deserialize_u16(visitor), - StandardType::U32 => self.deserialize_u32(visitor), - StandardType::U64 => self.deserialize_u64(visitor), - StandardType::S8 => self.deserialize_i8(visitor), - StandardType::S16 => self.deserialize_i16(visitor), - StandardType::S32 => self.deserialize_i32(visitor), - StandardType::S64 => self.deserialize_i64(visitor), - StandardType::Binary => visitor.visit_bytes(self.reader.read_bytes()?), - StandardType::Ip4 => { - let old_read_mode = self.set_read_mode(ReadMode::Array); - let value = visitor.visit_enum(Custom::new(self, node_type))?; - self.read_mode = old_read_mode; - Ok(value) - }, - StandardType::Boolean => self.deserialize_bool(visitor), - */ - StandardType::NodeStart => { - debug!("Deserializer::deserialize_any(node_type: {:?}, is_array: {}) => deserializing node", node_type, is_array); - let node = Node::deserialize(self); - debug!("Deserializer::deserialize_any(node_type: {:?}, is_array: {}) => node: {:?}", node_type, is_array, node); - let marshal = Marshal::with_node(StandardType::NodeStart, node?); - visitor.visit_newtype_struct(marshal.into_deserializer()) - }, - /* - StandardType::NodeEnd => { - // Move `deserialize_any` on to the next node - let _ = self.reader.read_node_type()?; - self.deserialize_any(visitor) - }, - */ - _ => { - let value = node_type.deserialize(self)?; - debug!("Deserializer::deserialize_any(node_type: {:?}, is_array: {}) => value: {:?}", node_type, is_array, value); - let marshal = Marshal::with_value(node_type, value); - visitor.visit_newtype_struct(marshal.into_deserializer()) - }, - }; - value + trace!("Deserializer::deserialize_any()"); + self.deserialize_map(visitor) } - fn deserialize_bool(self, visitor: V) -> Result - where V: Visitor<'de> - { - trace!("Deserializer::deserialize_bool()"); - - let value = match self.read_mode { - ReadMode::Key => return Err(KbinErrorKind::InvalidState.into()), - ReadMode::Single => self.reader.data_buf.get_aligned(*StandardType::Boolean)?[0], - ReadMode::Array => self.reader.read_u8().context(KbinErrorKind::DataRead(1))?, - }; - trace!("Deserializer::deserialize_bool() => value: {:?}", value); - - let value = match value { - 0x00 => false, - 0x01 => true, - value => return Err(Error::Message(format!("invalid value for boolean: {0:?} (0x{0:x})", value))), - }; - - visitor.visit_bool(value) - } - - de_type!(byte; deserialize_u8, visit_u8, U8); - de_type!(byte; deserialize_i8, visit_i8, S8 as i8); - de_type!(large; deserialize_u16, visit_u16, read_u16, U16); - de_type!(large; deserialize_i16, visit_i16, read_i16, S16); - de_type!(large; deserialize_u32, visit_u32, read_u32, U32); - de_type!(large; deserialize_i32, visit_i32, read_i32, S32); - de_type!(large; deserialize_u64, visit_u64, read_u64, U64); - de_type!(large; deserialize_i64, visit_i64, read_i64, S64); - de_type!(large; deserialize_f32, visit_f32, read_f32, Float); - de_type!(large; deserialize_f64, visit_f64, read_f64, Double); - - fn deserialize_char(self, _visitor: V) -> Result - where V: Visitor<'de> - { - trace!("Deserializer::deserialize_char()"); - Err(Error::StaticMessage("char deserialization is not supported")) - } - - fn deserialize_str(self, _visitor: V) -> Result - where V: Visitor<'de> - { - trace!("Deserializer::deserialize_str()"); - Err(Error::StaticMessage("borrowed string deserialization is not supported")) - } - - fn deserialize_string(self, visitor: V) -> Result - where V: Visitor<'de> - { - trace!("Deserializer::deserialize_string() => read_mode: {:?}", self.read_mode); - match self.read_mode { - ReadMode::Key => self.deserialize_identifier(visitor), - _ => visitor.visit_string(self.reader.read_string()?), - } - } - - fn deserialize_bytes(self, visitor: V) -> Result - where V: Visitor<'de> - { - trace!("Deserializer::deserialize_bytes()"); - visitor.visit_borrowed_bytes(self.reader.read_bytes()?) - } - - fn deserialize_byte_buf(self, visitor: V) -> Result - where V: Visitor<'de> - { - trace!("Deserializer::deserialize_byte_buf()"); - visitor.visit_byte_buf(self.reader.read_bytes()?.to_vec()) - } - - fn deserialize_option(self, visitor: V) -> Result - where V: Visitor<'de> - { - trace!("Deserializer::deserialize_option()"); - - // A `None` value will not occur because it will not be present in the input data - visitor.visit_some(self) - } - - fn deserialize_unit(self, _visitor: V) -> Result - where V: Visitor<'de> - { - trace!("Deserializer::deserialize_unit()"); - Err(Error::StaticMessage("unit deserialization is not supported")) - } - - fn deserialize_unit_struct(self, name: &'static str, _visitor: V) -> Result - where V: Visitor<'de> - { - trace!("Deserializer::deserialize_unit_struct(name: {:?})", name); - Err(Error::StaticMessage("unit struct deserialization is not supported")) - } - - fn deserialize_newtype_struct(self, name: &'static str, _visitor: V) -> Result - where V: Visitor<'de> - { - trace!("Deserializer::deserialize_newtype_struct(name: {:?})", name); - Err(Error::StaticMessage("newtype struct deserialization is not supported")) - } - - fn deserialize_seq(self, visitor: V) -> Result - where V: Visitor<'de> - { - trace!("Deserializer::deserialize_seq(read_mode: {:?})", self.read_mode); - - let (node_type, _) = *self.node_stack_last()?; - - let value = match node_type { - // If the last node type on the stack is a `NodeStart` then we are likely - // collecting a list of structs - StandardType::NodeStart => visitor.visit_seq(Seq::new(self, None)?)?, - - // Bytes should be deserialized by `deserialize_bytes` - StandardType::Binary => self.deserialize_bytes(visitor)?, - - _ => { - // TODO: add size check against len - let node_size = node_type.size * node_type.count; - let size = self.reader.read_u32().context(KbinErrorKind::ArrayLengthRead)?; - let arr_count = (size as usize) / node_size; - debug!("Deserializer::deserialize_seq() => read array size: {}, arr_count: {}", size, arr_count); - - // Changes to `self.read_mode` must stay here as `next_element_seed` is not - // called past the length of the array to reset the read mode - let old_read_mode = self.set_read_mode(ReadMode::Array); - let value = visitor.visit_seq(Seq::new(self, Some(arr_count))?)?; - self.read_mode = old_read_mode; - - // Only realign after the outermost array finishes reading - if self.read_mode == ReadMode::Single { - self.reader.data_buf.realign_reads(None)?; - } - - value - }, - }; - - Ok(value) - } - - fn deserialize_tuple(self, len: usize, visitor: V) -> Result - where V: Visitor<'de> - { - trace!("Deserializer::deserialize_tuple(len: {})", len); - - let (node_type, is_array) = *self.node_stack_last()?; - debug!("Deserializer::deserialize_tuple(len: {}) => node_type: {:?}, is_array: {}", len, node_type, is_array); - - // Handle case where kbin has an array but the Serde output is using a - // tuple - if is_array && self.read_mode == ReadMode::Single { - return self.deserialize_seq(visitor); - } - - // Use `get_aligned` to avoid edge cases with the indexors - if is_array { - let old_read_mode = self.set_read_mode(ReadMode::Array); - let value = visitor.visit_seq(Seq::new(self, Some(len))?)?; - self.read_mode = old_read_mode; - - // Only realign after the outermost array finishes reading - if self.read_mode == ReadMode::Single { - self.reader.data_buf.realign_reads(None)?; - } - - Ok(value) - } else { - let data = self.reader.data_buf.get_aligned(*node_type)?; - debug!("Deserializer::deserialize_tuple(len: {}) => data: 0x{:02x?}", len, data); - - visitor.visit_seq(TupleBytesDeserializer::new(node_type, data)) - } - } - - fn deserialize_tuple_struct(self, name: &'static str, len: usize, visitor: V) -> Result - where V: Visitor<'de> - { - trace!("Deserializer::deserialize_tuple_struct(name: {:?}, len: {})", name, len); - - match name { - "__key" => { - self.ignore_attributes = false; - - let (node_type, _is_array) = self.reader.last_node_type().ok_or(KbinErrorKind::InvalidState)?; - visitor.visit_enum(Custom::new(self, node_type)) - }, - "__value" => { - let (node_type, _is_array) = self.reader.last_node_type().ok_or(KbinErrorKind::InvalidState)?; - debug!("Deserializer::deserialize_tuple_struct(name: {:?}) => node_type: {:?}", name, node_type); - - let value = visitor.visit_map(NodeContents::new(self, node_type))?; - self.ignore_attributes = true; - - Ok(value) - }, - _ => { - let old_read_mode = self.set_read_mode(ReadMode::Array); - let value = visitor.visit_seq(Seq::new(self, Some(len))?)?; - self.read_mode = old_read_mode; - self.reader.data_buf.realign_reads(None)?; - - Ok(value) - }, - } + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str + string bytes byte_buf option unit unit_struct newtype_struct seq + tuple tuple_struct enum identifier } fn deserialize_map(self, visitor: V) -> Result @@ -413,20 +64,13 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { { trace!("Deserializer::deserialize_map()"); - // The `NodeStart` event is consumed by `deserialize_identifier` when - // reading the parent struct, don't consume the next event. - if self.first_struct { - let (node_type, _, name) = self.read_node_with_name()?; - debug!("Deserializer::deserialize_map() => node_type: {:?}, name: {:?}, last identifier: {:?}", node_type, name, self.reader.last_identifier()); + let value = visitor.visit_map(Struct::new(&mut self.collection))?; + let keys: Vec<_> = self.collection.children().iter() + .filter_map(|x| x.base().key().ok()) + .collect(); + trace!("Deserializer::deserialize_map() => end, keys: {:?}", keys); - // Sanity check - if node_type != StandardType::NodeStart { - return Err(KbinErrorKind::TypeMismatch(*StandardType::NodeStart, *node_type).into()); - } - } - self.first_struct = false; - - visitor.visit_map(Struct::new(self)) + Ok(value) } fn deserialize_struct(self, name: &'static str, fields: &'static [&'static str], visitor: V) -> Result @@ -434,47 +78,19 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { { trace!("Deserializer::deserialize_struct(name: {:?}, fields: {:?})", name, fields); - let value = self.deserialize_map(visitor)?; - trace!("Deserializer::deserialize_struct(name: {:?}) => end", name); + let value = visitor.visit_map(Struct::new(&mut self.collection))?; + let keys: Vec<_> = self.collection.children().iter() + .filter_map(|x| x.base().key().ok()) + .collect(); + trace!("Deserializer::deserialize_struct(name: {:?}) => end, keys: {:?}", name, keys); Ok(value) } - fn deserialize_enum(self, name: &'static str, variants: &'static [&'static str], _visitor: V) -> Result - where V: Visitor<'de> - { - trace!("Deserializer::deserialize_enum(name: {:?}, variants: {:?})", name, variants); - - Err(Error::StaticMessage("enum deserialization not supported")) - } - - fn deserialize_identifier(self, visitor: V) -> Result - where V: Visitor<'de> - { - let (node_type, _) = self.reader.last_node_type().ok_or(KbinErrorKind::InvalidState)?; - trace!("Deserializer::deserialize_identifier() => last node type: {:?}", node_type); - - // Prefix Attribute node identifier's with "attr_" to help the serializer - let name = match (node_type, self.reader.read_node_identifier()?) { - (StandardType::Attribute, name) => format!("attr_{}", name), - (StandardType::NodeStart, name) => { - self.first_struct = false; - name - }, - (_, name) => name, - }; - debug!("Deserializer::deserialize_identifier() => name: '{}'", name); - - // Do not use `deserialize_string`! That reads from the data buffer and - // this reads a sixbit string from the node buffer - visitor.visit_string(name) - } - fn deserialize_ignored_any(self, visitor: V) -> Result where V: Visitor<'de> { trace!("Deserializer::deserialize_ignored_any()"); - self.deserialize_any(visitor) } } diff --git a/src/de/node_contents.rs b/src/de/node_contents.rs index bb09847..f6679bd 100644 --- a/src/de/node_contents.rs +++ b/src/de/node_contents.rs @@ -1,8 +1,9 @@ use serde::de::{DeserializeSeed, IntoDeserializer, MapAccess}; -use de::{Custom, Deserializer, ReadMode, Result}; +use de::{Custom, Result}; +use de::definition::NodeDefinitionDeserializer; use error::{Error, KbinErrorKind}; -use node_types::StandardType; +use node::NodeCollection; #[derive(Debug)] enum ReadState { @@ -11,18 +12,16 @@ enum ReadState { } pub struct NodeContents<'a, 'de: 'a> { - de: &'a mut Deserializer<'de>, - node_type: StandardType, + collection: &'a mut NodeCollection<'de>, state: ReadState, } impl<'de, 'a> NodeContents<'a, 'de> { - pub fn new(de: &'a mut Deserializer<'de>, node_type: StandardType) -> Self { - trace!("--> NodeContents::new()"); + pub fn new(collection: &'a mut NodeCollection<'de>) -> Self { + trace!("--> NodeContents::new(node_type: {:?})", collection.base().node_type); Self { - de, - node_type, + collection, state: ReadState::Value, } } @@ -38,31 +37,22 @@ impl<'de, 'a> MapAccess<'de> for NodeContents<'a, 'de> { match self.state { ReadState::Value => { + let base = self.collection.base(); let de = "__value".into_deserializer(); - seed.deserialize(Custom::new(de, self.node_type)).map(Some) + seed.deserialize(Custom::new(de, base.node_type)).map(Some) }, ReadState::Attributes => { - let (node_type, _is_array) = self.de.reader.read_node_type()?; - debug!("NodeContents::next_key_seed() => node_type: {:?}", node_type); + if let Some(attribute) = self.collection.attributes().front() { + let key = attribute.key()?.ok_or(KbinErrorKind::InvalidState)?; + debug!("::next_key_seed(state: {:?}) => attribute: {:?}, key: {:?}", self.state, attribute, key); - match node_type { - StandardType::Attribute => {}, - StandardType::NodeEnd | - StandardType::FileEnd => { - debug!("<-- ::next_key_seed() => end of map, node stack: {:?}", self.de.node_stack); + let de = NodeDefinitionDeserializer::new(*attribute); + seed.deserialize(de).map(Some) + } else { + debug!("<-- ::next_key_seed(state: {:?}) => end of map", self.state); - return Ok(None); - }, - _ => return Err(KbinErrorKind::InvalidState.into()), - }; - - let old_read_mode = self.de.set_read_mode(ReadMode::Key); - let key = seed.deserialize(&mut *self.de).map(Some)?; - self.de.read_mode = old_read_mode; - - self.node_type = node_type; - - Ok(key) + Ok(None) + } }, } } @@ -74,13 +64,24 @@ impl<'de, 'a> MapAccess<'de> for NodeContents<'a, 'de> { match self.state { ReadState::Value => { - let value = seed.deserialize(&mut *self.de)?; + let base = self.collection.base(); + let de = NodeDefinitionDeserializer::new(base); + let value = seed.deserialize(de)?; self.state = ReadState::Attributes; Ok(value) }, ReadState::Attributes => { - seed.deserialize(Custom::new(&mut *self.de, self.node_type)) + if let Some(attribute) = self.collection.attributes_mut().pop_front() { + let node_type = attribute.node_type; + let value = attribute.value()?; + debug!("::next_value_seed() => attribute: {:?}, value: {:?}", attribute, value); + + let de = value.into_deserializer(); + seed.deserialize(Custom::new(de, node_type)) + } else { + Err(KbinErrorKind::InvalidState.into()) + } }, } } diff --git a/src/de/seq.rs b/src/de/seq.rs index f2708e8..760e788 100644 --- a/src/de/seq.rs +++ b/src/de/seq.rs @@ -1,57 +1,65 @@ -use serde::de::{DeserializeSeed, SeqAccess}; +use std::collections::VecDeque; -use de::{Deserializer, Result}; +use serde::de::{DeserializeSeed, IntoDeserializer, SeqAccess}; + +use de::collection::NodeCollectionDeserializer; +use de::custom::Custom; use error::{Error, KbinErrorKind}; +use node::NodeCollection; use node_types::StandardType; +use value::Value; + +enum SequenceMode { + Struct { + known_identifier: String, + }, + Value { + node_type: StandardType, + values: VecDeque, + }, +} pub struct Seq<'a, 'de: 'a> { - de: &'a mut Deserializer<'de>, + collection: &'a mut NodeCollection<'de>, index: usize, - len: Option, - known_identifier: Option, + seq_mode: SequenceMode, } impl<'de, 'a> Seq<'a, 'de> { - pub fn new(de: &'a mut Deserializer<'de>, len: Option) -> Result { - trace!("Seq::new(len: {:?})", len); + pub fn new(collection: &'a mut NodeCollection<'de>, is_array: bool) -> Result { + trace!("Seq::new(is_array: {})", is_array); - let known_identifier = if len.is_none() { - let value = de.reader.last_identifier().ok_or(KbinErrorKind::InvalidState)?.into(); - debug!("Seq::new(len: {:?}) => known identifier: {:?}", len, value); + let seq_mode = if is_array { + let base = collection.base(); + let node_type = base.node_type; + let value = base.value()?; + let values = if let Value::Array(node_type, values) = value { + debug!("Seq::new(is_array: {}) => len: {}", is_array, values.len()); - Some(value) + if node_type != base.node_type { + return Err(KbinErrorKind::TypeMismatch(base.node_type, node_type).into()); + } + + VecDeque::from(values) + } else { + return Err(KbinErrorKind::InvalidState.into()); + }; + + SequenceMode::Value { node_type, values } } else { - None + let child = collection.children().front().ok_or(KbinErrorKind::InvalidState)?; + let known_identifier = child.base().key()?.ok_or(KbinErrorKind::InvalidState)?; + debug!("Seq::new(is_array: {}) => known identifier: {:?}", is_array, known_identifier); + + SequenceMode::Struct { known_identifier } }; Ok(Self { - de, + collection, index: 0, - len, - known_identifier, + seq_mode, }) } - - fn is_end(&mut self, node_type: StandardType) -> Result { - // The struct sequence ends when the node identifier has a different name - // and the current node type is not `NodeStart` or `NodeEnd` and the last - // node was not a `NodeStart` event. - // - // The should not trigger for struct subfields because those would be - // deserialized by the struct deserializer. - if node_type != StandardType::NodeStart && - node_type != StandardType::NodeEnd - { - let node_identifier = self.de.reader.peek_node_identifier()?; - let known_identifier = self.known_identifier.as_ref().ok_or(KbinErrorKind::InvalidState)?; - if node_identifier.as_str() != known_identifier { - debug!("Seq::is_end() => peeked identifier does not equal known identifier: {:?}", known_identifier); - return Ok(true); - } - } - - Ok(false) - } } impl<'de, 'a> SeqAccess<'de> for Seq<'a, 'de> { @@ -59,48 +67,60 @@ impl<'de, 'a> SeqAccess<'de> for Seq<'a, 'de> { // A len of `None` indicates that the sequence ends when `NodeEnd` is reached // or a different type node is reached. - fn next_element_seed(&mut self, seed: T) -> Result> + fn next_element_seed(&mut self, seed: T) -> Result, Self::Error> where T: DeserializeSeed<'de> { trace!("--> Seq::next_element_seed()"); - if let Some(len) = self.len { - if self.index >= len { - debug!("Seq::next_element_seed() => out of bounds read, returning None"); + match self.seq_mode { + SequenceMode::Struct { ref known_identifier } => { + let base = match self.collection.children().front() { + Some(child) => child.base(), + None => { + debug!("<-- Seq::next_element_seed(mode: Struct) => end of sequence (by `collection.children.front() == None`)"); + return Ok(None); + }, + }; - return Ok(None); - } - } else { - let (node_type, _is_array) = self.de.reader.peek_node_type()?; - let (last_node_type, _is_array) = self.de.reader.last_node_type().ok_or(KbinErrorKind::InvalidState)?; - debug!("Seq::next_element_seed() => peeked type: {:?}, last type: {:?}", node_type, self.de.reader.last_node_type()); + let node_type = base.node_type; + debug!("Seq::next_element_seed(mode: Struct) => peeked type: {:?}", node_type); - if self.is_end(last_node_type)? { - debug!("<-- Seq::next_element_seed() => end of sequence (by last read node)"); - return Ok(None); - } - - // If the peeked node is not a `NodeStart` and this isn't the first - // element in the list, check the identifier - if self.index > 0 { - if self.is_end(node_type)? { - debug!("<-- Seq::next_element_seed() => end of sequence (by peeked node)"); - return Ok(None); + if self.index > 0 { + // The struct sequence ends when the node identifier has a different name + // and the current node type is not `NodeStart` or `NodeEnd` and the last + // node was not a `NodeStart` event. + // + // The should not trigger for struct subfields because those would be + // deserialized by the struct deserializer. + if node_type != StandardType::NodeStart && + node_type != StandardType::NodeEnd + { + let node_identifier = base.key()?.ok_or(KbinErrorKind::InvalidState)?; + if node_identifier.as_str() != known_identifier { + debug!("<-- Seq::next_element_seed(mode: Struct) => peeked identifier does not equal known identifier: {:?}", known_identifier); + return Ok(None); + } + } } - } + self.index += 1; - // `NodeEnd` signals the end of the sequence for a sequence of structs - // if all the structs in the sequence have the same type - match node_type { - // Trigger `deserialize_struct` to consume the `NodeStart` event after - // the first element in the struct sequence - StandardType::NodeStart => self.de.first_struct = true, - StandardType::NodeEnd => return Ok(None), - _ => {}, - }; + let de = NodeCollectionDeserializer::new(&mut self.collection); + seed.deserialize(de).map(Some) + }, + SequenceMode::Value { node_type, ref mut values } => { + let value = match values.pop_front() { + Some(v) => v, + None => { + debug!("<-- Seq::next_element_seed(mode: Value) => out of bounds read, returning None"); + + return Ok(None); + }, + }; + + let de = value.into_deserializer(); + let de = Custom::new(de, node_type); + seed.deserialize(de).map(Some) + }, } - self.index += 1; - - seed.deserialize(&mut *self.de).map(Some) } } diff --git a/src/de/structure.rs b/src/de/structure.rs index de7158e..36cc4fb 100644 --- a/src/de/structure.rs +++ b/src/de/structure.rs @@ -1,23 +1,29 @@ -use std::marker::PhantomData; +use serde::de::{DeserializeSeed, IntoDeserializer, MapAccess}; -use serde::de::{Deserialize, DeserializeSeed, MapAccess}; - -use de::{Deserializer, ReadMode, Result}; -use error::{Error, KbinErrorKind}; +use de::Custom; +use de::collection::NodeCollectionDeserializer; +use de::definition::NodeDefinitionDeserializer; +use error::Error; +use node::NodeCollection; use node_types::StandardType; pub struct Struct<'a, 'de: 'a> { - de: &'a mut Deserializer<'de>, - values_to_consume: usize, + collection: &'a mut NodeCollection<'de>, + key: Option, } impl<'de, 'a> Struct<'a, 'de> { - pub fn new(de: &'a mut Deserializer<'de>) -> Self { - trace!("--> Struct::new()"); + pub fn new(collection: &'a mut NodeCollection<'de>) -> Self { + let key = collection.base().key().ok().and_then(|v| v); + + trace!("--> Struct::new() => attributes len: {}, children len: {}, base: {}", + collection.attributes().len(), + collection.children().len(), + collection.base()); Self { - de, - values_to_consume: 0, + collection, + key, } } } @@ -25,93 +31,57 @@ impl<'de, 'a> Struct<'a, 'de> { impl<'de, 'a> MapAccess<'de> for Struct<'a, 'de> { type Error = Error; - fn next_key_seed(&mut self, seed: K) -> Result> + fn next_key_seed(&mut self, seed: K) -> Result, Self::Error> where K: DeserializeSeed<'de> { - trace!("--> ::next_key_seed()"); + debug!("--> ::next_key_seed()"); - let (node_type, is_array) = self.de.reader.read_node_type()?; - debug!("Struct::next_key_seed() => node_type: {:?}", node_type); + // First, if the key field is still present, emit the `__node_key` first + if self.key.is_some() { + let de = "__node_key".into_deserializer(); + return seed.deserialize(Custom::new(de, StandardType::String)).map(Some); + } - match node_type { - StandardType::NodeEnd | - StandardType::FileEnd => { + // Then if there are attributes left, deserialize them first + if let Some(attribute) = self.collection.attributes().front() { + let de = NodeDefinitionDeserializer::new(*attribute); + return seed.deserialize(de).map(Some); + } + + // Else, deserialize the child nodes + let mut node = match self.collection.children_mut().front_mut() { + Some(v) => v, + None => { debug!("<-- ::next_key_seed() => end of map"); return Ok(None); }, - _ => {}, }; - let old_read_mode = self.de.set_read_mode(ReadMode::Key); - let key = seed.deserialize(&mut *self.de).map(Some)?; - self.de.read_mode = old_read_mode; - - match node_type { - StandardType::NodeStart => { - debug!("Struct::next_key_seed() => got a node start!"); - }, - StandardType::Attribute => { - debug!("Struct::next_key_seed() => got an attribute!"); - }, - _ if self.de.ignore_attributes => { - // TODO(mbilker): Fix processing of `Attribute` nodes for non-NodeStart - // elements - loop { - let (node_type, _is_array) = self.de.reader.peek_node_type()?; - if node_type == StandardType::Attribute { - let _ = self.de.reader.read_node_type()?; - warn!("Struct::next_key_seed() => ignoring Attribute node"); - - let old_read_mode = self.de.set_read_mode(ReadMode::Key); - let key = String::deserialize(&mut *self.de).map(Some)?; - self.de.read_mode = old_read_mode; - warn!("Struct::next_key_seed() => ignored Attribute key: {:?}", key); - - self.values_to_consume += 1; - } else { - break; - } - } - - // Consume the end node and do a sanity check - let (node_type, _is_array) = self.de.reader.read_node_type()?; - if node_type != StandardType::NodeEnd { - return Err(KbinErrorKind::TypeMismatch(*StandardType::NodeEnd, *node_type).into()); - } - }, - _ => {}, - } - - // Store the current node type on the stack for stateful handling based on - // the current node type - self.de.node_stack.push((node_type, is_array)); - - Ok(key) + let de = NodeCollectionDeserializer::new(&mut node); + seed.deserialize(de).map(Some) } - fn next_value_seed(&mut self, seed: V) -> Result + fn next_value_seed(&mut self, seed: V) -> Result where V: DeserializeSeed<'de> { debug!("--> ::next_value_seed()"); - let value = seed.deserialize(&mut *self.de)?; - if self.de.ignore_attributes { - // Cannot use `next_value_seed` recursively here as it would restart this for loop - for _ in 0..self.values_to_consume { - warn!("Struct::next_value_seed() => ignoring Attribute node value"); - let seed = PhantomData; - let value: String = seed.deserialize(&mut *self.de)?; - warn!("Struct::next_value_seed() => ignored Attribute value: {:?}", value); - - let popped = self.de.node_stack.pop(); - debug!("::next_value_seed() => popped: {:?}, node_stack: {:?}", popped, self.de.node_stack); - } - self.values_to_consume = 0; + // First, if the key field is still present, emit the `__node_key` value + if let Some(key) = self.key.take() { + let de = key.into_deserializer(); + return seed.deserialize(de); } - let popped = self.de.node_stack.pop(); - debug!("::next_value_seed() => popped: {:?}, node_stack: {:?}", popped, self.de.node_stack); + // Then if there are attributes left, deserialize them first + if let Some(attribute) = self.collection.attributes_mut().pop_front() { + let de = NodeDefinitionDeserializer::new(attribute); + return seed.deserialize(de); + } - Ok(value) + // Else, deserialize the child nodes. Delegate popping nodes off the + // children queue by the deserialize methods else handling `Struct` + // sequences will break. + let de = NodeCollectionDeserializer::new(&mut self.collection); + seed.deserialize(de) } } diff --git a/src/ip4.rs b/src/ip4.rs deleted file mode 100644 index 77120f2..0000000 --- a/src/ip4.rs +++ /dev/null @@ -1,87 +0,0 @@ -use std::fmt; -use std::net::Ipv4Addr; -use std::ops::{Deref, DerefMut}; - -use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor}; -use serde::ser::{Serialize, SerializeTupleStruct, Serializer}; - -pub struct Ip4Addr(Ipv4Addr); - -pub(crate) struct Ip4Visitor; - -impl Ip4Addr { - pub fn new(addr: Ipv4Addr) -> Self { - Ip4Addr(addr) - } -} - -impl fmt::Display for Ip4Addr { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Display::fmt(&self.0, f) - } -} - -impl fmt::Debug for Ip4Addr { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Debug::fmt(&self.0, f) - } -} - -impl Deref for Ip4Addr { - type Target = Ipv4Addr; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl DerefMut for Ip4Addr { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} - -impl<'de> Visitor<'de> for Ip4Visitor { - type Value = [u8; 4]; - - fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str("a sequence of 4 bytes with no size indicator") - } - - fn visit_seq(self, mut seq: A) -> Result - where A: SeqAccess<'de> - { - trace!("Ip4Addr::visit_seq()"); - let v1: u8 = seq.next_element()?.unwrap(); - let v2: u8 = seq.next_element()?.unwrap(); - let v3: u8 = seq.next_element()?.unwrap(); - let v4: u8 = seq.next_element()?.unwrap(); - trace!("Ip4Addr:visit_seq() => [{}, {}, {}, {}]", v1, v2, v3, v4); - Ok([v1, v2, v3, v4]) - } -} - -impl<'de> Deserialize<'de> for Ip4Addr { - fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> - { - deserializer.deserialize_tuple_struct("ip4", 4, Ip4Visitor) - .map(|v| { - Ip4Addr(Ipv4Addr::from(v)) - }) - } -} - -impl Serialize for Ip4Addr { - fn serialize(&self, serializer: S) -> Result - where S: Serializer - { - let octets = self.0.octets(); - let mut ts = serializer.serialize_tuple_struct("ip4", 4)?; - ts.serialize_field(&octets[0])?; - ts.serialize_field(&octets[1])?; - ts.serialize_field(&octets[2])?; - ts.serialize_field(&octets[3])?; - ts.end() - } -} diff --git a/src/lib.rs b/src/lib.rs index f592c91..174f565 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -24,7 +24,6 @@ mod byte_buffer; mod compression; mod encoding_type; mod error; -mod ip4; mod node; mod node_types; mod options; @@ -50,7 +49,6 @@ pub use error::{KbinError, KbinErrorKind, Result}; pub use node::{ExtraNodes, Node}; pub use options::Options; pub use de::from_bytes; -pub use ip4::Ip4Addr; pub use ser::to_bytes; pub use value::Value; diff --git a/src/node/collection.rs b/src/node/collection.rs index 750de09..fa760ae 100644 --- a/src/node/collection.rs +++ b/src/node/collection.rs @@ -1,19 +1,29 @@ +use std::collections::VecDeque; +use std::fmt; use std::iter::Iterator; -use node::NodeDefinition; +use error::{KbinError, KbinErrorKind}; +use node::{Node, NodeDefinition}; use node_types::StandardType; +use value::Value; /// A collection of node definitions (`NodeDefinition`) #[derive(Debug)] -#[allow(dead_code)] pub struct NodeCollection<'buf> { base: NodeDefinition<'buf>, - attributes: Vec>, - children: Vec>, + attributes: VecDeque>, + children: VecDeque>, } impl<'buf> NodeCollection<'buf> { - #[allow(dead_code)] + pub fn new(base: NodeDefinition<'buf>) -> Self { + Self { + base, + attributes: VecDeque::with_capacity(0), + children: VecDeque::with_capacity(0), + } + } + pub fn from_iter(mut iter: I) -> Option> where I: Iterator> { @@ -26,21 +36,20 @@ impl<'buf> NodeCollection<'buf> { NodeCollection::with_base(base, &mut iter) } - #[allow(dead_code)] fn with_base(base: NodeDefinition<'buf>, iter: &mut I) -> Option> where I: Iterator> { - let mut attributes = Vec::new(); - let mut children = Vec::new(); + let mut attributes = VecDeque::new(); + let mut children = VecDeque::new(); loop { if let Some(def) = iter.next() { match def.node_type { - StandardType::Attribute => attributes.push(def), + StandardType::Attribute => attributes.push_back(def), StandardType::NodeEnd | StandardType::FileEnd => break, _ => match NodeCollection::with_base(def, iter) { - Some(child) => children.push(child), + Some(child) => children.push_back(child), None => return None, }, } @@ -55,4 +64,89 @@ impl<'buf> NodeCollection<'buf> { children, }) } + + #[inline] + pub fn base(&self) -> NodeDefinition<'buf> { + self.base + } + + #[inline] + pub fn attributes(&self) -> &VecDeque> { + &self.attributes + } + + #[inline] + pub fn attributes_mut(&mut self) -> &mut VecDeque> { + &mut self.attributes + } + + #[inline] + pub fn children(&self) -> &VecDeque> { + &self.children + } + + #[inline] + pub fn children_mut(&mut self) -> &mut VecDeque> { + &mut self.children + } + + pub fn as_node(&self) -> Result { + let mut node = self.base.as_node()?; + + for attr in &self.attributes { + let key = attr.key()?.ok_or(KbinErrorKind::InvalidState)?; + + if let Value::Attribute(value) = attr.value()? { + node.set_attr(key, value); + } else { + return Err(KbinErrorKind::InvalidState.into()); + } + } + + for child in &self.children { + node.append_child(child.as_node()?); + } + + Ok(node) + } +} + +struct DisplayDebugWrapper<'a, T: fmt::Display + 'a>(&'a T, bool); +impl<'a, T> fmt::Debug for DisplayDebugWrapper<'a, T> + where T: fmt::Display +{ + #[inline] + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if self.1 { + write!(f, "{:#}", self.0) + } else { + write!(f, "{}", self.0) + } + } +} + +struct VecDisplayDebugWrapper<'a, T: fmt::Display + 'a>(&'a VecDeque, bool); +impl<'a, T> fmt::Debug for VecDisplayDebugWrapper<'a, T> + where T: fmt::Display +{ + #[inline] + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut l = f.debug_list(); + for entry in self.0 { + l.entry(&DisplayDebugWrapper(&entry, self.1)); + } + l.finish() + } +} + +impl<'buf> fmt::Display for NodeCollection<'buf> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut d = f.debug_struct("NodeCollection"); + + d.field("base", &DisplayDebugWrapper(&self.base, false)); + d.field("attributes", &VecDisplayDebugWrapper(&self.attributes, false)); + d.field("children", &VecDisplayDebugWrapper(&self.children, true)); + + d.finish() + } } diff --git a/src/node/de.rs b/src/node/de.rs index 0da8a6c..f5e4efd 100644 --- a/src/node/de.rs +++ b/src/node/de.rs @@ -1,9 +1,8 @@ -use std::fmt::{self, Write}; +use std::fmt; use std::marker::PhantomData; -use indexmap::IndexMap; use serde::de::{self, Deserialize, DeserializeSeed, Error, EnumAccess, IntoDeserializer, MapAccess, SeqAccess, VariantAccess, Visitor}; -use serde::de::value::MapDeserializer; +use serde::de::value::{MapDeserializer, SeqDeserializer}; use node::Node; use node_types::StandardType; @@ -27,12 +26,9 @@ impl<'de> NodeVisitor { Ok(value) }, - // TODO: roll up `NodeStart` and everything else into a single map handler + // Rolling up the `NodeStart` handling and other value types is not going + // to happen as `NodeStart` nodes do not have a value node_type => { - //let value = try!(map.next_value()); - //debug!("NodeVisitor::map_to_node(node_type: {:?}) => value: {:?}", node_type, value); - - //let node = Node::with_value(key.to_owned(), value); let node = try!(map.next_value_seed(NodeWithValueSeed(key.to_owned()))); debug!("NodeVisitor::map_to_node(node_type: {:?}) => node: {:?}", node_type, node); @@ -55,9 +51,7 @@ impl<'de> Visitor<'de> for NodeVisitor { { trace!("NodeVisitor::visit_map()"); - let mut attributes = None; - let mut nodes = IndexMap::new(); - let mut value = None; + let mut node = Node::new(self.key.unwrap_or_else(|| "".to_owned())); while let Some(NodeStart { key, node_type }) = try!(map.next_key()) { debug!("NodeVisitor::visit_map() => node_type: {:?}, key: {:?}", node_type, key); @@ -68,7 +62,14 @@ impl<'de> Visitor<'de> for NodeVisitor { let node_value = try!(map.next_value()); debug!("NodeVisitor::visit_map() => node value: {:?}", node_value); - value = Some(node_value); + node.set_value(Some(node_value)); + } else if key == "__node_key" { + trace!("NodeVisitor::visit_map() => got __node_key, getting node key"); + + let node_key: String = try!(map.next_value()); + debug!("NodeVisitor::visit_map() => node key: {:?}", node_key); + + node.set_key(node_key); } else { match node_type { StandardType::Attribute => { @@ -76,47 +77,23 @@ impl<'de> Visitor<'de> for NodeVisitor { debug!("NodeVisitor::visit_map() => value: {:?}", value); if let Value::Attribute(s) = try!(value) { - let key = String::from(&key["attr_".len()..]); - let attributes = attributes.get_or_insert_with(IndexMap::new); - attributes.insert(key, s); + //let key = String::from(&key["attr_".len()..]); + node.set_attr(key, s); } else { return Err(A::Error::custom("`Attribute` node must have `Value::Attribute` value")); } }, _ => { - let node = NodeVisitor::map_to_node(node_type, &key, &mut map)?; + let new_node = NodeVisitor::map_to_node(node_type, &key, &mut map)?; debug!("NodeVisitor::visit_map() => node: {:?}", node); - if !nodes.contains_key(&key) { - nodes.insert(key, node); - } else { - let mut new_key = format!("{}1", key); - let mut i = 2; - while nodes.contains_key(&new_key) { - new_key.truncate(key.len()); - write!(new_key, "{}", i); - i += 1; - } - debug!("Node::visit_map() => next open key: {:?}", new_key); - nodes.insert(new_key, node); - } + node.append_child(new_node); }, }; } } - let children = match nodes.len() { - 0 => None, - _ => Some(nodes), - }; - - //debug!("NodeVisitor::visit_map() => nodes: {:#?}", nodes); - Ok(Node { - key: self.key.unwrap_or_else(|| "".to_owned()), - attributes, - children, - value, - }) + Ok(node) } #[inline] @@ -170,6 +147,8 @@ impl<'de> DeserializeSeed<'de> for NodeValueSeed { fn deserialize(self, deserializer: D) -> Result where D: de::Deserializer<'de> { + trace!("NodeValueSeed(key: {:?})::deserialize()", self.0); + deserializer.deserialize_map(NodeVisitor { key: Some(self.0) }) } } @@ -184,7 +163,7 @@ impl<'de> DeserializeSeed<'de> for NodeWithValueSeed { fn deserialize(self, deserializer: D) -> Result where D: de::Deserializer<'de> { - trace!("NodeValue::deserialize()"); + trace!("NodeWithValueSeed(key: {:?})::deserialize()", self.0); deserializer.deserialize_tuple_struct("__value", 0, NodeVisitor { key: Some(self.0) }) } @@ -222,11 +201,11 @@ impl<'de, E: Error> SeqAccess<'de> for NodeDeserializer { fn next_element_seed(&mut self, seed: T) -> Result, Self::Error> where T: DeserializeSeed<'de> { - macro_rules! map_deserializer { - ($value:expr) => { + macro_rules! make_deserializer { + ($value:expr, $deserializer:ident) => { match $value.take() { Some(value) => { - let deserializer = MapDeserializer::new(value.into_iter()); + let deserializer = $deserializer::new(value.into_iter()); seed.deserialize(deserializer).map(Some) }, None => seed.deserialize(().into_deserializer()).map(Some), @@ -237,8 +216,8 @@ impl<'de, E: Error> SeqAccess<'de> for NodeDeserializer { trace!("--> ::next_element_seed(index: {})", self.index); let value = match self.index { 0 => seed.deserialize(self.node.key.as_str().into_deserializer()).map(Some), - 1 => map_deserializer!(self.node.attributes), - 2 => map_deserializer!(self.node.children), + 1 => make_deserializer!(self.node.attributes, MapDeserializer), + 2 => make_deserializer!(self.node.children, SeqDeserializer), 3 => match self.node.value.take() { Some(value) => seed.deserialize(value.into_deserializer()).map(Some), None => seed.deserialize(().into_deserializer()).map(Some), @@ -286,7 +265,7 @@ impl<'de> Deserialize<'de> for NodeStart { type Value = NodeStart; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("valid node type (for NodeSeed)") + formatter.write_str("enum input of a node (for NodeStart)") } #[inline] diff --git a/src/node/definition.rs b/src/node/definition.rs index c147e2f..906290f 100644 --- a/src/node/definition.rs +++ b/src/node/definition.rs @@ -1,3 +1,5 @@ +use std::fmt; + use byte_buffer::strip_trailing_null_bytes; use encoding_type::EncodingType; use error::{KbinError, KbinErrorKind}; @@ -6,7 +8,7 @@ use node_types::StandardType; use sixbit::{Sixbit, SixbitSize}; use value::Value; -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy)] pub enum Key<'buf> { Compressed { size: SixbitSize, @@ -104,6 +106,13 @@ impl<'buf> NodeDefinition<'buf> { } } + pub fn value_bytes(&self) -> Option<&'buf [u8]> { + match self.data { + NodeData::Some { ref value_data, .. } => Some(value_data), + NodeData::None => None, + } + } + pub fn as_node(&self) -> Result { trace!("parsing definition: {:?}", self); match (self.node_type, self.data) { @@ -126,3 +135,54 @@ impl<'buf> NodeDefinition<'buf> { } } } + +impl<'buf> fmt::Debug for Key<'buf> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if let Ok(key) = self.to_string() { + write!(f, "\"{}\"", key) + } else { + match self { + Key::Compressed { ref size, ref data } => { + f.debug_struct("Compressed") + .field("size", &size) + .field("data", &data) + .finish() + }, + Key::Uncompressed { encoding, ref data } => { + f.debug_struct("Uncompressed") + .field("encoding", &encoding) + .field("data", &data) + .finish() + }, + } + } + } +} + +impl<'buf> fmt::Display for NodeDefinition<'buf> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut d = f.debug_struct("NodeDefinition"); + d.field("node_type", &self.node_type); + + match self.node_type { + StandardType::Attribute | + StandardType::String => { + d.field("encoding", &self.encoding); + }, + _ => {}, + }; + + match self.data { + NodeData::Some { ref key, ref value_data } => { + match key.to_string() { + Ok(key) => d.field("key", &key), + Err(e) => d.field("key", &e), + }; + d.field("value_data", &value_data); + }, + NodeData::None => {}, + }; + + d.finish() + } +} diff --git a/src/node/extra/de.rs b/src/node/extra/de.rs index 3549906..419f7dc 100644 --- a/src/node/extra/de.rs +++ b/src/node/extra/de.rs @@ -32,6 +32,16 @@ impl<'de> Deserialize<'de> for ExtraNodes { while let Some(key) = try!(map.next_key::()) { debug!("ExtraNodesVisitor::visit_map() => key: {:?}", key); + if key == "__node_key" { + debug!("ExtraNodesVisitor::visit_map() => got __node_key, getting node key"); + + let node_key: String = try!(map.next_value()); + debug!("ExtraNodesVisitor::visit_map() => node key: {:?}", node_key); + + extra.set_parent_key(node_key); + continue; + } + let marshal: Marshal = try!(map.next_value()); debug!("ExtraNodesVisitor::visit_map() => marshal: {:?}", marshal); diff --git a/src/node/extra/mod.rs b/src/node/extra/mod.rs index 6e795f8..3a4d33b 100644 --- a/src/node/extra/mod.rs +++ b/src/node/extra/mod.rs @@ -1,3 +1,5 @@ +use std::mem; + use indexmap::IndexMap; use node::Node; @@ -9,6 +11,7 @@ mod ser; /// parent object #[derive(Clone, Debug, Default, PartialEq)] pub struct ExtraNodes { + parent_key: String, attributes: IndexMap, nodes: IndexMap, } @@ -16,11 +19,17 @@ pub struct ExtraNodes { impl ExtraNodes { pub fn new() -> Self { Self { + parent_key: String::with_capacity(0), attributes: IndexMap::new(), nodes: IndexMap::new(), } } + #[inline] + pub fn parent_key(&self) -> &str { + &self.parent_key + } + #[inline] pub fn attributes(&self) -> &IndexMap { &self.attributes @@ -31,6 +40,10 @@ impl ExtraNodes { &self.nodes } + pub fn set_parent_key(&mut self, key: String) -> String { + mem::replace(&mut self.parent_key, key) + } + pub fn set_attr(&mut self, key: String, value: String) -> Option { self.attributes.insert(key, value) } diff --git a/src/node/mod.rs b/src/node/mod.rs index da4c043..b33b8c4 100644 --- a/src/node/mod.rs +++ b/src/node/mod.rs @@ -1,4 +1,5 @@ use std::fmt; +use std::mem; use indexmap::IndexMap; @@ -14,13 +15,21 @@ mod ser; pub use self::collection::NodeCollection; pub use self::definition::{Key, NodeData, NodeDefinition}; pub use self::extra::ExtraNodes; -pub use self::marshal::Marshal; +pub use self::marshal::{Marshal, MarshalDeserializer}; + +/* +#[derive(Clone, Debug, PartialEq)] +pub enum Child { + Single(Node), + Multiple(Vec), +} +*/ #[derive(Clone, Default, PartialEq)] pub struct Node { key: String, attributes: Option>, - children: Option>, + children: Option>, value: Option, } @@ -73,7 +82,7 @@ impl Node { } #[inline] - pub fn children(&self) -> Option<&IndexMap> { + pub fn children(&self) -> Option<&Vec> { self.children.as_ref() } @@ -86,13 +95,50 @@ impl Node { (self.key, self.value) } + pub fn set_key(&mut self, key: String) { + self.key = key; + } + pub fn set_attr(&mut self, key: String, value: String) -> Option { let attributes = self.attributes.get_or_insert_with(Default::default); attributes.insert(key, value) } - pub fn insert(&mut self, key: String, value: Node) -> Option { + pub fn append_child(&mut self, value: Node) { let children = self.children.get_or_insert_with(Default::default); - children.insert(key, value) + children.push(value); + + /* + match children.entry(key) { + Entry::Occupied(mut entry) => { + match entry.get_mut() { + child @ Child::Single(_) => { + let old = mem::replace(child, Child::Multiple(Vec::with_capacity(2))); + let node = match old { + Child::Single(node) => node, + Child::Multiple(_) => panic!("`old` was `Child::Multiple` after checking"), + }; + match child { + Child::Multiple(ref mut nodes) => { + nodes.push(node); + nodes.push(value); + }, + _ => panic!("Invalid result of node swap"), + }; + }, + Child::Multiple(ref mut nodes) => { + nodes.push(value); + }, + }; + }, + Entry::Vacant(entry) => { + entry.insert(Child::Single(value)); + }, + }; + */ + } + + pub fn set_value(&mut self, value: Option) -> Option { + mem::replace(&mut self.value, value) } } diff --git a/src/printer.rs b/src/printer.rs index b65dd2f..b640f45 100644 --- a/src/printer.rs +++ b/src/printer.rs @@ -1,5 +1,5 @@ use error::Result; -//use node::NodeCollection; +use node::NodeCollection; use node_types::StandardType; use reader::Reader; @@ -45,20 +45,11 @@ impl Printer { }; } - for def in &definitions { - match def.node_type { - StandardType::NodeEnd | - StandardType::FileEnd => {}, - _ => { - eprintln!("node: {:?}", def.as_node()); - }, - } - } - - /* let collection = NodeCollection::from_iter(definitions.into_iter()); - eprintln!("collection: {:#?}", collection); - */ + match collection { + Some(collection) => eprintln!("collection: {:#}", collection), + None => eprintln!("collection: {:?}", collection), + }; Ok(()) } diff --git a/src/reader.rs b/src/reader.rs index 79c4bc4..ca78eca 100644 --- a/src/reader.rs +++ b/src/reader.rs @@ -1,4 +1,4 @@ -use std::io::{Seek, SeekFrom}; +//use std::io::{Seek, SeekFrom}; use byteorder::{BigEndian, ReadBytesExt}; use failure::ResultExt; @@ -21,9 +21,6 @@ pub struct Reader<'buf> { pub(crate) data_buf: ByteBufferRead<'buf>, data_buf_start: u64, - - last_node_type: Option<(StandardType, bool)>, - last_node_identifier: Option, } impl<'buf> Reader<'buf> { @@ -68,9 +65,6 @@ impl<'buf> Reader<'buf> { data_buf, data_buf_start: data_buf_start as u64, - - last_node_type: None, - last_node_identifier: None, }) } @@ -93,16 +87,6 @@ impl<'buf> Reader<'buf> { self.encoding } - #[inline] - pub fn last_node_type(&self) -> Option<(StandardType, bool)> { - self.last_node_type - } - - #[inline] - pub fn last_identifier(&self) -> Option<&str> { - self.last_node_identifier.as_ref().map(String::as_str) - } - pub fn check_if_node_buffer_end(&self) -> Result<()> { if self.node_buf.position() >= self.data_buf_start { Err(KbinErrorKind::EndOfNodeBuffer.into()) @@ -111,6 +95,7 @@ impl<'buf> Reader<'buf> { } } + /* pub fn peek_node_type(&self) -> Result<(StandardType, bool)> { self.check_if_node_buffer_end()?; @@ -142,17 +127,18 @@ impl<'buf> Reader<'buf> { Ok(value) } + */ pub fn read_node_type(&mut self) -> Result<(StandardType, bool)> { self.check_if_node_buffer_end()?; let raw_node_type = self.node_buf.read_u8().context(KbinErrorKind::NodeTypeRead)?; let value = Self::parse_node_type(raw_node_type)?; - self.last_node_type = Some(value); Ok(value) } + /* pub fn read_node_identifier(&mut self) -> Result { let value = match self.compression { Compression::Compressed => { @@ -168,10 +154,9 @@ impl<'buf> Reader<'buf> { }; debug!("Reader::read_node_identifier() => value: {:?}", value); - self.last_node_identifier = Some(value.clone()); - Ok(value) } + */ pub fn read_node_data(&mut self, node_type: (StandardType, bool)) -> Result<&'buf [u8]> { let (node_type, is_array) = node_type; @@ -182,6 +167,10 @@ impl<'buf> Reader<'buf> { StandardType::String => self.data_buf.buf_read()?, StandardType::Binary => self.read_bytes()?, + StandardType::NodeStart | + StandardType::NodeEnd | + StandardType::FileEnd => &[], + _ if is_array => { let arr_size = self.read_u32().context(KbinErrorKind::ArrayLengthRead)?; let data = self.data_buf.get(arr_size)?; @@ -224,6 +213,7 @@ impl<'buf> Reader<'buf> { } } + /* pub fn read_string(&mut self) -> Result { let value = self.data_buf.read_str(self.encoding)?; debug!("Reader::read_string() => value: {:?}", value); @@ -237,6 +227,7 @@ impl<'buf> Reader<'buf> { Ok(value) } + */ pub fn read_u32(&mut self) -> Result { let value = self.data_buf.read_u32::().context(KbinErrorKind::DataRead(4))?;