diff options
Diffstat (limited to 'third_party/rust/bincode/src/de')
-rw-r--r-- | third_party/rust/bincode/src/de/mod.rs | 465 | ||||
-rw-r--r-- | third_party/rust/bincode/src/de/read.rs | 201 |
2 files changed, 666 insertions, 0 deletions
diff --git a/third_party/rust/bincode/src/de/mod.rs b/third_party/rust/bincode/src/de/mod.rs new file mode 100644 index 0000000000..00f672d36b --- /dev/null +++ b/third_party/rust/bincode/src/de/mod.rs @@ -0,0 +1,465 @@ +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<R, O: Options> { + reader: R, + options: O, +} + +impl<'de, R: BincodeRead<'de>, O: Options> Deserializer<R, O> { + /// Creates a new Deserializer with a given `Read`er and a size_limit. + pub(crate) fn new(r: R, options: O) -> Deserializer<R, O> { + Deserializer { + reader: r, + options: options, + } + } + + fn read_bytes(&mut self, count: u64) -> Result<()> { + self.options.limit().add(count) + } + + fn read_type<T>(&mut self) -> Result<()> { + use std::mem::size_of; + self.read_bytes(size_of::<T>() as u64) + } + + fn read_vec(&mut self) -> Result<Vec<u8>> { + 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<String> { + 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<V>(self, visitor: V) -> Result<V::Value> + where V: serde::de::Visitor<'de>, + { + try!(self.read_type::<$ty>()); + let value = try!(self.reader.$reader_method::<O::Endian>()); + visitor.$visitor_method(value) + } + } +} + +impl<'de, 'a, R, O> serde::Deserializer<'de> for &'a mut Deserializer<R, O> +where + R: BincodeRead<'de>, + O: Options, +{ + type Error = Error; + + #[inline] + fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value> + where + V: serde::de::Visitor<'de>, + { + Err(Box::new(ErrorKind::DeserializeAnyNotSupported)) + } + + fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value> + 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<V>(self, visitor: V) -> Result<V::Value> + where + V: serde::de::Visitor<'de>, + { + try!(self.read_type::<u8>()); + visitor.visit_u8(try!(self.reader.read_u8())) + } + + #[inline] + fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value> + where + V: serde::de::Visitor<'de>, + { + try!(self.read_type::<i8>()); + visitor.visit_i8(try!(self.reader.read_i8())) + } + + fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value> + where + V: serde::de::Visitor<'de>, + { + visitor.visit_unit() + } + + fn deserialize_char<V>(self, visitor: V) -> Result<V::Value> + 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<V>(self, visitor: V) -> Result<V::Value> + 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<V>(self, visitor: V) -> Result<V::Value> + where + V: serde::de::Visitor<'de>, + { + visitor.visit_string(try!(self.read_string())) + } + + fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value> + 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<V>(self, visitor: V) -> Result<V::Value> + where + V: serde::de::Visitor<'de>, + { + visitor.visit_byte_buf(try!(self.read_vec())) + } + + fn deserialize_enum<V>( + self, + _enum: &'static str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result<V::Value> + where + V: serde::de::Visitor<'de>, + { + impl<'de, 'a, R: 'a, O> serde::de::EnumAccess<'de> for &'a mut Deserializer<R, O> + where + R: BincodeRead<'de>, + O: Options, + { + type Error = Error; + type Variant = Self; + + fn variant_seed<V>(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<V>(self, len: usize, visitor: V) -> Result<V::Value> + where + V: serde::de::Visitor<'de>, + { + struct Access<'a, R: Read + 'a, O: Options + 'a> { + deserializer: &'a mut Deserializer<R, O>, + 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<T>(&mut self, seed: T) -> Result<Option<T::Value>> + 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<usize> { + Some(self.len) + } + } + + visitor.visit_seq(Access { + deserializer: self, + len: len, + }) + } + + fn deserialize_option<V>(self, visitor: V) -> Result<V::Value> + 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<V>(self, visitor: V) -> Result<V::Value> + where + V: serde::de::Visitor<'de>, + { + let len = try!(serde::Deserialize::deserialize(&mut *self)); + + self.deserialize_tuple(len, visitor) + } + + fn deserialize_map<V>(self, visitor: V) -> Result<V::Value> + where + V: serde::de::Visitor<'de>, + { + struct Access<'a, R: Read + 'a, O: Options + 'a> { + deserializer: &'a mut Deserializer<R, O>, + 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<K>(&mut self, seed: K) -> Result<Option<K::Value>> + 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<V>(&mut self, seed: V) -> Result<V::Value> + where + V: serde::de::DeserializeSeed<'de>, + { + let value = try!(serde::de::DeserializeSeed::deserialize( + seed, + &mut *self.deserializer, + )); + Ok(value) + } + + fn size_hint(&self) -> Option<usize> { + Some(self.len) + } + } + + let len = try!(serde::Deserialize::deserialize(&mut *self)); + + visitor.visit_map(Access { + deserializer: self, + len: len, + }) + } + + fn deserialize_struct<V>( + self, + _name: &str, + fields: &'static [&'static str], + visitor: V, + ) -> Result<V::Value> + where + V: serde::de::Visitor<'de>, + { + self.deserialize_tuple(fields.len(), visitor) + } + + fn deserialize_identifier<V>(self, _visitor: V) -> Result<V::Value> + where + V: serde::de::Visitor<'de>, + { + let message = "Bincode does not support Deserializer::deserialize_identifier"; + Err(Error::custom(message)) + } + + fn deserialize_newtype_struct<V>(self, _name: &str, visitor: V) -> Result<V::Value> + where + V: serde::de::Visitor<'de>, + { + visitor.visit_newtype_struct(self) + } + + fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value> + where + V: serde::de::Visitor<'de>, + { + visitor.visit_unit() + } + + fn deserialize_tuple_struct<V>( + self, + _name: &'static str, + len: usize, + visitor: V, + ) -> Result<V::Value> + where + V: serde::de::Visitor<'de>, + { + self.deserialize_tuple(len, visitor) + } + + fn deserialize_ignored_any<V>(self, _visitor: V) -> Result<V::Value> + 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<R, O> +where + R: BincodeRead<'de>, + O: Options, +{ + type Error = Error; + + fn unit_variant(self) -> Result<()> { + Ok(()) + } + + fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value> + where + T: serde::de::DeserializeSeed<'de>, + { + serde::de::DeserializeSeed::deserialize(seed, self) + } + + fn tuple_variant<V>(self, len: usize, visitor: V) -> Result<V::Value> + where + V: serde::de::Visitor<'de>, + { + serde::de::Deserializer::deserialize_tuple(self, len, visitor) + } + + fn struct_variant<V>(self, fields: &'static [&'static str], visitor: V) -> Result<V::Value> + 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 +} diff --git a/third_party/rust/bincode/src/de/read.rs b/third_party/rust/bincode/src/de/read.rs new file mode 100644 index 0000000000..ffc5ae2ac0 --- /dev/null +++ b/third_party/rust/bincode/src/de/read.rs @@ -0,0 +1,201 @@ +use error::Result; +use serde; +use std::{io, slice}; + +/// An optional Read trait for advanced Bincode usage. +/// +/// It is highly recommended to use bincode with `io::Read` or `&[u8]` before +/// implementing a custom `BincodeRead`. +pub trait BincodeRead<'storage>: io::Read { + /// Forwards reading `length` bytes of a string on to the serde reader. + fn forward_read_str<V>(&mut self, length: usize, visitor: V) -> Result<V::Value> + where + V: serde::de::Visitor<'storage>; + + /// Return the first `length` bytes of the internal byte buffer. + fn get_byte_buffer(&mut self, length: usize) -> Result<Vec<u8>>; + + /// Forwards reading `length` bytes on to the serde reader. + fn forward_read_bytes<V>(&mut self, length: usize, visitor: V) -> Result<V::Value> + where + V: serde::de::Visitor<'storage>; +} + +/// A BincodeRead implementation for byte slices +/// NOT A PART OF THE STABLE PUBLIC API +#[doc(hidden)] +pub struct SliceReader<'storage> { + slice: &'storage [u8], +} + +/// A BincodeRead implementation for io::Readers +/// NOT A PART OF THE STABLE PUBLIC API +#[doc(hidden)] +pub struct IoReader<R> { + reader: R, + temp_buffer: Vec<u8>, +} + +impl<'storage> SliceReader<'storage> { + /// Constructs a slice reader + pub fn new(bytes: &'storage [u8]) -> SliceReader<'storage> { + SliceReader { slice: bytes } + } +} + +impl<R> IoReader<R> { + /// Constructs an IoReadReader + pub fn new(r: R) -> IoReader<R> { + IoReader { + reader: r, + temp_buffer: vec![], + } + } +} + +impl<'storage> io::Read for SliceReader<'storage> { + #[inline(always)] + fn read(&mut self, out: &mut [u8]) -> io::Result<usize> { + (&mut self.slice).read(out) + } + #[inline(always)] + fn read_exact(&mut self, out: &mut [u8]) -> io::Result<()> { + (&mut self.slice).read_exact(out) + } +} + +impl<R: io::Read> io::Read for IoReader<R> { + #[inline(always)] + fn read(&mut self, out: &mut [u8]) -> io::Result<usize> { + self.reader.read(out) + } + #[inline(always)] + fn read_exact(&mut self, out: &mut [u8]) -> io::Result<()> { + self.reader.read_exact(out) + } +} + +impl<'storage> SliceReader<'storage> { + #[inline(always)] + fn unexpected_eof() -> Box<::ErrorKind> { + return Box::new(::ErrorKind::Io(io::Error::new( + io::ErrorKind::UnexpectedEof, + "", + ))); + } +} + +impl<'storage> BincodeRead<'storage> for SliceReader<'storage> { + #[inline(always)] + fn forward_read_str<V>(&mut self, length: usize, visitor: V) -> Result<V::Value> + where + V: serde::de::Visitor<'storage>, + { + use ErrorKind; + if length > self.slice.len() { + return Err(SliceReader::unexpected_eof()); + } + + let string = match ::std::str::from_utf8(&self.slice[..length]) { + Ok(s) => s, + Err(e) => return Err(ErrorKind::InvalidUtf8Encoding(e).into()), + }; + let r = visitor.visit_borrowed_str(string); + self.slice = &self.slice[length..]; + r + } + + #[inline(always)] + fn get_byte_buffer(&mut self, length: usize) -> Result<Vec<u8>> { + if length > self.slice.len() { + return Err(SliceReader::unexpected_eof()); + } + + let r = &self.slice[..length]; + self.slice = &self.slice[length..]; + Ok(r.to_vec()) + } + + #[inline(always)] + fn forward_read_bytes<V>(&mut self, length: usize, visitor: V) -> Result<V::Value> + where + V: serde::de::Visitor<'storage>, + { + if length > self.slice.len() { + return Err(SliceReader::unexpected_eof()); + } + + let r = visitor.visit_borrowed_bytes(&self.slice[..length]); + self.slice = &self.slice[length..]; + r + } +} + +impl<R> IoReader<R> +where + R: io::Read, +{ + fn fill_buffer(&mut self, length: usize) -> Result<()> { + // We first reserve the space needed in our buffer. + let current_length = self.temp_buffer.len(); + if length > current_length { + self.temp_buffer.reserve_exact(length - current_length); + } + + // Then create a slice with the length as our desired length. This is + // safe as long as we only write (no reads) to this buffer, because + // `reserve_exact` above has allocated this space. + let buf = unsafe { + slice::from_raw_parts_mut(self.temp_buffer.as_mut_ptr(), length) + }; + + // This method is assumed to properly handle slices which include + // uninitialized bytes (as ours does). See discussion at the link below. + // https://github.com/servo/bincode/issues/260 + self.reader.read_exact(buf)?; + + // Only after `read_exact` successfully returns do we set the buffer + // length. By doing this after the call to `read_exact`, we can avoid + // exposing uninitialized memory in the case of `read_exact` returning + // an error. + unsafe { + self.temp_buffer.set_len(length); + } + + Ok(()) + } +} + +impl<'a, R> BincodeRead<'a> for IoReader<R> +where + R: io::Read, +{ + fn forward_read_str<V>(&mut self, length: usize, visitor: V) -> Result<V::Value> + where + V: serde::de::Visitor<'a>, + { + self.fill_buffer(length)?; + + let string = match ::std::str::from_utf8(&self.temp_buffer[..]) { + Ok(s) => s, + Err(e) => return Err(::ErrorKind::InvalidUtf8Encoding(e).into()), + }; + + let r = visitor.visit_str(string); + r + } + + fn get_byte_buffer(&mut self, length: usize) -> Result<Vec<u8>> { + self.fill_buffer(length)?; + Ok(::std::mem::replace(&mut self.temp_buffer, Vec::new())) + } + + fn forward_read_bytes<V>(&mut self, length: usize, visitor: V) -> Result<V::Value> + where + V: serde::de::Visitor<'a>, + { + self.fill_buffer(length)?; + let r = visitor.visit_bytes(&self.temp_buffer[..]); + r + } +} |