use config::Options; use std::io::Read; use self::read::BincodeRead; use byteorder::ReadBytesExt; use internal::SizeLimit; use serde; use serde::de::Error as DeError; use serde::de::IntoDeserializer; use {Error, ErrorKind, Result}; pub mod read; /// A Deserializer that reads bytes from a buffer. /// /// This struct should rarely be used. /// In most cases, prefer the `deserialize_from` function. /// /// The ByteOrder that is chosen will impact the endianness that /// is used to read integers out of the reader. /// /// ```ignore /// let d = Deserializer::new(&mut some_reader, SizeLimit::new()); /// serde::Deserialize::deserialize(&mut deserializer); /// let bytes_read = d.bytes_read(); /// ``` pub(crate) struct Deserializer { reader: R, options: O, } impl<'de, R: BincodeRead<'de>, O: Options> Deserializer { /// Creates a new Deserializer with a given `Read`er and a size_limit. pub(crate) fn new(r: R, options: O) -> Deserializer { Deserializer { reader: r, options: options, } } fn read_bytes(&mut self, count: u64) -> Result<()> { self.options.limit().add(count) } fn read_type(&mut self) -> Result<()> { use std::mem::size_of; self.read_bytes(size_of::() as u64) } fn read_vec(&mut self) -> Result> { let len: usize = try!(serde::Deserialize::deserialize(&mut *self)); self.read_bytes(len as u64)?; self.reader.get_byte_buffer(len) } fn read_string(&mut self) -> Result { let vec = self.read_vec()?; String::from_utf8(vec).map_err(|e| ErrorKind::InvalidUtf8Encoding(e.utf8_error()).into()) } } macro_rules! impl_nums { ($ty:ty, $dser_method:ident, $visitor_method:ident, $reader_method:ident) => { #[inline] fn $dser_method(self, visitor: V) -> Result where V: serde::de::Visitor<'de>, { try!(self.read_type::<$ty>()); let value = try!(self.reader.$reader_method::()); visitor.$visitor_method(value) } } } impl<'de, 'a, R, O> serde::Deserializer<'de> for &'a mut Deserializer where R: BincodeRead<'de>, O: Options, { type Error = Error; #[inline] fn deserialize_any(self, _visitor: V) -> Result where V: serde::de::Visitor<'de>, { Err(Box::new(ErrorKind::DeserializeAnyNotSupported)) } fn deserialize_bool(self, visitor: V) -> Result where V: serde::de::Visitor<'de>, { let value: u8 = try!(serde::Deserialize::deserialize(self)); match value { 1 => visitor.visit_bool(true), 0 => visitor.visit_bool(false), value => Err(ErrorKind::InvalidBoolEncoding(value).into()), } } impl_nums!(u16, deserialize_u16, visit_u16, read_u16); impl_nums!(u32, deserialize_u32, visit_u32, read_u32); impl_nums!(u64, deserialize_u64, visit_u64, read_u64); impl_nums!(i16, deserialize_i16, visit_i16, read_i16); impl_nums!(i32, deserialize_i32, visit_i32, read_i32); impl_nums!(i64, deserialize_i64, visit_i64, read_i64); impl_nums!(f32, deserialize_f32, visit_f32, read_f32); impl_nums!(f64, deserialize_f64, visit_f64, read_f64); serde_if_integer128! { impl_nums!(u128, deserialize_u128, visit_u128, read_u128); impl_nums!(i128, deserialize_i128, visit_i128, read_i128); } #[inline] fn deserialize_u8(self, visitor: V) -> Result where V: serde::de::Visitor<'de>, { try!(self.read_type::()); visitor.visit_u8(try!(self.reader.read_u8())) } #[inline] fn deserialize_i8(self, visitor: V) -> Result where V: serde::de::Visitor<'de>, { try!(self.read_type::()); visitor.visit_i8(try!(self.reader.read_i8())) } fn deserialize_unit(self, visitor: V) -> Result where V: serde::de::Visitor<'de>, { visitor.visit_unit() } fn deserialize_char(self, visitor: V) -> Result where V: serde::de::Visitor<'de>, { use std::str; let error = || ErrorKind::InvalidCharEncoding.into(); let mut buf = [0u8; 4]; // Look at the first byte to see how many bytes must be read let _ = try!(self.reader.read_exact(&mut buf[..1])); let width = utf8_char_width(buf[0]); if width == 1 { return visitor.visit_char(buf[0] as char); } if width == 0 { return Err(error()); } if self.reader.read_exact(&mut buf[1..width]).is_err() { return Err(error()); } let res = try!( str::from_utf8(&buf[..width]) .ok() .and_then(|s| s.chars().next()) .ok_or(error()) ); visitor.visit_char(res) } fn deserialize_str(self, visitor: V) -> Result where V: serde::de::Visitor<'de>, { let len: usize = try!(serde::Deserialize::deserialize(&mut *self)); try!(self.read_bytes(len as u64)); self.reader.forward_read_str(len, visitor) } fn deserialize_string(self, visitor: V) -> Result where V: serde::de::Visitor<'de>, { visitor.visit_string(try!(self.read_string())) } fn deserialize_bytes(self, visitor: V) -> Result where V: serde::de::Visitor<'de>, { let len: usize = try!(serde::Deserialize::deserialize(&mut *self)); try!(self.read_bytes(len as u64)); self.reader.forward_read_bytes(len, visitor) } fn deserialize_byte_buf(self, visitor: V) -> Result where V: serde::de::Visitor<'de>, { visitor.visit_byte_buf(try!(self.read_vec())) } fn deserialize_enum( self, _enum: &'static str, _variants: &'static [&'static str], visitor: V, ) -> Result where V: serde::de::Visitor<'de>, { impl<'de, 'a, R: 'a, O> serde::de::EnumAccess<'de> for &'a mut Deserializer where R: BincodeRead<'de>, O: Options, { type Error = Error; type Variant = Self; fn variant_seed(self, seed: V) -> Result<(V::Value, Self::Variant)> where V: serde::de::DeserializeSeed<'de>, { let idx: u32 = try!(serde::de::Deserialize::deserialize(&mut *self)); let val: Result<_> = seed.deserialize(idx.into_deserializer()); Ok((try!(val), self)) } } visitor.visit_enum(self) } fn deserialize_tuple(self, len: usize, visitor: V) -> Result where V: serde::de::Visitor<'de>, { struct Access<'a, R: Read + 'a, O: Options + 'a> { deserializer: &'a mut Deserializer, len: usize, } impl<'de, 'a, 'b: 'a, R: BincodeRead<'de> + 'b, O: Options> serde::de::SeqAccess<'de> for Access<'a, R, O> { type Error = Error; fn next_element_seed(&mut self, seed: T) -> Result> where T: serde::de::DeserializeSeed<'de>, { if self.len > 0 { self.len -= 1; let value = try!(serde::de::DeserializeSeed::deserialize( seed, &mut *self.deserializer, )); Ok(Some(value)) } else { Ok(None) } } fn size_hint(&self) -> Option { Some(self.len) } } visitor.visit_seq(Access { deserializer: self, len: len, }) } fn deserialize_option(self, visitor: V) -> Result where V: serde::de::Visitor<'de>, { let value: u8 = try!(serde::de::Deserialize::deserialize(&mut *self)); match value { 0 => visitor.visit_none(), 1 => visitor.visit_some(&mut *self), v => Err(ErrorKind::InvalidTagEncoding(v as usize).into()), } } fn deserialize_seq(self, visitor: V) -> Result where V: serde::de::Visitor<'de>, { let len = try!(serde::Deserialize::deserialize(&mut *self)); self.deserialize_tuple(len, visitor) } fn deserialize_map(self, visitor: V) -> Result where V: serde::de::Visitor<'de>, { struct Access<'a, R: Read + 'a, O: Options + 'a> { deserializer: &'a mut Deserializer, len: usize, } impl<'de, 'a, 'b: 'a, R: BincodeRead<'de> + 'b, O: Options> serde::de::MapAccess<'de> for Access<'a, R, O> { type Error = Error; fn next_key_seed(&mut self, seed: K) -> Result> where K: serde::de::DeserializeSeed<'de>, { if self.len > 0 { self.len -= 1; let key = try!(serde::de::DeserializeSeed::deserialize( seed, &mut *self.deserializer, )); Ok(Some(key)) } else { Ok(None) } } fn next_value_seed(&mut self, seed: V) -> Result where V: serde::de::DeserializeSeed<'de>, { let value = try!(serde::de::DeserializeSeed::deserialize( seed, &mut *self.deserializer, )); Ok(value) } fn size_hint(&self) -> Option { Some(self.len) } } let len = try!(serde::Deserialize::deserialize(&mut *self)); visitor.visit_map(Access { deserializer: self, len: len, }) } fn deserialize_struct( self, _name: &str, fields: &'static [&'static str], visitor: V, ) -> Result where V: serde::de::Visitor<'de>, { self.deserialize_tuple(fields.len(), visitor) } fn deserialize_identifier(self, _visitor: V) -> Result where V: serde::de::Visitor<'de>, { let message = "Bincode does not support Deserializer::deserialize_identifier"; Err(Error::custom(message)) } fn deserialize_newtype_struct(self, _name: &str, visitor: V) -> Result where V: serde::de::Visitor<'de>, { visitor.visit_newtype_struct(self) } fn deserialize_unit_struct(self, _name: &'static str, visitor: V) -> Result where V: serde::de::Visitor<'de>, { visitor.visit_unit() } fn deserialize_tuple_struct( self, _name: &'static str, len: usize, visitor: V, ) -> Result where V: serde::de::Visitor<'de>, { self.deserialize_tuple(len, visitor) } fn deserialize_ignored_any(self, _visitor: V) -> Result where V: serde::de::Visitor<'de>, { let message = "Bincode does not support Deserializer::deserialize_ignored_any"; Err(Error::custom(message)) } fn is_human_readable(&self) -> bool { false } } impl<'de, 'a, R, O> serde::de::VariantAccess<'de> for &'a mut Deserializer where R: BincodeRead<'de>, O: Options, { type Error = Error; fn unit_variant(self) -> Result<()> { Ok(()) } fn newtype_variant_seed(self, seed: T) -> Result where T: serde::de::DeserializeSeed<'de>, { serde::de::DeserializeSeed::deserialize(seed, self) } fn tuple_variant(self, len: usize, visitor: V) -> Result where V: serde::de::Visitor<'de>, { serde::de::Deserializer::deserialize_tuple(self, len, visitor) } fn struct_variant(self, fields: &'static [&'static str], visitor: V) -> Result where V: serde::de::Visitor<'de>, { serde::de::Deserializer::deserialize_tuple(self, fields.len(), visitor) } } static UTF8_CHAR_WIDTH: [u8; 256] = [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x1F 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x3F 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x5F 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x7F 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x9F 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xBF 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xDF 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xEF 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xFF ]; // This function is a copy of core::str::utf8_char_width fn utf8_char_width(b: u8) -> usize { UTF8_CHAR_WIDTH[b as usize] as usize }