de(inner_types): start breakout work on type deserialization from Map, Seq, and Structure handling

This commit is contained in:
Matt Bilker
2018-08-15 05:18:13 +00:00
parent d93677fb4d
commit c7fe349ac5
2 changed files with 356 additions and 14 deletions

333
src/de/inner_types.rs Normal file
View File

@@ -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<T> = StdResult<T, Error>;
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<V>(self, visitor: V) -> Result<V::Value>
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<V>(self, visitor: V) -> Result<V::Value>
where V: Visitor<'de>
{
let value = if self.is_array {
self.parent.reader.data_buf.$read_method::<BigEndian>().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<V>(self, _visitor: V) -> Result<V::Value>
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<V>(self, visitor: V) -> Result<V::Value>
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<V>(self, visitor: V) -> Result<V::Value>
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<V>(self, visitor: V) -> Result<V::Value>
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<V>(self, visitor: V) -> Result<V::Value>
where V: Visitor<'de>
{
trace!("TypeDeserializer::deserialize_bytes()");
visitor.visit_bytes(self.parent.reader.read_bytes()?)
}
fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
where V: Visitor<'de>
{
trace!("TypeDeserializer::deserialize_byte_buf()");
visitor.visit_byte_buf(self.parent.reader.read_bytes()?.to_vec())
}
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
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<V>(self, name: &'static str, _visitor: V) -> Result<V::Value>
where V: Visitor<'de>
{
trace!("TypeDeserializer::deserialize_unit_struct(name: {:?})", name);
unimplemented!();
}
fn deserialize_newtype_struct<V>(self, name: &'static str, _visitor: V) -> Result<V::Value>
where V: Visitor<'de>
{
trace!("TypeDeserializer::deserialize_newtype_struct(name: {:?})", name);
unimplemented!();
}
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
where V: Visitor<'de>
{
trace!("TypeDeserializer::deserialize_seq()");
unimplemented!();
}
fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value>
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<V>(self, name: &'static str, len: usize, visitor: V) -> Result<V::Value>
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<V>(self, visitor: V) -> Result<V::Value>
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<V>(self, name: &'static str, fields: &'static [&'static str], visitor: V) -> Result<V::Value>
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<V>(self, name: &'static str, variants: &'static [&'static str], _visitor: V) -> Result<V::Value>
where V: Visitor<'de>
{
trace!("Deserializer::deserialize_enum(name: {:?}, variants: {:?})", name, variants);
unimplemented!();
}
fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
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<V>(self, visitor: V) -> Result<V::Value>
where V: Visitor<'de>
{
trace!("Deserializer::deserialize_ignored_any()");
self.deserialize_any(visitor)
}
}

View File

@@ -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<V>(self, visitor: V) -> Result<V::Value>
where V: Visitor<'de>
{
trace!("Deserializer::deserialize_bytes()");
visitor.visit_bytes(self.reader.read_bytes()?)
forward_to_deserialize_any! {
bytes
}
fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
@@ -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<V>(self, visitor: V) -> Result<V::Value>