From c7fe349ac578ac8ce280d9dab253e8fb2bf9e24a Mon Sep 17 00:00:00 2001 From: Matt Bilker Date: Wed, 15 Aug 2018 05:18:13 +0000 Subject: [PATCH] de(inner_types): start breakout work on type deserialization from Map, Seq, and Structure handling --- src/de/inner_types.rs | 333 ++++++++++++++++++++++++++++++++++++++++++ src/de/mod.rs | 37 +++-- 2 files changed, 356 insertions(+), 14 deletions(-) create mode 100644 src/de/inner_types.rs diff --git a/src/de/inner_types.rs b/src/de/inner_types.rs new file mode 100644 index 0000000..e09e5ab --- /dev/null +++ b/src/de/inner_types.rs @@ -0,0 +1,333 @@ +use std::result::Result as StdResult; + +use byteorder::{BigEndian, ByteOrder, ReadBytesExt}; +use failure::ResultExt; +use serde::de::Visitor; +use serde::de::Deserializer as SerdeDeserializer; + +use de::{Custom, Deserializer}; +use error::{Error, KbinErrorKind}; +use node_types::StandardType; + +pub type Result = StdResult; + +pub struct TypeDeserializer<'a, 'de: 'a> { + parent: &'a mut Deserializer<'de>, + node_type: StandardType, + is_array: bool, +} + +impl<'de, 'a> TypeDeserializer<'a, 'de> { + pub fn new(parent: &'a mut Deserializer<'de>, node_type: StandardType, is_array: bool) -> Self { + Self { + parent, + node_type, + is_array, + } + } +} + +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 = if self.is_array { + self.parent.reader.read_u8().context(KbinErrorKind::DataRead(1))? $($cast)* + } else { + self.parent.reader.data_buf.get_aligned(*StandardType::$standard_type)?[0] $($cast)* + }; + trace!(concat!("TypeDeserializer::", 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 = if self.is_array { + self.parent.reader.data_buf.$read_method::().context(KbinErrorKind::DataRead(StandardType::$standard_type.size as usize))? + } else { + let value = self.parent.reader.data_buf.get_aligned(*StandardType::$standard_type)?; + BigEndian::$read_method(&value) + }; + trace!(concat!("TypeDeserializer::", stringify!($method), "() => value: {:?}"), value); + + visitor.$visit_method(value) + } + } +} + +macro_rules! implement_type { + ($method:ident) => { + fn $method(self, _visitor: V) -> Result + where V: Visitor<'de> + { + trace!("TypeDeserializer::{}()", stringify!($method)); + unimplemented!(); + } + } +} + +impl<'de, 'a> SerdeDeserializer<'de> for TypeDeserializer<'a, 'de> { + type Error = Error; + + fn is_human_readable(&self) -> bool { + false + } + + fn deserialize_any(self, visitor: V) -> Result + where V: Visitor<'de> + { + trace!("TypeDeserializer::deserialize_any(node_type: {:?}, is_array: {})", self.node_type, self.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), + }; + } + */ + + let value = match self.node_type { + StandardType::Attribute => self.deserialize_string(visitor), + StandardType::String => self.deserialize_string(visitor), + StandardType::Binary => self.deserialize_bytes(visitor), + 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::Boolean => self.deserialize_bool(visitor), + StandardType::NodeStart => unimplemented!(), + StandardType::NodeEnd => unimplemented!(), + _ => visitor.visit_enum(Custom::new(self.parent, self.node_type)), + }; + value + } + + fn deserialize_bool(self, visitor: V) -> Result + where V: Visitor<'de> + { + trace!("TypeDeserializer::deserialize_bool()"); + + let value = self.parent.reader.data_buf.get_aligned(*StandardType::Boolean)?[0]; + trace!("TypeDeserializer::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); + implement_type!(deserialize_char); + implement_type!(deserialize_str); + + fn deserialize_string(self, visitor: V) -> Result + where V: Visitor<'de> + { + trace!("TypeDeserializer::deserialize_string()"); + visitor.visit_string(self.parent.reader.read_string()?) + /* + 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!("TypeDeserializer::deserialize_bytes()"); + + visitor.visit_bytes(self.parent.reader.read_bytes()?) + } + + fn deserialize_byte_buf(self, visitor: V) -> Result + where V: Visitor<'de> + { + trace!("TypeDeserializer::deserialize_byte_buf()"); + + visitor.visit_byte_buf(self.parent.reader.read_bytes()?.to_vec()) + } + + fn deserialize_option(self, visitor: V) -> Result + where V: Visitor<'de> + { + trace!("TypeDeserializer::deserialize_option()"); + + // A `None` value will not occur because it will not be present in the input data + visitor.visit_some(self) + } + + implement_type!(deserialize_unit); + + fn deserialize_unit_struct(self, name: &'static str, _visitor: V) -> Result + where V: Visitor<'de> + { + trace!("TypeDeserializer::deserialize_unit_struct(name: {:?})", name); + unimplemented!(); + } + + fn deserialize_newtype_struct(self, name: &'static str, _visitor: V) -> Result + where V: Visitor<'de> + { + trace!("TypeDeserializer::deserialize_newtype_struct(name: {:?})", name); + unimplemented!(); + } + + fn deserialize_seq(self, visitor: V) -> Result + where V: Visitor<'de> + { + trace!("TypeDeserializer::deserialize_seq()"); + unimplemented!(); + } + + fn deserialize_tuple(self, len: usize, visitor: V) -> Result + where V: Visitor<'de> + { + trace!("TypeDeserializer::deserialize_tuple(len: {})", len); + unimplemented!(); + + /* + 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); + } + + //self.deserialize_seq(visitor) + 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) + */ + } + + fn deserialize_tuple_struct(self, name: &'static str, len: usize, visitor: V) -> Result + where V: Visitor<'de> + { + trace!("TypeDeserializer::deserialize_tuple_struct(name: {:?}, len: {})", name, len); + unimplemented!(); + + /* + if name == "__key" { + let (node_type, _is_array) = self.reader.last_node_type().ok_or(KbinErrorKind::InvalidState)?; + visitor.visit_enum(Custom::new(self, node_type)) + } else { + 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) + } + */ + } + + fn deserialize_map(self, visitor: V) -> Result + where V: Visitor<'de> + { + trace!("TypeDeserializer::deserialize_map()"); + unimplemented!(); + + // 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()); + + // 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)) + */ + } + + fn deserialize_struct(self, name: &'static str, fields: &'static [&'static str], visitor: V) -> Result + where V: Visitor<'de> + { + trace!("Deserializer::deserialize_struct(name: {:?}, fields: {:?})", name, fields); + + let value = self.deserialize_map(visitor)?; + trace!("Deserializer::deserialize_struct(name: {:?}) => end", name); + + 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); + unimplemented!(); + } + + fn deserialize_identifier(self, visitor: V) -> Result + where V: Visitor<'de> + { + trace!("TypeDeserializer::deserialize_identifier()"); + visitor.visit_string(self.parent.reader.read_node_identifier()?) + + /* + 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/mod.rs b/src/de/mod.rs index 532477e..2dcca76 100644 --- a/src/de/mod.rs +++ b/src/de/mod.rs @@ -9,6 +9,7 @@ use node_types::StandardType; use reader::Reader; mod custom; +mod inner_types; mod seq; mod structure; @@ -155,9 +156,10 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { } let value = match node_type { + /* StandardType::Attribute => self.deserialize_string(visitor), StandardType::String => self.deserialize_string(visitor), - StandardType::Binary => self.deserialize_bytes(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), @@ -166,13 +168,15 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { 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::Boolean => self.deserialize_bool(visitor), StandardType::NodeStart => self.deserialize_map(visitor), StandardType::NodeEnd => { // Move `deserialize_any` on to the next node @@ -189,7 +193,11 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { { trace!("Deserializer::deserialize_bool()"); - let value = self.reader.data_buf.get_aligned(*StandardType::Boolean)?[0]; + 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 { @@ -224,12 +232,8 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { } } - fn deserialize_bytes(self, visitor: V) -> Result - where V: Visitor<'de> - { - trace!("Deserializer::deserialize_bytes()"); - - visitor.visit_bytes(self.reader.read_bytes()?) + forward_to_deserialize_any! { + bytes } fn deserialize_byte_buf(self, visitor: V) -> Result @@ -334,12 +338,17 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { { trace!("Deserializer::deserialize_tuple_struct(name: {:?}, len: {})", name, len); - 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)?; + if name == "__key" { + let (node_type, _is_array) = self.reader.last_node_type().ok_or(KbinErrorKind::InvalidState)?; + visitor.visit_enum(Custom::new(self, node_type)) + } else { + 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) + Ok(value) + } } fn deserialize_map(self, visitor: V) -> Result