From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- third_party/rust/bincode/src/byteorder.rs | 385 ++++++++++++ third_party/rust/bincode/src/config/endian.rs | 27 + third_party/rust/bincode/src/config/int.rs | 682 +++++++++++++++++++++ third_party/rust/bincode/src/config/legacy.rs | 253 ++++++++ third_party/rust/bincode/src/config/limit.rs | 49 ++ third_party/rust/bincode/src/config/mod.rs | 408 +++++++++++++ third_party/rust/bincode/src/config/trailing.rs | 37 ++ third_party/rust/bincode/src/de/mod.rs | 515 ++++++++++++++++ third_party/rust/bincode/src/de/read.rs | 202 +++++++ third_party/rust/bincode/src/error.rs | 115 ++++ third_party/rust/bincode/src/internal.rs | 124 ++++ third_party/rust/bincode/src/lib.rs | 201 ++++++ third_party/rust/bincode/src/ser/mod.rs | 772 ++++++++++++++++++++++++ 13 files changed, 3770 insertions(+) create mode 100644 third_party/rust/bincode/src/byteorder.rs create mode 100644 third_party/rust/bincode/src/config/endian.rs create mode 100644 third_party/rust/bincode/src/config/int.rs create mode 100644 third_party/rust/bincode/src/config/legacy.rs create mode 100644 third_party/rust/bincode/src/config/limit.rs create mode 100644 third_party/rust/bincode/src/config/mod.rs create mode 100644 third_party/rust/bincode/src/config/trailing.rs create mode 100644 third_party/rust/bincode/src/de/mod.rs create mode 100644 third_party/rust/bincode/src/de/read.rs create mode 100644 third_party/rust/bincode/src/error.rs create mode 100644 third_party/rust/bincode/src/internal.rs create mode 100644 third_party/rust/bincode/src/lib.rs create mode 100644 third_party/rust/bincode/src/ser/mod.rs (limited to 'third_party/rust/bincode/src') diff --git a/third_party/rust/bincode/src/byteorder.rs b/third_party/rust/bincode/src/byteorder.rs new file mode 100644 index 0000000000..298503d20f --- /dev/null +++ b/third_party/rust/bincode/src/byteorder.rs @@ -0,0 +1,385 @@ +// Copyright (c) 2015 Andrew Gallant + +use std::io; +use std::io::Result; +use std::ptr::copy_nonoverlapping; + +#[derive(Copy, Clone)] +pub struct LittleEndian; + +#[derive(Copy, Clone)] +pub struct BigEndian; + +#[cfg(target_endian = "little")] +pub type NativeEndian = LittleEndian; + +#[cfg(target_endian = "big")] +pub type NativeEndian = BigEndian; + +macro_rules! read_num_bytes { + ($ty:ty, $size:expr, $src:expr, $which:ident) => {{ + assert!($size == ::std::mem::size_of::<$ty>()); + assert!($size <= $src.len()); + let mut data: $ty = 0; + unsafe { + copy_nonoverlapping($src.as_ptr(), &mut data as *mut $ty as *mut u8, $size); + } + data.$which() + }}; +} + +macro_rules! write_num_bytes { + ($ty:ty, $size:expr, $n:expr, $dst:expr, $which:ident) => {{ + assert!($size <= $dst.len()); + unsafe { + // N.B. https://github.com/rust-lang/rust/issues/22776 + let bytes = *(&$n.$which() as *const _ as *const [u8; $size]); + copy_nonoverlapping((&bytes).as_ptr(), $dst.as_mut_ptr(), $size); + } + }}; +} + +impl ByteOrder for LittleEndian { + #[inline] + fn read_u16(buf: &[u8]) -> u16 { + read_num_bytes!(u16, 2, buf, to_le) + } + + #[inline] + fn read_u32(buf: &[u8]) -> u32 { + read_num_bytes!(u32, 4, buf, to_le) + } + + #[inline] + fn read_u64(buf: &[u8]) -> u64 { + read_num_bytes!(u64, 8, buf, to_le) + } + + #[inline] + fn write_u16(buf: &mut [u8], n: u16) { + write_num_bytes!(u16, 2, n, buf, to_le); + } + + #[inline] + fn write_u32(buf: &mut [u8], n: u32) { + write_num_bytes!(u32, 4, n, buf, to_le); + } + + #[inline] + fn write_u64(buf: &mut [u8], n: u64) { + write_num_bytes!(u64, 8, n, buf, to_le); + } + + serde_if_integer128! { + #[inline] + fn write_u128(buf: &mut [u8], n: u128) { + write_num_bytes!(u128, 16, n, buf, to_le); + } + + #[inline] + fn read_u128(buf: &[u8]) -> u128 { + read_num_bytes!(u128, 16, buf, to_le) + } + } +} + +impl ByteOrder for BigEndian { + #[inline] + fn read_u16(buf: &[u8]) -> u16 { + read_num_bytes!(u16, 2, buf, to_be) + } + + #[inline] + fn read_u32(buf: &[u8]) -> u32 { + read_num_bytes!(u32, 4, buf, to_be) + } + + #[inline] + fn read_u64(buf: &[u8]) -> u64 { + read_num_bytes!(u64, 8, buf, to_be) + } + + #[inline] + fn write_u16(buf: &mut [u8], n: u16) { + write_num_bytes!(u16, 2, n, buf, to_be); + } + + #[inline] + fn write_u32(buf: &mut [u8], n: u32) { + write_num_bytes!(u32, 4, n, buf, to_be); + } + + #[inline] + fn write_u64(buf: &mut [u8], n: u64) { + write_num_bytes!(u64, 8, n, buf, to_be); + } + + serde_if_integer128! { + #[inline] + fn write_u128(buf: &mut [u8], n: u128) { + write_num_bytes!(u128, 16, n, buf, to_be); + } + + #[inline] + fn read_u128(buf: &[u8]) -> u128 { + read_num_bytes!(u128, 16, buf, to_be) + } + } +} + +pub trait ByteOrder: Clone + Copy { + fn read_u16(buf: &[u8]) -> u16; + + fn read_u32(buf: &[u8]) -> u32; + + fn read_u64(buf: &[u8]) -> u64; + + fn write_u16(buf: &mut [u8], n: u16); + + fn write_u32(buf: &mut [u8], n: u32); + + fn write_u64(buf: &mut [u8], n: u64); + + #[inline] + fn read_i16(buf: &[u8]) -> i16 { + Self::read_u16(buf) as i16 + } + + #[inline] + fn read_i32(buf: &[u8]) -> i32 { + Self::read_u32(buf) as i32 + } + + #[inline] + fn read_i64(buf: &[u8]) -> i64 { + Self::read_u64(buf) as i64 + } + + #[inline] + fn read_f32(buf: &[u8]) -> f32 { + unsafe { *(&Self::read_u32(buf) as *const u32 as *const f32) } + } + + #[inline] + fn read_f64(buf: &[u8]) -> f64 { + unsafe { *(&Self::read_u64(buf) as *const u64 as *const f64) } + } + + #[inline] + fn write_i16(buf: &mut [u8], n: i16) { + Self::write_u16(buf, n as u16) + } + + #[inline] + fn write_i32(buf: &mut [u8], n: i32) { + Self::write_u32(buf, n as u32) + } + + #[inline] + fn write_i64(buf: &mut [u8], n: i64) { + Self::write_u64(buf, n as u64) + } + + #[inline] + fn write_f32(buf: &mut [u8], n: f32) { + let n = unsafe { *(&n as *const f32 as *const u32) }; + Self::write_u32(buf, n) + } + + #[inline] + fn write_f64(buf: &mut [u8], n: f64) { + let n = unsafe { *(&n as *const f64 as *const u64) }; + Self::write_u64(buf, n) + } + + serde_if_integer128! { + fn read_u128(buf: &[u8]) -> u128; + fn write_u128(buf: &mut [u8], n: u128); + + #[inline] + fn read_i128(buf: &[u8]) -> i128 { + Self::read_u128(buf) as i128 + } + + #[inline] + fn write_i128(buf: &mut [u8], n: i128) { + Self::write_u128(buf, n as u128) + } + } +} + +pub trait ReadBytesExt: io::Read { + #[inline] + fn read_u8(&mut self) -> Result { + let mut buf = [0; 1]; + try!(self.read_exact(&mut buf)); + Ok(buf[0]) + } + + #[inline] + fn read_i8(&mut self) -> Result { + let mut buf = [0; 1]; + try!(self.read_exact(&mut buf)); + Ok(buf[0] as i8) + } + + #[inline] + fn read_u16(&mut self) -> Result { + let mut buf = [0; 2]; + try!(self.read_exact(&mut buf)); + Ok(T::read_u16(&buf)) + } + + #[inline] + fn read_i16(&mut self) -> Result { + let mut buf = [0; 2]; + try!(self.read_exact(&mut buf)); + Ok(T::read_i16(&buf)) + } + + #[inline] + fn read_u32(&mut self) -> Result { + let mut buf = [0; 4]; + try!(self.read_exact(&mut buf)); + Ok(T::read_u32(&buf)) + } + + #[inline] + fn read_i32(&mut self) -> Result { + let mut buf = [0; 4]; + try!(self.read_exact(&mut buf)); + Ok(T::read_i32(&buf)) + } + + #[inline] + fn read_u64(&mut self) -> Result { + let mut buf = [0; 8]; + try!(self.read_exact(&mut buf)); + Ok(T::read_u64(&buf)) + } + + #[inline] + fn read_i64(&mut self) -> Result { + let mut buf = [0; 8]; + try!(self.read_exact(&mut buf)); + Ok(T::read_i64(&buf)) + } + + #[inline] + fn read_f32(&mut self) -> Result { + let mut buf = [0; 4]; + try!(self.read_exact(&mut buf)); + Ok(T::read_f32(&buf)) + } + + #[inline] + fn read_f64(&mut self) -> Result { + let mut buf = [0; 8]; + try!(self.read_exact(&mut buf)); + Ok(T::read_f64(&buf)) + } + + serde_if_integer128! { + #[inline] + fn read_u128(&mut self) -> Result { + let mut buf = [0; 16]; + try!(self.read_exact(&mut buf)); + Ok(T::read_u128(&buf)) + } + + #[inline] + fn read_i128(&mut self) -> Result { + let mut buf = [0; 16]; + try!(self.read_exact(&mut buf)); + Ok(T::read_i128(&buf)) + } + } +} + +impl ReadBytesExt for R {} + +pub trait WriteBytesExt: io::Write { + #[inline] + fn write_u8(&mut self, n: u8) -> Result<()> { + self.write_all(&[n]) + } + + #[inline] + fn write_i8(&mut self, n: i8) -> Result<()> { + self.write_all(&[n as u8]) + } + + #[inline] + fn write_u16(&mut self, n: u16) -> Result<()> { + let mut buf = [0; 2]; + T::write_u16(&mut buf, n); + self.write_all(&buf) + } + + #[inline] + fn write_i16(&mut self, n: i16) -> Result<()> { + let mut buf = [0; 2]; + T::write_i16(&mut buf, n); + self.write_all(&buf) + } + + #[inline] + fn write_u32(&mut self, n: u32) -> Result<()> { + let mut buf = [0; 4]; + T::write_u32(&mut buf, n); + self.write_all(&buf) + } + + #[inline] + fn write_i32(&mut self, n: i32) -> Result<()> { + let mut buf = [0; 4]; + T::write_i32(&mut buf, n); + self.write_all(&buf) + } + + #[inline] + fn write_u64(&mut self, n: u64) -> Result<()> { + let mut buf = [0; 8]; + T::write_u64(&mut buf, n); + self.write_all(&buf) + } + + #[inline] + fn write_i64(&mut self, n: i64) -> Result<()> { + let mut buf = [0; 8]; + T::write_i64(&mut buf, n); + self.write_all(&buf) + } + + #[inline] + fn write_f32(&mut self, n: f32) -> Result<()> { + let mut buf = [0; 4]; + T::write_f32(&mut buf, n); + self.write_all(&buf) + } + + #[inline] + fn write_f64(&mut self, n: f64) -> Result<()> { + let mut buf = [0; 8]; + T::write_f64(&mut buf, n); + self.write_all(&buf) + } + + serde_if_integer128! { + #[inline] + fn write_u128(&mut self, n: u128) -> Result<()> { + let mut buf = [0; 16]; + T::write_u128(&mut buf, n); + self.write_all(&buf) + } + + #[inline] + fn write_i128(&mut self, n: i128) -> Result<()> { + let mut buf = [0; 16]; + T::write_i128(&mut buf, n); + self.write_all(&buf) + } + } +} + +impl WriteBytesExt for W {} diff --git a/third_party/rust/bincode/src/config/endian.rs b/third_party/rust/bincode/src/config/endian.rs new file mode 100644 index 0000000000..2561620a2f --- /dev/null +++ b/third_party/rust/bincode/src/config/endian.rs @@ -0,0 +1,27 @@ +pub trait BincodeByteOrder { + type Endian: ::byteorder::ByteOrder + 'static; +} + +/// Little-endian byte ordering. +#[derive(Copy, Clone)] +pub struct LittleEndian; + +/// Big-endian byte ordering. +#[derive(Copy, Clone)] +pub struct BigEndian; + +/// The native byte ordering of the current system. +#[derive(Copy, Clone)] +pub struct NativeEndian; + +impl BincodeByteOrder for LittleEndian { + type Endian = ::byteorder::LittleEndian; +} + +impl BincodeByteOrder for BigEndian { + type Endian = ::byteorder::BigEndian; +} + +impl BincodeByteOrder for NativeEndian { + type Endian = ::byteorder::NativeEndian; +} diff --git a/third_party/rust/bincode/src/config/int.rs b/third_party/rust/bincode/src/config/int.rs new file mode 100644 index 0000000000..f716d1abdc --- /dev/null +++ b/third_party/rust/bincode/src/config/int.rs @@ -0,0 +1,682 @@ +use std::io::Write; +use std::mem::size_of; + +use super::Options; +use de::read::BincodeRead; +use error::{ErrorKind, Result}; + +pub trait IntEncoding { + /// Gets the size (in bytes) that a value would be serialized to. + fn u16_size(n: u16) -> u64; + /// Gets the size (in bytes) that a value would be serialized to. + fn u32_size(n: u32) -> u64; + /// Gets the size (in bytes) that a value would be serialized to. + fn u64_size(n: u64) -> u64; + + /// Gets the size (in bytes) that a value would be serialized to. + fn i16_size(n: i16) -> u64; + /// Gets the size (in bytes) that a value would be serialized to. + fn i32_size(n: i32) -> u64; + /// Gets the size (in bytes) that a value would be serialized to. + fn i64_size(n: i64) -> u64; + + #[inline(always)] + fn len_size(len: usize) -> u64 { + Self::u64_size(len as u64) + } + + /// Serializes a sequence length. + #[inline(always)] + fn serialize_len( + ser: &mut ::ser::Serializer, + len: usize, + ) -> Result<()> { + Self::serialize_u64(ser, len as u64) + } + + fn serialize_u16( + ser: &mut ::ser::Serializer, + val: u16, + ) -> Result<()>; + + fn serialize_u32( + ser: &mut ::ser::Serializer, + val: u32, + ) -> Result<()>; + + fn serialize_u64( + ser: &mut ::ser::Serializer, + val: u64, + ) -> Result<()>; + + fn serialize_i16( + ser: &mut ::ser::Serializer, + val: i16, + ) -> Result<()>; + + fn serialize_i32( + ser: &mut ::ser::Serializer, + val: i32, + ) -> Result<()>; + + fn serialize_i64( + ser: &mut ::ser::Serializer, + val: i64, + ) -> Result<()>; + + /// Deserializes a sequence length. + #[inline(always)] + fn deserialize_len<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::de::Deserializer, + ) -> Result { + Self::deserialize_u64(de).and_then(cast_u64_to_usize) + } + + fn deserialize_u16<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::de::Deserializer, + ) -> Result; + + fn deserialize_u32<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::de::Deserializer, + ) -> Result; + + fn deserialize_u64<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::de::Deserializer, + ) -> Result; + + fn deserialize_i16<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::de::Deserializer, + ) -> Result; + + fn deserialize_i32<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::de::Deserializer, + ) -> Result; + + fn deserialize_i64<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::de::Deserializer, + ) -> Result; + + serde_if_integer128! { + fn u128_size(v: u128) -> u64; + fn i128_size(v: i128) -> u64; + fn serialize_u128( + ser: &mut ::Serializer, + val: u128, + ) -> Result<()>; + fn deserialize_u128<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::Deserializer, + ) -> Result; + fn serialize_i128( + ser: &mut ::Serializer, + val: i128, + ) -> Result<()>; + fn deserialize_i128<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::Deserializer, + ) -> Result; + } +} + +/// Fixed-size integer encoding. +/// +/// * Fixed size integers are encoded directly +/// * Enum discriminants are encoded as u32 +/// * Lengths and usize are encoded as u64 +#[derive(Copy, Clone)] +pub struct FixintEncoding; + +/// Variable-size integer encoding (excepting [ui]8). +/// +/// Encoding an unsigned integer v (of any type excepting u8) works as follows: +/// +/// 1. If `u < 251`, encode it as a single byte with that value. +/// 2. If `251 <= u < 2**16`, encode it as a literal byte 251, followed by a u16 with value `u`. +/// 3. If `2**16 <= u < 2**32`, encode it as a literal byte 252, followed by a u32 with value `u`. +/// 4. If `2**32 <= u < 2**64`, encode it as a literal byte 253, followed by a u64 with value `u`. +/// 5. If `2**64 <= u < 2**128`, encode it as a literal byte 254, followed by a +/// u128 with value `u`. +/// +/// Then, for signed integers, we first convert to unsigned using the zigzag algorithm, +/// and then encode them as we do for unsigned integers generally. The reason we use this +/// algorithm is that it encodes those values which are close to zero in less bytes; the +/// obvious algorithm, where we encode the cast values, gives a very large encoding for all +/// negative values. +/// +/// The zigzag algorithm is defined as follows: +/// +/// ```ignore +/// fn zigzag(v: Signed) -> Unsigned { +/// match v { +/// 0 => 0, +/// v if v < 0 => |v| * 2 - 1 +/// v if v > 0 => v * 2 +/// } +/// } +/// ``` +/// +/// And works such that: +/// +/// ```ignore +/// assert_eq!(zigzag(0), 0); +/// assert_eq!(zigzag(-1), 1); +/// assert_eq!(zigzag(1), 2); +/// assert_eq!(zigzag(-2), 3); +/// assert_eq!(zigzag(2), 4); +/// assert_eq!(zigzag(i64::min_value()), u64::max_value()); +/// ``` +/// +/// Note that u256 and the like are unsupported by this format; if and when they are added to the +/// language, they may be supported via the extension point given by the 255 byte. +#[derive(Copy, Clone)] +pub struct VarintEncoding; + +const SINGLE_BYTE_MAX: u8 = 250; +const U16_BYTE: u8 = 251; +const U32_BYTE: u8 = 252; +const U64_BYTE: u8 = 253; +const U128_BYTE: u8 = 254; +const DESERIALIZE_EXTENSION_POINT_ERR: &str = r#" +Byte 255 is treated as an extension point; it should not be encoding anything. +Do you have a mismatched bincode version or configuration? +"#; + +impl VarintEncoding { + fn varint_size(n: u64) -> u64 { + if n <= SINGLE_BYTE_MAX as u64 { + 1 + } else if n <= u16::max_value() as u64 { + (1 + size_of::()) as u64 + } else if n <= u32::max_value() as u64 { + (1 + size_of::()) as u64 + } else { + (1 + size_of::()) as u64 + } + } + + #[inline(always)] + fn zigzag_encode(n: i64) -> u64 { + if n < 0 { + // let's avoid the edge case of i64::min_value() + // !n is equal to `-n - 1`, so this is: + // !n * 2 + 1 = 2(-n - 1) + 1 = -2n - 2 + 1 = -2n - 1 + !(n as u64) * 2 + 1 + } else { + (n as u64) * 2 + } + } + + #[inline(always)] + fn zigzag_decode(n: u64) -> i64 { + if n % 2 == 0 { + // positive number + (n / 2) as i64 + } else { + // negative number + // !m * 2 + 1 = n + // !m * 2 = n - 1 + // !m = (n - 1) / 2 + // m = !((n - 1) / 2) + // since we have n is odd, we have floor(n / 2) = floor((n - 1) / 2) + !(n / 2) as i64 + } + } + + fn serialize_varint( + ser: &mut ::ser::Serializer, + n: u64, + ) -> Result<()> { + if n <= SINGLE_BYTE_MAX as u64 { + ser.serialize_byte(n as u8) + } else if n <= u16::max_value() as u64 { + ser.serialize_byte(U16_BYTE)?; + ser.serialize_literal_u16(n as u16) + } else if n <= u32::max_value() as u64 { + ser.serialize_byte(U32_BYTE)?; + ser.serialize_literal_u32(n as u32) + } else { + ser.serialize_byte(U64_BYTE)?; + ser.serialize_literal_u64(n as u64) + } + } + + fn deserialize_varint<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::de::Deserializer, + ) -> Result { + #[allow(ellipsis_inclusive_range_patterns)] + match de.deserialize_byte()? { + byte @ 0...SINGLE_BYTE_MAX => Ok(byte as u64), + U16_BYTE => Ok(de.deserialize_literal_u16()? as u64), + U32_BYTE => Ok(de.deserialize_literal_u32()? as u64), + U64_BYTE => de.deserialize_literal_u64(), + U128_BYTE => Err(Box::new(ErrorKind::Custom( + "Invalid value (u128 range): you may have a version or configuration disagreement?" + .to_string(), + ))), + _ => Err(Box::new(ErrorKind::Custom( + DESERIALIZE_EXTENSION_POINT_ERR.to_string(), + ))), + } + } + + serde_if_integer128! { + // see zigzag_encode and zigzag_decode for implementation comments + #[inline(always)] + fn zigzag128_encode(n: i128) -> u128 { + if n < 0 { + !(n as u128) * 2 + 1 + } else { + (n as u128) * 2 + } + } + #[inline(always)] + fn zigzag128_decode(n: u128) -> i128 { + if n % 2 == 0 { + (n / 2) as i128 + } else { + !(n / 2) as i128 + } + } + + fn varint128_size(n: u128) -> u64 { + if n <= SINGLE_BYTE_MAX as u128 { + 1 + } else if n <= u16::max_value() as u128 { + (1 + size_of::()) as u64 + } else if n <= u32::max_value() as u128 { + (1 + size_of::()) as u64 + } else if n <= u64::max_value() as u128 { + (1 + size_of::()) as u64 + } else { + (1 + size_of::()) as u64 + } + } + + fn serialize_varint128( + ser: &mut ::ser::Serializer, + n: u128, + ) -> Result<()> { + if n <= SINGLE_BYTE_MAX as u128 { + ser.serialize_byte(n as u8) + } else if n <= u16::max_value() as u128 { + ser.serialize_byte(U16_BYTE)?; + ser.serialize_literal_u16(n as u16) + } else if n <= u32::max_value() as u128 { + ser.serialize_byte(U32_BYTE)?; + ser.serialize_literal_u32(n as u32) + } else if n <= u64::max_value() as u128 { + ser.serialize_byte(U64_BYTE)?; + ser.serialize_literal_u64(n as u64) + } else { + ser.serialize_byte(U128_BYTE)?; + ser.serialize_literal_u128(n) + } + } + + fn deserialize_varint128<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::de::Deserializer, + ) -> Result { + #[allow(ellipsis_inclusive_range_patterns)] + match de.deserialize_byte()? { + byte @ 0...SINGLE_BYTE_MAX => Ok(byte as u128), + U16_BYTE => Ok(de.deserialize_literal_u16()? as u128), + U32_BYTE => Ok(de.deserialize_literal_u32()? as u128), + U64_BYTE => Ok(de.deserialize_literal_u64()? as u128), + U128_BYTE => de.deserialize_literal_u128(), + _ => Err(Box::new(ErrorKind::Custom(DESERIALIZE_EXTENSION_POINT_ERR.to_string()))), + } + } + } +} + +impl IntEncoding for FixintEncoding { + #[inline(always)] + fn u16_size(_: u16) -> u64 { + size_of::() as u64 + } + #[inline(always)] + fn u32_size(_: u32) -> u64 { + size_of::() as u64 + } + #[inline(always)] + fn u64_size(_: u64) -> u64 { + size_of::() as u64 + } + + #[inline(always)] + fn i16_size(_: i16) -> u64 { + size_of::() as u64 + } + #[inline(always)] + fn i32_size(_: i32) -> u64 { + size_of::() as u64 + } + #[inline(always)] + fn i64_size(_: i64) -> u64 { + size_of::() as u64 + } + + #[inline(always)] + fn serialize_u16(ser: &mut ::Serializer, val: u16) -> Result<()> { + ser.serialize_literal_u16(val) + } + #[inline(always)] + fn serialize_u32(ser: &mut ::Serializer, val: u32) -> Result<()> { + ser.serialize_literal_u32(val) + } + #[inline(always)] + fn serialize_u64(ser: &mut ::Serializer, val: u64) -> Result<()> { + ser.serialize_literal_u64(val) + } + + #[inline(always)] + fn serialize_i16(ser: &mut ::Serializer, val: i16) -> Result<()> { + ser.serialize_literal_u16(val as u16) + } + #[inline(always)] + fn serialize_i32(ser: &mut ::Serializer, val: i32) -> Result<()> { + ser.serialize_literal_u32(val as u32) + } + #[inline(always)] + fn serialize_i64(ser: &mut ::Serializer, val: i64) -> Result<()> { + ser.serialize_literal_u64(val as u64) + } + + #[inline(always)] + fn deserialize_u16<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::Deserializer, + ) -> Result { + de.deserialize_literal_u16() + } + #[inline(always)] + fn deserialize_u32<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::Deserializer, + ) -> Result { + de.deserialize_literal_u32() + } + #[inline(always)] + fn deserialize_u64<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::Deserializer, + ) -> Result { + de.deserialize_literal_u64() + } + + #[inline(always)] + fn deserialize_i16<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::Deserializer, + ) -> Result { + Ok(de.deserialize_literal_u16()? as i16) + } + #[inline(always)] + fn deserialize_i32<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::Deserializer, + ) -> Result { + Ok(de.deserialize_literal_u32()? as i32) + } + #[inline(always)] + fn deserialize_i64<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::Deserializer, + ) -> Result { + Ok(de.deserialize_literal_u64()? as i64) + } + + serde_if_integer128! { + #[inline(always)] + fn u128_size(_: u128) -> u64{ + size_of::() as u64 + } + #[inline(always)] + fn i128_size(_: i128) -> u64{ + size_of::() as u64 + } + + #[inline(always)] + fn serialize_u128( + ser: &mut ::Serializer, + val: u128, + ) -> Result<()> { + ser.serialize_literal_u128(val) + } + #[inline(always)] + fn serialize_i128( + ser: &mut ::Serializer, + val: i128, + ) -> Result<()> { + ser.serialize_literal_u128(val as u128) + } + #[inline(always)] + fn deserialize_u128<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::Deserializer, + ) -> Result { + de.deserialize_literal_u128() + } + #[inline(always)] + fn deserialize_i128<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::Deserializer, + ) -> Result { + Ok(de.deserialize_literal_u128()? as i128) + } + } +} + +impl IntEncoding for VarintEncoding { + #[inline(always)] + fn u16_size(n: u16) -> u64 { + Self::varint_size(n as u64) + } + #[inline(always)] + fn u32_size(n: u32) -> u64 { + Self::varint_size(n as u64) + } + #[inline(always)] + fn u64_size(n: u64) -> u64 { + Self::varint_size(n) + } + + #[inline(always)] + fn i16_size(n: i16) -> u64 { + Self::varint_size(Self::zigzag_encode(n as i64)) + } + #[inline(always)] + fn i32_size(n: i32) -> u64 { + Self::varint_size(Self::zigzag_encode(n as i64)) + } + #[inline(always)] + fn i64_size(n: i64) -> u64 { + Self::varint_size(Self::zigzag_encode(n)) + } + + #[inline(always)] + fn serialize_u16(ser: &mut ::Serializer, val: u16) -> Result<()> { + Self::serialize_varint(ser, val as u64) + } + #[inline(always)] + fn serialize_u32(ser: &mut ::Serializer, val: u32) -> Result<()> { + Self::serialize_varint(ser, val as u64) + } + #[inline(always)] + fn serialize_u64(ser: &mut ::Serializer, val: u64) -> Result<()> { + Self::serialize_varint(ser, val) + } + + #[inline(always)] + fn serialize_i16(ser: &mut ::Serializer, val: i16) -> Result<()> { + Self::serialize_varint(ser, Self::zigzag_encode(val as i64)) + } + #[inline(always)] + fn serialize_i32(ser: &mut ::Serializer, val: i32) -> Result<()> { + Self::serialize_varint(ser, Self::zigzag_encode(val as i64)) + } + #[inline(always)] + fn serialize_i64(ser: &mut ::Serializer, val: i64) -> Result<()> { + Self::serialize_varint(ser, Self::zigzag_encode(val)) + } + + #[inline(always)] + fn deserialize_u16<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::Deserializer, + ) -> Result { + Self::deserialize_varint(de).and_then(cast_u64_to_u16) + } + #[inline(always)] + fn deserialize_u32<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::Deserializer, + ) -> Result { + Self::deserialize_varint(de).and_then(cast_u64_to_u32) + } + #[inline(always)] + fn deserialize_u64<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::Deserializer, + ) -> Result { + Self::deserialize_varint(de) + } + + #[inline(always)] + fn deserialize_i16<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::Deserializer, + ) -> Result { + Self::deserialize_varint(de) + .map(Self::zigzag_decode) + .and_then(cast_i64_to_i16) + } + #[inline(always)] + fn deserialize_i32<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::Deserializer, + ) -> Result { + Self::deserialize_varint(de) + .map(Self::zigzag_decode) + .and_then(cast_i64_to_i32) + } + #[inline(always)] + fn deserialize_i64<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::Deserializer, + ) -> Result { + Self::deserialize_varint(de).map(Self::zigzag_decode) + } + + serde_if_integer128! { + #[inline(always)] + fn u128_size(n: u128) -> u64 { + Self::varint128_size(n) + } + #[inline(always)] + fn i128_size(n: i128) -> u64 { + Self::varint128_size(Self::zigzag128_encode(n)) + } + #[inline(always)] + fn serialize_u128( + ser: &mut ::Serializer, + val: u128, + ) -> Result<()> { + Self::serialize_varint128(ser, val) + } + #[inline(always)] + fn serialize_i128( + ser: &mut ::Serializer, + val: i128, + ) -> Result<()> { + Self::serialize_varint128(ser, Self::zigzag128_encode(val)) + } + #[inline(always)] + fn deserialize_u128<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::Deserializer, + ) -> Result { + Self::deserialize_varint128(de) + } + #[inline(always)] + fn deserialize_i128<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::Deserializer, + ) -> Result { + Self::deserialize_varint128(de).map(Self::zigzag128_decode) + } + } +} + +fn cast_u64_to_usize(n: u64) -> Result { + if n <= usize::max_value() as u64 { + Ok(n as usize) + } else { + Err(Box::new(ErrorKind::Custom(format!( + "Invalid size {}: sizes must fit in a usize (0 to {})", + n, + usize::max_value() + )))) + } +} +fn cast_u64_to_u32(n: u64) -> Result { + if n <= u32::max_value() as u64 { + Ok(n as u32) + } else { + Err(Box::new(ErrorKind::Custom(format!( + "Invalid u32 {}: you may have a version disagreement?", + n, + )))) + } +} +fn cast_u64_to_u16(n: u64) -> Result { + if n <= u16::max_value() as u64 { + Ok(n as u16) + } else { + Err(Box::new(ErrorKind::Custom(format!( + "Invalid u16 {}: you may have a version disagreement?", + n, + )))) + } +} + +fn cast_i64_to_i32(n: i64) -> Result { + if n <= i32::max_value() as i64 && n >= i32::min_value() as i64 { + Ok(n as i32) + } else { + Err(Box::new(ErrorKind::Custom(format!( + "Invalid i32 {}: you may have a version disagreement?", + n, + )))) + } +} + +fn cast_i64_to_i16(n: i64) -> Result { + if n <= i16::max_value() as i64 && n >= i16::min_value() as i64 { + Ok(n as i16) + } else { + Err(Box::new(ErrorKind::Custom(format!( + "Invalid i16 {}: you may have a version disagreement?", + n, + )))) + } +} + +#[cfg(test)] +mod test { + use super::VarintEncoding; + + #[test] + fn test_zigzag_encode() { + let zigzag = VarintEncoding::zigzag_encode; + + assert_eq!(zigzag(0), 0); + for x in 1..512 { + assert_eq!(zigzag(x), (x as u64) * 2); + assert_eq!(zigzag(-x), (x as u64) * 2 - 1); + } + } + + #[test] + fn test_zigzag_decode() { + // zigzag' + let zigzagp = VarintEncoding::zigzag_decode; + for x in (0..512).map(|x| x * 2) { + assert_eq!(zigzagp(x), x as i64 / 2); + assert_eq!(zigzagp(x + 1), -(x as i64) / 2 - 1); + } + } + + #[test] + fn test_zigzag_edge_cases() { + let (zigzag, zigzagp) = (VarintEncoding::zigzag_encode, VarintEncoding::zigzag_decode); + + assert_eq!(zigzag(i64::max_value()), u64::max_value() - 1); + assert_eq!(zigzag(i64::min_value()), u64::max_value()); + + assert_eq!(zigzagp(u64::max_value() - 1), i64::max_value()); + assert_eq!(zigzagp(u64::max_value()), i64::min_value()); + } +} diff --git a/third_party/rust/bincode/src/config/legacy.rs b/third_party/rust/bincode/src/config/legacy.rs new file mode 100644 index 0000000000..ec5c7f0449 --- /dev/null +++ b/third_party/rust/bincode/src/config/legacy.rs @@ -0,0 +1,253 @@ +use std::io::{Read, Write}; + +use self::EndianOption::*; +use self::LimitOption::*; +use super::{DefaultOptions, Options}; +use de::read::BincodeRead; +use error::Result; +use serde; + +/// A configuration builder whose options Bincode will use +/// while serializing and deserializing. +/// +/// ### Options +/// Endianness: The endianness with which multi-byte integers will be read/written. *default: little endian* +/// Limit: The maximum number of bytes that will be read/written in a bincode serialize/deserialize. *default: unlimited* +/// +/// ### Byte Limit Details +/// The purpose of byte-limiting is to prevent Denial-Of-Service attacks whereby malicious attackers get bincode +/// deserialization to crash your process by allocating too much memory or keeping a connection open for too long. +/// +/// When a byte limit is set, bincode will return `Err` on any deserialization that goes over the limit, or any +/// serialization that goes over the limit. +#[derive(Clone, Debug)] +#[deprecated( + since = "1.3.0", + note = "please use the `DefaultOptions`/`Options` system instead" +)] +pub struct Config { + limit: LimitOption, + endian: EndianOption, +} + +#[derive(Clone, Copy, Debug)] +enum LimitOption { + Unlimited, + Limited(u64), +} + +#[derive(Clone, Copy, Debug)] +enum EndianOption { + Big, + Little, + Native, +} + +macro_rules! config_map { + ($self:expr, $opts:ident => $call:expr) => { + match ($self.limit, $self.endian) { + (Unlimited, Little) => { + let $opts = DefaultOptions::new() + .with_fixint_encoding() + .allow_trailing_bytes() + .with_no_limit() + .with_little_endian(); + $call + } + (Unlimited, Big) => { + let $opts = DefaultOptions::new() + .with_fixint_encoding() + .allow_trailing_bytes() + .with_no_limit() + .with_big_endian(); + $call + } + (Unlimited, Native) => { + let $opts = DefaultOptions::new() + .with_fixint_encoding() + .allow_trailing_bytes() + .with_no_limit() + .with_native_endian(); + $call + } + + (Limited(l), Little) => { + let $opts = DefaultOptions::new() + .with_fixint_encoding() + .allow_trailing_bytes() + .with_limit(l) + .with_little_endian(); + $call + } + (Limited(l), Big) => { + let $opts = DefaultOptions::new() + .with_fixint_encoding() + .allow_trailing_bytes() + .with_limit(l) + .with_big_endian(); + $call + } + (Limited(l), Native) => { + let $opts = DefaultOptions::new() + .with_fixint_encoding() + .allow_trailing_bytes() + .with_limit(l) + .with_native_endian(); + $call + } + } + }; +} + +impl Config { + #[inline(always)] + pub(crate) fn new() -> Config { + Config { + limit: LimitOption::Unlimited, + endian: EndianOption::Little, + } + } + + /// Sets the byte limit to be unlimited. + /// This is the default. + #[inline(always)] + pub fn no_limit(&mut self) -> &mut Self { + self.limit = LimitOption::Unlimited; + self + } + + /// Sets the byte limit to `limit`. + #[inline(always)] + pub fn limit(&mut self, limit: u64) -> &mut Self { + self.limit = LimitOption::Limited(limit); + self + } + + /// Sets the endianness to little-endian + /// This is the default. + #[inline(always)] + pub fn little_endian(&mut self) -> &mut Self { + self.endian = EndianOption::Little; + self + } + + /// Sets the endianness to big-endian + #[inline(always)] + pub fn big_endian(&mut self) -> &mut Self { + self.endian = EndianOption::Big; + self + } + + /// Sets the endianness to the the machine-native endianness + #[inline(always)] + pub fn native_endian(&mut self) -> &mut Self { + self.endian = EndianOption::Native; + self + } + + /// Serializes a serializable object into a `Vec` of bytes using this configuration + #[inline(always)] + pub fn serialize(&self, t: &T) -> Result> { + config_map!(self, opts => ::internal::serialize(t, opts)) + } + + /// Returns the size that an object would be if serialized using Bincode with this configuration + #[inline(always)] + pub fn serialized_size(&self, t: &T) -> Result { + config_map!(self, opts => ::internal::serialized_size(t, opts)) + } + + /// Serializes an object directly into a `Writer` using this configuration + /// + /// If the serialization would take more bytes than allowed by the size limit, an error + /// is returned and *no bytes* will be written into the `Writer` + #[inline(always)] + pub fn serialize_into( + &self, + w: W, + t: &T, + ) -> Result<()> { + config_map!(self, opts => ::internal::serialize_into(w, t, opts)) + } + + /// Deserializes a slice of bytes into an instance of `T` using this configuration + #[inline(always)] + pub fn deserialize<'a, T: serde::Deserialize<'a>>(&self, bytes: &'a [u8]) -> Result { + config_map!(self, opts => ::internal::deserialize(bytes, opts)) + } + + /// TODO: document + #[doc(hidden)] + #[inline(always)] + pub fn deserialize_in_place<'a, R, T>(&self, reader: R, place: &mut T) -> Result<()> + where + R: BincodeRead<'a>, + T: serde::de::Deserialize<'a>, + { + config_map!(self, opts => ::internal::deserialize_in_place(reader, opts, place)) + } + + /// Deserializes a slice of bytes with state `seed` using this configuration. + #[inline(always)] + pub fn deserialize_seed<'a, T: serde::de::DeserializeSeed<'a>>( + &self, + seed: T, + bytes: &'a [u8], + ) -> Result { + config_map!(self, opts => ::internal::deserialize_seed(seed, bytes, opts)) + } + + /// Deserializes an object directly from a `Read`er using this configuration + /// + /// If this returns an `Error`, `reader` may be in an invalid state. + #[inline(always)] + pub fn deserialize_from( + &self, + reader: R, + ) -> Result { + config_map!(self, opts => ::internal::deserialize_from(reader, opts)) + } + + /// Deserializes an object directly from a `Read`er with state `seed` using this configuration + /// + /// If this returns an `Error`, `reader` may be in an invalid state. + #[inline(always)] + pub fn deserialize_from_seed<'a, R: Read, T: serde::de::DeserializeSeed<'a>>( + &self, + seed: T, + reader: R, + ) -> Result { + config_map!(self, opts => ::internal::deserialize_from_seed(seed, reader, opts)) + } + + /// Deserializes an object from a custom `BincodeRead`er using the default configuration. + /// It is highly recommended to use `deserialize_from` unless you need to implement + /// `BincodeRead` for performance reasons. + /// + /// If this returns an `Error`, `reader` may be in an invalid state. + #[inline(always)] + pub fn deserialize_from_custom<'a, R: BincodeRead<'a>, T: serde::de::DeserializeOwned>( + &self, + reader: R, + ) -> Result { + config_map!(self, opts => ::internal::deserialize_from_custom(reader, opts)) + } + + /// Deserializes an object from a custom `BincodeRead`er with state `seed` using the default + /// configuration. It is highly recommended to use `deserialize_from` unless you need to + /// implement `BincodeRead` for performance reasons. + /// + /// If this returns an `Error`, `reader` may be in an invalid state. + #[inline(always)] + pub fn deserialize_from_custom_seed< + 'a, + R: BincodeRead<'a>, + T: serde::de::DeserializeSeed<'a>, + >( + &self, + seed: T, + reader: R, + ) -> Result { + config_map!(self, opts => ::internal::deserialize_from_custom_seed(seed, reader, opts)) + } +} diff --git a/third_party/rust/bincode/src/config/limit.rs b/third_party/rust/bincode/src/config/limit.rs new file mode 100644 index 0000000000..477229830b --- /dev/null +++ b/third_party/rust/bincode/src/config/limit.rs @@ -0,0 +1,49 @@ +use error::{ErrorKind, Result}; + +/// A trait for stopping serialization and deserialization when a certain limit has been reached. +pub trait SizeLimit { + /// Tells the SizeLimit that a certain number of bytes has been + /// read or written. Returns Err if the limit has been exceeded. + fn add(&mut self, n: u64) -> Result<()>; + /// Returns the hard limit (if one exists) + fn limit(&self) -> Option; +} + +/// A SizeLimit that restricts serialized or deserialized messages from +/// exceeding a certain byte length. +#[derive(Copy, Clone)] +pub struct Bounded(pub u64); + +/// A SizeLimit without a limit! +/// Use this if you don't care about the size of encoded or decoded messages. +#[derive(Copy, Clone)] +pub struct Infinite; + +impl SizeLimit for Bounded { + #[inline(always)] + fn add(&mut self, n: u64) -> Result<()> { + if self.0 >= n { + self.0 -= n; + Ok(()) + } else { + Err(Box::new(ErrorKind::SizeLimit)) + } + } + + #[inline(always)] + fn limit(&self) -> Option { + Some(self.0) + } +} + +impl SizeLimit for Infinite { + #[inline(always)] + fn add(&mut self, _: u64) -> Result<()> { + Ok(()) + } + + #[inline(always)] + fn limit(&self) -> Option { + None + } +} diff --git a/third_party/rust/bincode/src/config/mod.rs b/third_party/rust/bincode/src/config/mod.rs new file mode 100644 index 0000000000..33fa920083 --- /dev/null +++ b/third_party/rust/bincode/src/config/mod.rs @@ -0,0 +1,408 @@ +//! `bincode` uses a Builder-pattern to configure the Serializers and Deserializers in this +//! crate. This means that if you need to customize the behavior of `bincode`, you should create an +//! instance of the `DefaultOptions` struct: +//! +//! ```rust +//! use bincode::Options; +//! let my_options = bincode::DefaultOptions::new(); +//! ``` +//! +//! # Options Struct vs bincode functions +//! +//! Due to historical reasons, the default options used by the `serialize()` and `deserialize()` +//! family of functions are different than the default options created by the `DefaultOptions` struct: +//! +//! | | Byte limit | Endianness | Int Encoding | Trailing Behavior | +//! |----------|------------|------------|--------------|-------------------| +//! | struct | Unlimited | Little | Varint | Reject | +//! | function | Unlimited | Little | Fixint | Allow | +//! +//! This means that if you want to use the `Serialize` / `Deserialize` structs with the same +//! settings as the functions, you should adjust the `DefaultOptions` struct like so: +//! +//! ```rust +//! use bincode::Options; +//! let my_options = bincode::DefaultOptions::new() +//! .with_fixint_encoding() +//! .allow_trailing_bytes(); +//! ``` + +use de::read::BincodeRead; +use error::Result; +use serde; +use std::io::{Read, Write}; +use std::marker::PhantomData; + +pub(crate) use self::endian::BincodeByteOrder; +pub(crate) use self::int::IntEncoding; +pub(crate) use self::internal::*; +pub(crate) use self::limit::SizeLimit; +pub(crate) use self::trailing::TrailingBytes; + +pub use self::endian::{BigEndian, LittleEndian, NativeEndian}; +pub use self::int::{FixintEncoding, VarintEncoding}; +pub use self::legacy::*; +pub use self::limit::{Bounded, Infinite}; +pub use self::trailing::{AllowTrailing, RejectTrailing}; + +mod endian; +mod int; +mod legacy; +mod limit; +mod trailing; + +/// The default options for bincode serialization/deserialization. +/// +/// ### Defaults +/// By default bincode will use little-endian encoding for multi-byte integers, and will not +/// limit the number of serialized/deserialized bytes. +/// +/// ### Configuring `DefaultOptions` +/// +/// `DefaultOptions` implements the [Options] trait, which means it exposes functions to change the behavior of bincode. +/// +/// For example, if you wanted to limit the bincode deserializer to 1 kilobyte of user input: +/// +/// ```rust +/// use bincode::Options; +/// let my_options = bincode::DefaultOptions::new().with_limit(1024); +/// ``` +/// +/// ### DefaultOptions struct vs. functions +/// +/// The default configuration used by this struct is not the same as that used by the bincode +/// helper functions in the root of this crate. See the +/// [config](index.html#options-struct-vs-bincode-functions) module for more details +#[derive(Copy, Clone)] +pub struct DefaultOptions(Infinite); + +impl DefaultOptions { + /// Get a default configuration object. + /// + /// ### Default Configuration: + /// + /// | Byte limit | Endianness | Int Encoding | Trailing Behavior | + /// |------------|------------|--------------|-------------------| + /// | Unlimited | Little | Varint | Reject | + pub fn new() -> DefaultOptions { + DefaultOptions(Infinite) + } +} + +impl Default for DefaultOptions { + fn default() -> Self { + Self::new() + } +} + +impl InternalOptions for DefaultOptions { + type Limit = Infinite; + type Endian = LittleEndian; + type IntEncoding = VarintEncoding; + type Trailing = RejectTrailing; + + #[inline(always)] + fn limit(&mut self) -> &mut Infinite { + &mut self.0 + } +} + +/// A configuration builder trait whose options Bincode will use +/// while serializing and deserializing. +/// +/// ### Options +/// Endianness: The endianness with which multi-byte integers will be read/written. *default: little endian* +/// +/// Limit: The maximum number of bytes that will be read/written in a bincode serialize/deserialize. *default: unlimited* +/// +/// Int Encoding: The encoding used for numbers, enum discriminants, and lengths. *default: varint* +/// +/// Trailing Behavior: The behavior when there are trailing bytes left over in a slice after deserialization. *default: reject* +/// +/// ### Byte Limit Details +/// The purpose of byte-limiting is to prevent Denial-Of-Service attacks whereby malicious attackers get bincode +/// deserialization to crash your process by allocating too much memory or keeping a connection open for too long. +/// +/// When a byte limit is set, bincode will return `Err` on any deserialization that goes over the limit, or any +/// serialization that goes over the limit. +pub trait Options: InternalOptions + Sized { + /// Sets the byte limit to be unlimited. + /// This is the default. + fn with_no_limit(self) -> WithOtherLimit { + WithOtherLimit::new(self, Infinite) + } + + /// Sets the byte limit to `limit`. + fn with_limit(self, limit: u64) -> WithOtherLimit { + WithOtherLimit::new(self, Bounded(limit)) + } + + /// Sets the endianness to little-endian + /// This is the default. + fn with_little_endian(self) -> WithOtherEndian { + WithOtherEndian::new(self) + } + + /// Sets the endianness to big-endian + fn with_big_endian(self) -> WithOtherEndian { + WithOtherEndian::new(self) + } + + /// Sets the endianness to the the machine-native endianness + fn with_native_endian(self) -> WithOtherEndian { + WithOtherEndian::new(self) + } + + /// Sets the length encoding to varint + fn with_varint_encoding(self) -> WithOtherIntEncoding { + WithOtherIntEncoding::new(self) + } + + /// Sets the length encoding to be fixed + fn with_fixint_encoding(self) -> WithOtherIntEncoding { + WithOtherIntEncoding::new(self) + } + + /// Sets the deserializer to reject trailing bytes + fn reject_trailing_bytes(self) -> WithOtherTrailing { + WithOtherTrailing::new(self) + } + + /// Sets the deserializer to allow trailing bytes + fn allow_trailing_bytes(self) -> WithOtherTrailing { + WithOtherTrailing::new(self) + } + + /// Serializes a serializable object into a `Vec` of bytes using this configuration + #[inline(always)] + fn serialize(self, t: &S) -> Result> { + ::internal::serialize(t, self) + } + + /// Returns the size that an object would be if serialized using Bincode with this configuration + #[inline(always)] + fn serialized_size(self, t: &T) -> Result { + ::internal::serialized_size(t, self) + } + + /// Serializes an object directly into a `Writer` using this configuration + /// + /// If the serialization would take more bytes than allowed by the size limit, an error + /// is returned and *no bytes* will be written into the `Writer` + #[inline(always)] + fn serialize_into(self, w: W, t: &T) -> Result<()> { + ::internal::serialize_into(w, t, self) + } + + /// Deserializes a slice of bytes into an instance of `T` using this configuration + #[inline(always)] + fn deserialize<'a, T: serde::Deserialize<'a>>(self, bytes: &'a [u8]) -> Result { + ::internal::deserialize(bytes, self) + } + + /// TODO: document + #[doc(hidden)] + #[inline(always)] + fn deserialize_in_place<'a, R, T>(self, reader: R, place: &mut T) -> Result<()> + where + R: BincodeRead<'a>, + T: serde::de::Deserialize<'a>, + { + ::internal::deserialize_in_place(reader, self, place) + } + + /// Deserializes a slice of bytes with state `seed` using this configuration. + #[inline(always)] + fn deserialize_seed<'a, T: serde::de::DeserializeSeed<'a>>( + self, + seed: T, + bytes: &'a [u8], + ) -> Result { + ::internal::deserialize_seed(seed, bytes, self) + } + + /// Deserializes an object directly from a `Read`er using this configuration + /// + /// If this returns an `Error`, `reader` may be in an invalid state. + #[inline(always)] + fn deserialize_from(self, reader: R) -> Result { + ::internal::deserialize_from(reader, self) + } + + /// Deserializes an object directly from a `Read`er with state `seed` using this configuration + /// + /// If this returns an `Error`, `reader` may be in an invalid state. + #[inline(always)] + fn deserialize_from_seed<'a, R: Read, T: serde::de::DeserializeSeed<'a>>( + self, + seed: T, + reader: R, + ) -> Result { + ::internal::deserialize_from_seed(seed, reader, self) + } + + /// Deserializes an object from a custom `BincodeRead`er using the default configuration. + /// It is highly recommended to use `deserialize_from` unless you need to implement + /// `BincodeRead` for performance reasons. + /// + /// If this returns an `Error`, `reader` may be in an invalid state. + #[inline(always)] + fn deserialize_from_custom<'a, R: BincodeRead<'a>, T: serde::de::DeserializeOwned>( + self, + reader: R, + ) -> Result { + ::internal::deserialize_from_custom(reader, self) + } + + /// Deserializes an object from a custom `BincodeRead`er with state `seed` using the default + /// configuration. It is highly recommended to use `deserialize_from` unless you need to + /// implement `BincodeRead` for performance reasons. + /// + /// If this returns an `Error`, `reader` may be in an invalid state. + #[inline(always)] + fn deserialize_from_custom_seed<'a, R: BincodeRead<'a>, T: serde::de::DeserializeSeed<'a>>( + self, + seed: T, + reader: R, + ) -> Result { + ::internal::deserialize_from_custom_seed(seed, reader, self) + } +} + +impl Options for T {} + +/// A configuration struct with a user-specified byte limit +#[derive(Clone, Copy)] +pub struct WithOtherLimit { + _options: O, + pub(crate) new_limit: L, +} + +/// A configuration struct with a user-specified endian order +#[derive(Clone, Copy)] +pub struct WithOtherEndian { + options: O, + _endian: PhantomData, +} + +/// A configuration struct with a user-specified length encoding +#[derive(Clone, Copy)] +pub struct WithOtherIntEncoding { + options: O, + _length: PhantomData, +} + +/// A configuration struct with a user-specified trailing bytes behavior. +#[derive(Clone, Copy)] +pub struct WithOtherTrailing { + options: O, + _trailing: PhantomData, +} + +impl WithOtherLimit { + #[inline(always)] + pub(crate) fn new(options: O, limit: L) -> WithOtherLimit { + WithOtherLimit { + _options: options, + new_limit: limit, + } + } +} + +impl WithOtherEndian { + #[inline(always)] + pub(crate) fn new(options: O) -> WithOtherEndian { + WithOtherEndian { + options, + _endian: PhantomData, + } + } +} + +impl WithOtherIntEncoding { + #[inline(always)] + pub(crate) fn new(options: O) -> WithOtherIntEncoding { + WithOtherIntEncoding { + options, + _length: PhantomData, + } + } +} + +impl WithOtherTrailing { + #[inline(always)] + pub(crate) fn new(options: O) -> WithOtherTrailing { + WithOtherTrailing { + options, + _trailing: PhantomData, + } + } +} + +impl InternalOptions for WithOtherEndian { + type Limit = O::Limit; + type Endian = E; + type IntEncoding = O::IntEncoding; + type Trailing = O::Trailing; + #[inline(always)] + fn limit(&mut self) -> &mut O::Limit { + self.options.limit() + } +} + +impl InternalOptions for WithOtherLimit { + type Limit = L; + type Endian = O::Endian; + type IntEncoding = O::IntEncoding; + type Trailing = O::Trailing; + fn limit(&mut self) -> &mut L { + &mut self.new_limit + } +} + +impl InternalOptions for WithOtherIntEncoding { + type Limit = O::Limit; + type Endian = O::Endian; + type IntEncoding = I; + type Trailing = O::Trailing; + + fn limit(&mut self) -> &mut O::Limit { + self.options.limit() + } +} + +impl InternalOptions for WithOtherTrailing { + type Limit = O::Limit; + type Endian = O::Endian; + type IntEncoding = O::IntEncoding; + type Trailing = T; + + fn limit(&mut self) -> &mut O::Limit { + self.options.limit() + } +} + +mod internal { + use super::*; + + pub trait InternalOptions { + type Limit: SizeLimit + 'static; + type Endian: BincodeByteOrder + 'static; + type IntEncoding: IntEncoding + 'static; + type Trailing: TrailingBytes + 'static; + + fn limit(&mut self) -> &mut Self::Limit; + } + + impl<'a, O: InternalOptions> InternalOptions for &'a mut O { + type Limit = O::Limit; + type Endian = O::Endian; + type IntEncoding = O::IntEncoding; + type Trailing = O::Trailing; + + #[inline(always)] + fn limit(&mut self) -> &mut Self::Limit { + (*self).limit() + } + } +} diff --git a/third_party/rust/bincode/src/config/trailing.rs b/third_party/rust/bincode/src/config/trailing.rs new file mode 100644 index 0000000000..6052fc7d78 --- /dev/null +++ b/third_party/rust/bincode/src/config/trailing.rs @@ -0,0 +1,37 @@ +use de::read::SliceReader; +use {ErrorKind, Result}; + +/// A trait for erroring deserialization if not all bytes were read. +pub trait TrailingBytes { + /// Checks a given slice reader to determine if deserialization used all bytes in the slice. + fn check_end(reader: &SliceReader) -> Result<()>; +} + +/// A TrailingBytes config that will allow trailing bytes in slices after deserialization. +#[derive(Copy, Clone)] +pub struct AllowTrailing; + +/// A TrailingBytes config that will cause bincode to produce an error if bytes are left over in the slice when deserialization is complete. + +#[derive(Copy, Clone)] +pub struct RejectTrailing; + +impl TrailingBytes for AllowTrailing { + #[inline(always)] + fn check_end(_reader: &SliceReader) -> Result<()> { + Ok(()) + } +} + +impl TrailingBytes for RejectTrailing { + #[inline(always)] + fn check_end(reader: &SliceReader) -> Result<()> { + if reader.is_finished() { + Ok(()) + } else { + Err(Box::new(ErrorKind::Custom( + "Slice had bytes remaining after deserialization".to_string(), + ))) + } + } +} 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..7b2bdf5286 --- /dev/null +++ b/third_party/rust/bincode/src/de/mod.rs @@ -0,0 +1,515 @@ +use config::{BincodeByteOrder, Options}; +use std::io::Read; + +use self::read::{BincodeRead, IoReader, SliceReader}; +use byteorder::ReadBytesExt; +use config::{IntEncoding, SizeLimit}; +use serde; +use serde::de::Error as DeError; +use serde::de::IntoDeserializer; +use {Error, ErrorKind, Result}; + +/// Specialized ways to read data into bincode. +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 struct Deserializer { + pub(crate) reader: R, + options: O, +} + +macro_rules! impl_deserialize_literal { + ($name:ident : $ty:ty = $read:ident()) => { + #[inline] + pub(crate) fn $name(&mut self) -> Result<$ty> { + self.read_literal_type::<$ty>()?; + self.reader + .$read::<::Endian>() + .map_err(Into::into) + } + }; +} + +impl<'de, IR: Read, O: Options> Deserializer, O> { + /// Creates a new Deserializer with a given `Read`er and options. + pub fn with_reader(r: IR, options: O) -> Self { + Deserializer { + reader: IoReader::new(r), + options, + } + } +} + +impl<'de, O: Options> Deserializer, O> { + /// Creates a new Deserializer that will read from the given slice. + pub fn from_slice(slice: &'de [u8], options: O) -> Self { + Deserializer { + reader: SliceReader::new(slice), + options, + } + } +} + +impl<'de, R: BincodeRead<'de>, O: Options> Deserializer { + /// Creates a new Deserializer with the given `BincodeRead`er + pub fn with_bincode_read(r: R, options: O) -> Deserializer { + Deserializer { reader: r, options } + } + + pub(crate) fn deserialize_byte(&mut self) -> Result { + self.read_literal_type::()?; + self.reader.read_u8().map_err(Into::into) + } + + impl_deserialize_literal! { deserialize_literal_u16 : u16 = read_u16() } + impl_deserialize_literal! { deserialize_literal_u32 : u32 = read_u32() } + impl_deserialize_literal! { deserialize_literal_u64 : u64 = read_u64() } + + serde_if_integer128! { + impl_deserialize_literal! { deserialize_literal_u128 : u128 = read_u128() } + } + + fn read_bytes(&mut self, count: u64) -> Result<()> { + self.options.limit().add(count) + } + + fn read_literal_type(&mut self) -> Result<()> { + use std::mem::size_of; + self.read_bytes(size_of::() as u64) + } + + fn read_vec(&mut self) -> Result> { + let len = O::IntEncoding::deserialize_len(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_deserialize_int { + ($name:ident = $visitor_method:ident ($dser_method:ident)) => { + #[inline] + fn $name(self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + visitor.$visitor_method(O::IntEncoding::$dser_method(self)?) + } + }; +} + +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>, + { + match self.deserialize_byte()? { + 1 => visitor.visit_bool(true), + 0 => visitor.visit_bool(false), + value => Err(ErrorKind::InvalidBoolEncoding(value).into()), + } + } + + impl_deserialize_int!(deserialize_u16 = visit_u16(deserialize_u16)); + impl_deserialize_int!(deserialize_u32 = visit_u32(deserialize_u32)); + impl_deserialize_int!(deserialize_u64 = visit_u64(deserialize_u64)); + impl_deserialize_int!(deserialize_i16 = visit_i16(deserialize_i16)); + impl_deserialize_int!(deserialize_i32 = visit_i32(deserialize_i32)); + impl_deserialize_int!(deserialize_i64 = visit_i64(deserialize_i64)); + + fn deserialize_f32(self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + self.read_literal_type::()?; + let value = self + .reader + .read_f32::<::Endian>()?; + visitor.visit_f32(value) + } + + fn deserialize_f64(self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + self.read_literal_type::()?; + let value = self + .reader + .read_f64::<::Endian>()?; + visitor.visit_f64(value) + } + + serde_if_integer128! { + impl_deserialize_int!(deserialize_u128 = visit_u128(deserialize_u128)); + impl_deserialize_int!(deserialize_i128 = visit_i128(deserialize_i128)); + } + + #[inline] + fn deserialize_u8(self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + visitor.visit_u8(self.deserialize_byte()? as u8) + } + + #[inline] + fn deserialize_i8(self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + visitor.visit_i8(self.deserialize_byte()? as 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 + 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 = str::from_utf8(&buf[..width]) + .ok() + .and_then(|s| s.chars().next()) + .ok_or_else(error)?; + visitor.visit_char(res) + } + + fn deserialize_str(self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let len = O::IntEncoding::deserialize_len(self)?; + 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(self.read_string()?) + } + + fn deserialize_bytes(self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let len = O::IntEncoding::deserialize_len(self)?; + 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(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 = O::IntEncoding::deserialize_u32(self)?; + let val: Result<_> = seed.deserialize(idx.into_deserializer()); + Ok((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 = + 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, + }) + } + + fn deserialize_option(self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let value: u8 = 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 = O::IntEncoding::deserialize_len(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 = + 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 = serde::de::DeserializeSeed::deserialize(seed, &mut *self.deserializer)?; + Ok(value) + } + + fn size_hint(&self) -> Option { + Some(self.len) + } + } + + let len = O::IntEncoding::deserialize_len(self)?; + + visitor.visit_map(Access { + deserializer: self, + 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 +} 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..08b76adc90 --- /dev/null +++ b/third_party/rust/bincode/src/de/read.rs @@ -0,0 +1,202 @@ +use error::Result; +use serde; +use std::io; + +/// 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`. +/// +/// The forward_read_* methods are necessary because some byte sources want +/// to pass a long-lived borrow to the visitor and others want to pass a +/// transient slice. +pub trait BincodeRead<'storage>: io::Read { + /// Check that the next `length` bytes are a valid string and pass + /// it on to the serde reader. + fn forward_read_str(&mut self, length: usize, visitor: V) -> Result + where + V: serde::de::Visitor<'storage>; + + /// Transfer ownership of the next `length` bytes to the caller. + fn get_byte_buffer(&mut self, length: usize) -> Result>; + + /// Pass a slice of the next `length` bytes on to the serde reader. + fn forward_read_bytes(&mut self, length: usize, visitor: V) -> Result + where + V: serde::de::Visitor<'storage>; +} + +/// A BincodeRead implementation for byte slices +pub struct SliceReader<'storage> { + slice: &'storage [u8], +} + +/// A BincodeRead implementation for `io::Read`ers +pub struct IoReader { + reader: R, + temp_buffer: Vec, +} + +impl<'storage> SliceReader<'storage> { + /// Constructs a slice reader + pub(crate) fn new(bytes: &'storage [u8]) -> SliceReader<'storage> { + SliceReader { slice: bytes } + } + + #[inline(always)] + fn get_byte_slice(&mut self, length: usize) -> Result<&'storage [u8]> { + if length > self.slice.len() { + return Err(SliceReader::unexpected_eof()); + } + let (read_slice, remaining) = self.slice.split_at(length); + self.slice = remaining; + Ok(read_slice) + } + + pub(crate) fn is_finished(&self) -> bool { + self.slice.is_empty() + } +} + +impl IoReader { + /// Constructs an IoReadReader + pub(crate) fn new(r: R) -> IoReader { + IoReader { + reader: r, + temp_buffer: vec![], + } + } +} + +impl<'storage> io::Read for SliceReader<'storage> { + #[inline(always)] + fn read(&mut self, out: &mut [u8]) -> io::Result { + if out.len() > self.slice.len() { + return Err(io::ErrorKind::UnexpectedEof.into()); + } + let (read_slice, remaining) = self.slice.split_at(out.len()); + out.copy_from_slice(read_slice); + self.slice = remaining; + + Ok(out.len()) + } + + #[inline(always)] + fn read_exact(&mut self, out: &mut [u8]) -> io::Result<()> { + self.read(out).map(|_| ()) + } +} + +impl io::Read for IoReader { + #[inline(always)] + fn read(&mut self, out: &mut [u8]) -> io::Result { + 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> { + Box::new(::ErrorKind::Io(io::Error::new( + io::ErrorKind::UnexpectedEof, + "", + ))) + } +} + +impl<'storage> BincodeRead<'storage> for SliceReader<'storage> { + #[inline(always)] + fn forward_read_str(&mut self, length: usize, visitor: V) -> Result + where + V: serde::de::Visitor<'storage>, + { + use ErrorKind; + let string = match ::std::str::from_utf8(self.get_byte_slice(length)?) { + Ok(s) => s, + Err(e) => return Err(ErrorKind::InvalidUtf8Encoding(e).into()), + }; + visitor.visit_borrowed_str(string) + } + + #[inline(always)] + fn get_byte_buffer(&mut self, length: usize) -> Result> { + self.get_byte_slice(length).map(|x| x.to_vec()) + } + + #[inline(always)] + fn forward_read_bytes(&mut self, length: usize, visitor: V) -> Result + where + V: serde::de::Visitor<'storage>, + { + visitor.visit_borrowed_bytes(self.get_byte_slice(length)?) + } +} + +impl IoReader +where + R: io::Read, +{ + fn fill_buffer(&mut self, length: usize) -> Result<()> { + self.temp_buffer.resize(length, 0); + + self.reader.read_exact(&mut self.temp_buffer)?; + + Ok(()) + } +} + +impl<'a, R> BincodeRead<'a> for IoReader +where + R: io::Read, +{ + fn forward_read_str(&mut self, length: usize, visitor: V) -> Result + 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()), + }; + + visitor.visit_str(string) + } + + fn get_byte_buffer(&mut self, length: usize) -> Result> { + self.fill_buffer(length)?; + Ok(::std::mem::replace(&mut self.temp_buffer, Vec::new())) + } + + fn forward_read_bytes(&mut self, length: usize, visitor: V) -> Result + where + V: serde::de::Visitor<'a>, + { + self.fill_buffer(length)?; + visitor.visit_bytes(&self.temp_buffer[..]) + } +} + +#[cfg(test)] +mod test { + use super::IoReader; + + #[test] + fn test_fill_buffer() { + let buffer = vec![0u8; 64]; + let mut reader = IoReader::new(buffer.as_slice()); + + reader.fill_buffer(20).unwrap(); + assert_eq!(20, reader.temp_buffer.len()); + + reader.fill_buffer(30).unwrap(); + assert_eq!(30, reader.temp_buffer.len()); + + reader.fill_buffer(5).unwrap(); + assert_eq!(5, reader.temp_buffer.len()); + } +} diff --git a/third_party/rust/bincode/src/error.rs b/third_party/rust/bincode/src/error.rs new file mode 100644 index 0000000000..420fa7ab7d --- /dev/null +++ b/third_party/rust/bincode/src/error.rs @@ -0,0 +1,115 @@ +use std::error::Error as StdError; +use std::io; +use std::str::Utf8Error; +use std::{error, fmt}; + +use serde; + +/// The result of a serialization or deserialization operation. +pub type Result = ::std::result::Result; + +/// An error that can be produced during (de)serializing. +pub type Error = Box; + +/// The kind of error that can be produced during a serialization or deserialization. +#[derive(Debug)] +pub enum ErrorKind { + /// If the error stems from the reader/writer that is being used + /// during (de)serialization, that error will be stored and returned here. + Io(io::Error), + /// Returned if the deserializer attempts to deserialize a string that is not valid utf8 + InvalidUtf8Encoding(Utf8Error), + /// Returned if the deserializer attempts to deserialize a bool that was + /// not encoded as either a 1 or a 0 + InvalidBoolEncoding(u8), + /// Returned if the deserializer attempts to deserialize a char that is not in the correct format. + InvalidCharEncoding, + /// Returned if the deserializer attempts to deserialize the tag of an enum that is + /// not in the expected ranges + InvalidTagEncoding(usize), + /// Serde has a deserialize_any method that lets the format hint to the + /// object which route to take in deserializing. + DeserializeAnyNotSupported, + /// If (de)serializing a message takes more than the provided size limit, this + /// error is returned. + SizeLimit, + /// Bincode can not encode sequences of unknown length (like iterators). + SequenceMustHaveLength, + /// A custom error message from Serde. + Custom(String), +} + +impl StdError for ErrorKind { + fn description(&self) -> &str { + match *self { + ErrorKind::Io(ref err) => error::Error::description(err), + ErrorKind::InvalidUtf8Encoding(_) => "string is not valid utf8", + ErrorKind::InvalidBoolEncoding(_) => "invalid u8 while decoding bool", + ErrorKind::InvalidCharEncoding => "char is not valid", + ErrorKind::InvalidTagEncoding(_) => "tag for enum is not valid", + ErrorKind::SequenceMustHaveLength => { + "Bincode can only encode sequences and maps that have a knowable size ahead of time" + } + ErrorKind::DeserializeAnyNotSupported => { + "Bincode doesn't support serde::Deserializer::deserialize_any" + } + ErrorKind::SizeLimit => "the size limit has been reached", + ErrorKind::Custom(ref msg) => msg, + } + } + + fn cause(&self) -> Option<&error::Error> { + match *self { + ErrorKind::Io(ref err) => Some(err), + ErrorKind::InvalidUtf8Encoding(_) => None, + ErrorKind::InvalidBoolEncoding(_) => None, + ErrorKind::InvalidCharEncoding => None, + ErrorKind::InvalidTagEncoding(_) => None, + ErrorKind::SequenceMustHaveLength => None, + ErrorKind::DeserializeAnyNotSupported => None, + ErrorKind::SizeLimit => None, + ErrorKind::Custom(_) => None, + } + } +} + +impl From for Error { + fn from(err: io::Error) -> Error { + ErrorKind::Io(err).into() + } +} + +impl fmt::Display for ErrorKind { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + match *self { + ErrorKind::Io(ref ioerr) => write!(fmt, "io error: {}", ioerr), + ErrorKind::InvalidUtf8Encoding(ref e) => write!(fmt, "{}: {}", self.description(), e), + ErrorKind::InvalidBoolEncoding(b) => { + write!(fmt, "{}, expected 0 or 1, found {}", self.description(), b) + } + ErrorKind::InvalidCharEncoding => write!(fmt, "{}", self.description()), + ErrorKind::InvalidTagEncoding(tag) => { + write!(fmt, "{}, found {}", self.description(), tag) + } + ErrorKind::SequenceMustHaveLength => write!(fmt, "{}", self.description()), + ErrorKind::SizeLimit => write!(fmt, "{}", self.description()), + ErrorKind::DeserializeAnyNotSupported => write!( + fmt, + "Bincode does not support the serde::Deserializer::deserialize_any method" + ), + ErrorKind::Custom(ref s) => s.fmt(fmt), + } + } +} + +impl serde::de::Error for Error { + fn custom(desc: T) -> Error { + ErrorKind::Custom(desc.to_string()).into() + } +} + +impl serde::ser::Error for Error { + fn custom(msg: T) -> Self { + ErrorKind::Custom(msg.to_string()).into() + } +} diff --git a/third_party/rust/bincode/src/internal.rs b/third_party/rust/bincode/src/internal.rs new file mode 100644 index 0000000000..1d2a9a1290 --- /dev/null +++ b/third_party/rust/bincode/src/internal.rs @@ -0,0 +1,124 @@ +use serde; +use std::io::{Read, Write}; +use std::marker::PhantomData; + +use config::{Infinite, InternalOptions, Options, SizeLimit, TrailingBytes}; +use de::read::BincodeRead; +use Result; + +pub(crate) fn serialize_into(writer: W, value: &T, mut options: O) -> Result<()> +where + W: Write, + T: serde::Serialize, + O: InternalOptions, +{ + if options.limit().limit().is_some() { + // "compute" the size for the side-effect + // of returning Err if the bound was reached. + serialized_size(value, &mut options)?; + } + + let mut serializer = ::ser::Serializer::<_, O>::new(writer, options); + serde::Serialize::serialize(value, &mut serializer) +} + +pub(crate) fn serialize(value: &T, mut options: O) -> Result> +where + T: serde::Serialize, + O: InternalOptions, +{ + let mut writer = { + let actual_size = serialized_size(value, &mut options)?; + Vec::with_capacity(actual_size as usize) + }; + + serialize_into(&mut writer, value, options.with_no_limit())?; + Ok(writer) +} + +pub(crate) fn serialized_size(value: &T, options: O) -> Result +where + T: serde::Serialize, +{ + let mut size_counter = ::ser::SizeChecker { options, total: 0 }; + + let result = value.serialize(&mut size_counter); + result.map(|_| size_counter.total) +} + +pub(crate) fn deserialize_from(reader: R, options: O) -> Result +where + R: Read, + T: serde::de::DeserializeOwned, + O: InternalOptions, +{ + deserialize_from_seed(PhantomData, reader, options) +} + +pub(crate) fn deserialize_from_seed<'a, R, T, O>(seed: T, reader: R, options: O) -> Result +where + R: Read, + T: serde::de::DeserializeSeed<'a>, + O: InternalOptions, +{ + let reader = ::de::read::IoReader::new(reader); + deserialize_from_custom_seed(seed, reader, options) +} + +pub(crate) fn deserialize_from_custom<'a, R, T, O>(reader: R, options: O) -> Result +where + R: BincodeRead<'a>, + T: serde::de::DeserializeOwned, + O: InternalOptions, +{ + deserialize_from_custom_seed(PhantomData, reader, options) +} + +pub(crate) fn deserialize_from_custom_seed<'a, R, T, O>( + seed: T, + reader: R, + options: O, +) -> Result +where + R: BincodeRead<'a>, + T: serde::de::DeserializeSeed<'a>, + O: InternalOptions, +{ + let mut deserializer = ::de::Deserializer::<_, O>::with_bincode_read(reader, options); + seed.deserialize(&mut deserializer) +} + +pub(crate) fn deserialize_in_place<'a, R, T, O>(reader: R, options: O, place: &mut T) -> Result<()> +where + R: BincodeRead<'a>, + T: serde::de::Deserialize<'a>, + O: InternalOptions, +{ + let mut deserializer = ::de::Deserializer::<_, _>::with_bincode_read(reader, options); + serde::Deserialize::deserialize_in_place(&mut deserializer, place) +} + +pub(crate) fn deserialize<'a, T, O>(bytes: &'a [u8], options: O) -> Result +where + T: serde::de::Deserialize<'a>, + O: InternalOptions, +{ + deserialize_seed(PhantomData, bytes, options) +} + +pub(crate) fn deserialize_seed<'a, T, O>(seed: T, bytes: &'a [u8], options: O) -> Result +where + T: serde::de::DeserializeSeed<'a>, + O: InternalOptions, +{ + let options = ::config::WithOtherLimit::new(options, Infinite); + + let reader = ::de::read::SliceReader::new(bytes); + let mut deserializer = ::de::Deserializer::with_bincode_read(reader, options); + let val = seed.deserialize(&mut deserializer)?; + + match O::Trailing::check_end(&deserializer.reader) { + Ok(_) => Ok(val), + Err(err) => Err(err), + } +} diff --git a/third_party/rust/bincode/src/lib.rs b/third_party/rust/bincode/src/lib.rs new file mode 100644 index 0000000000..3969ab773b --- /dev/null +++ b/third_party/rust/bincode/src/lib.rs @@ -0,0 +1,201 @@ +#![deny(missing_docs)] +#![allow(unknown_lints, bare_trait_objects, deprecated)] + +//! Bincode is a crate for encoding and decoding using a tiny binary +//! serialization strategy. Using it, you can easily go from having +//! an object in memory, quickly serialize it to bytes, and then +//! deserialize it back just as fast! +//! +//! ### Using Basic Functions +//! +//! ```edition2018 +//! fn main() { +//! // The object that we will serialize. +//! let target: Option = Some("hello world".to_string()); +//! +//! let encoded: Vec = bincode::serialize(&target).unwrap(); +//! let decoded: Option = bincode::deserialize(&encoded[..]).unwrap(); +//! assert_eq!(target, decoded); +//! } +//! ``` +//! +//! ### 128bit numbers +//! +//! Support for `i128` and `u128` is automatically enabled on Rust toolchains +//! greater than or equal to `1.26.0` and disabled for targets which do not support it + +#![doc(html_root_url = "https://docs.rs/bincode/1.3.3")] +#![crate_name = "bincode"] +#![crate_type = "rlib"] +#![crate_type = "dylib"] + +#[macro_use] +extern crate serde; + +pub mod config; +/// Deserialize bincode data to a Rust data structure. +pub mod de; + +mod byteorder; +mod error; +mod internal; +mod ser; + +pub use config::{Config, DefaultOptions, Options}; +pub use de::read::BincodeRead; +pub use de::Deserializer; +pub use error::{Error, ErrorKind, Result}; +pub use ser::Serializer; + +/// Get a default configuration object. +/// +/// ### Default Configuration: +/// +/// | Byte limit | Endianness | +/// |------------|------------| +/// | Unlimited | Little | +#[inline(always)] +#[deprecated(since = "1.3.0", note = "please use `options()` instead")] +pub fn config() -> Config { + Config::new() +} + +/// Get a default configuration object. +/// +/// **Warning:** the default configuration returned by this function +/// is not the same as that used by the other functions in this +/// module. See the +/// [config](config/index.html#options-struct-vs-bincode-functions) +/// module for more details +/// +/// ### Default Configuration: +/// +/// | Byte limit | Endianness | Int Encoding | Trailing Behavior | +/// |------------|------------|--------------|-------------------| +/// | Unlimited | Little | Varint | Reject | +#[inline(always)] +pub fn options() -> DefaultOptions { + DefaultOptions::new() +} + +/// Serializes an object directly into a `Writer` using the default configuration. +/// +/// If the serialization would take more bytes than allowed by the size limit, an error +/// is returned and *no bytes* will be written into the `Writer`. +/// +/// **Warning:** the default configuration used by this function is not +/// the same as that used by the `DefaultOptions` struct. See the +/// [config](config/index.html#options-struct-vs-bincode-functions) +/// module for more details +pub fn serialize_into(writer: W, value: &T) -> Result<()> +where + W: std::io::Write, + T: serde::Serialize, +{ + DefaultOptions::new() + .with_fixint_encoding() + .serialize_into(writer, value) +} + +/// Serializes a serializable object into a `Vec` of bytes using the default configuration. +/// +/// **Warning:** the default configuration used by this function is not +/// the same as that used by the `DefaultOptions` struct. See the +/// [config](config/index.html#options-struct-vs-bincode-functions) +/// module for more details +pub fn serialize(value: &T) -> Result> +where + T: serde::Serialize, +{ + DefaultOptions::new() + .with_fixint_encoding() + .allow_trailing_bytes() + .serialize(value) +} + +/// Deserializes an object directly from a `Read`er using the default configuration. +/// +/// If this returns an `Error`, `reader` may be in an invalid state. +/// +/// **Warning:** the default configuration used by this function is not +/// the same as that used by the `DefaultOptions` struct. See the +/// [config](config/index.html#options-struct-vs-bincode-functions) +/// module for more details +pub fn deserialize_from(reader: R) -> Result +where + R: std::io::Read, + T: serde::de::DeserializeOwned, +{ + DefaultOptions::new() + .with_fixint_encoding() + .allow_trailing_bytes() + .deserialize_from(reader) +} + +/// Deserializes an object from a custom `BincodeRead`er using the default configuration. +/// It is highly recommended to use `deserialize_from` unless you need to implement +/// `BincodeRead` for performance reasons. +/// +/// If this returns an `Error`, `reader` may be in an invalid state. +/// +/// **Warning:** the default configuration used by this function is not +/// the same as that used by the `DefaultOptions` struct. See the +/// [config](config/index.html#options-struct-vs-bincode-functions) +/// module for more details +pub fn deserialize_from_custom<'a, R, T>(reader: R) -> Result +where + R: de::read::BincodeRead<'a>, + T: serde::de::DeserializeOwned, +{ + DefaultOptions::new() + .with_fixint_encoding() + .allow_trailing_bytes() + .deserialize_from_custom(reader) +} + +/// Only use this if you know what you're doing. +/// +/// This is part of the public API. +#[doc(hidden)] +pub fn deserialize_in_place<'a, R, T>(reader: R, place: &mut T) -> Result<()> +where + T: serde::de::Deserialize<'a>, + R: BincodeRead<'a>, +{ + DefaultOptions::new() + .with_fixint_encoding() + .allow_trailing_bytes() + .deserialize_in_place(reader, place) +} + +/// Deserializes a slice of bytes into an instance of `T` using the default configuration. +/// +/// **Warning:** the default configuration used by this function is not +/// the same as that used by the `DefaultOptions` struct. See the +/// [config](config/index.html#options-struct-vs-bincode-functions) +/// module for more details +pub fn deserialize<'a, T>(bytes: &'a [u8]) -> Result +where + T: serde::de::Deserialize<'a>, +{ + DefaultOptions::new() + .with_fixint_encoding() + .allow_trailing_bytes() + .deserialize(bytes) +} + +/// Returns the size that an object would be if serialized using Bincode with the default configuration. +/// +/// **Warning:** the default configuration used by this function is not +/// the same as that used by the `DefaultOptions` struct. See the +/// [config](config/index.html#options-struct-vs-bincode-functions) +/// module for more details +pub fn serialized_size(value: &T) -> Result +where + T: serde::Serialize, +{ + DefaultOptions::new() + .with_fixint_encoding() + .allow_trailing_bytes() + .serialized_size(value) +} diff --git a/third_party/rust/bincode/src/ser/mod.rs b/third_party/rust/bincode/src/ser/mod.rs new file mode 100644 index 0000000000..be4f3f2230 --- /dev/null +++ b/third_party/rust/bincode/src/ser/mod.rs @@ -0,0 +1,772 @@ +use std::io::Write; +use std::u32; + +use serde; + +use byteorder::WriteBytesExt; + +use super::config::{IntEncoding, SizeLimit}; +use super::{Error, ErrorKind, Result}; +use config::{BincodeByteOrder, Options}; +use std::mem::size_of; + +/// An Serializer that encodes values directly into a Writer. +/// +/// The specified byte-order will impact the endianness that is +/// used during the encoding. +/// +/// This struct should not be used often. +/// For most cases, prefer the `encode_into` function. +pub struct Serializer { + writer: W, + _options: O, +} + +macro_rules! impl_serialize_literal { + ($ser_method:ident($ty:ty) = $write:ident()) => { + pub(crate) fn $ser_method(&mut self, v: $ty) -> Result<()> { + self.writer + .$write::<::Endian>(v) + .map_err(Into::into) + } + }; +} + +impl Serializer { + /// Creates a new Serializer with the given `Write`r. + pub fn new(w: W, options: O) -> Serializer { + Serializer { + writer: w, + _options: options, + } + } + + pub(crate) fn serialize_byte(&mut self, v: u8) -> Result<()> { + self.writer.write_u8(v).map_err(Into::into) + } + + impl_serialize_literal! {serialize_literal_u16(u16) = write_u16()} + impl_serialize_literal! {serialize_literal_u32(u32) = write_u32()} + impl_serialize_literal! {serialize_literal_u64(u64) = write_u64()} + + serde_if_integer128! { + impl_serialize_literal!{serialize_literal_u128(u128) = write_u128()} + } +} + +macro_rules! impl_serialize_int { + ($ser_method:ident($ty:ty) = $ser_int:ident()) => { + fn $ser_method(self, v: $ty) -> Result<()> { + O::IntEncoding::$ser_int(self, v) + } + }; +} + +impl<'a, W: Write, O: Options> serde::Serializer for &'a mut Serializer { + type Ok = (); + type Error = Error; + type SerializeSeq = Compound<'a, W, O>; + type SerializeTuple = Compound<'a, W, O>; + type SerializeTupleStruct = Compound<'a, W, O>; + type SerializeTupleVariant = Compound<'a, W, O>; + type SerializeMap = Compound<'a, W, O>; + type SerializeStruct = Compound<'a, W, O>; + type SerializeStructVariant = Compound<'a, W, O>; + + fn serialize_unit(self) -> Result<()> { + Ok(()) + } + + fn serialize_unit_struct(self, _: &'static str) -> Result<()> { + Ok(()) + } + + fn serialize_bool(self, v: bool) -> Result<()> { + self.serialize_byte(v as u8) + } + + fn serialize_u8(self, v: u8) -> Result<()> { + self.serialize_byte(v) + } + + impl_serialize_int! {serialize_u16(u16) = serialize_u16()} + impl_serialize_int! {serialize_u32(u32) = serialize_u32()} + impl_serialize_int! {serialize_u64(u64) = serialize_u64()} + + fn serialize_i8(self, v: i8) -> Result<()> { + self.serialize_byte(v as u8) + } + + impl_serialize_int! {serialize_i16(i16) = serialize_i16()} + impl_serialize_int! {serialize_i32(i32) = serialize_i32()} + impl_serialize_int! {serialize_i64(i64) = serialize_i64()} + + serde_if_integer128! { + impl_serialize_int!{serialize_u128(u128) = serialize_u128()} + impl_serialize_int!{serialize_i128(i128) = serialize_i128()} + } + + fn serialize_f32(self, v: f32) -> Result<()> { + self.writer + .write_f32::<::Endian>(v) + .map_err(Into::into) + } + + fn serialize_f64(self, v: f64) -> Result<()> { + self.writer + .write_f64::<::Endian>(v) + .map_err(Into::into) + } + + fn serialize_str(self, v: &str) -> Result<()> { + O::IntEncoding::serialize_len(self, v.len())?; + self.writer.write_all(v.as_bytes()).map_err(Into::into) + } + + fn serialize_char(self, c: char) -> Result<()> { + self.writer + .write_all(encode_utf8(c).as_slice()) + .map_err(Into::into) + } + + fn serialize_bytes(self, v: &[u8]) -> Result<()> { + O::IntEncoding::serialize_len(self, v.len())?; + self.writer.write_all(v).map_err(Into::into) + } + + fn serialize_none(self) -> Result<()> { + self.writer.write_u8(0).map_err(Into::into) + } + + fn serialize_some(self, v: &T) -> Result<()> + where + T: serde::Serialize, + { + self.writer.write_u8(1)?; + v.serialize(self) + } + + fn serialize_seq(self, len: Option) -> Result { + let len = len.ok_or(ErrorKind::SequenceMustHaveLength)?; + O::IntEncoding::serialize_len(self, len)?; + Ok(Compound { ser: self }) + } + + fn serialize_tuple(self, _len: usize) -> Result { + Ok(Compound { ser: self }) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result { + Ok(Compound { ser: self }) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + O::IntEncoding::serialize_u32(self, variant_index)?; + Ok(Compound { ser: self }) + } + + fn serialize_map(self, len: Option) -> Result { + let len = len.ok_or(ErrorKind::SequenceMustHaveLength)?; + O::IntEncoding::serialize_len(self, len)?; + Ok(Compound { ser: self }) + } + + fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { + Ok(Compound { ser: self }) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + O::IntEncoding::serialize_u32(self, variant_index)?; + Ok(Compound { ser: self }) + } + + fn serialize_newtype_struct(self, _name: &'static str, value: &T) -> Result<()> + where + T: serde::ser::Serialize, + { + value.serialize(self) + } + + fn serialize_newtype_variant( + self, + _name: &'static str, + variant_index: u32, + _variant: &'static str, + value: &T, + ) -> Result<()> + where + T: serde::ser::Serialize, + { + O::IntEncoding::serialize_u32(self, variant_index)?; + value.serialize(self) + } + + fn serialize_unit_variant( + self, + _name: &'static str, + variant_index: u32, + _variant: &'static str, + ) -> Result<()> { + O::IntEncoding::serialize_u32(self, variant_index) + } + + fn is_human_readable(&self) -> bool { + false + } +} + +pub(crate) struct SizeChecker { + pub options: O, + pub total: u64, +} + +impl SizeChecker { + fn add_raw(&mut self, size: u64) -> Result<()> { + self.options.limit().add(size)?; + self.total += size; + + Ok(()) + } + + fn add_discriminant(&mut self, idx: u32) -> Result<()> { + let bytes = O::IntEncoding::u32_size(idx); + self.add_raw(bytes) + } + + fn add_len(&mut self, len: usize) -> Result<()> { + let bytes = O::IntEncoding::len_size(len); + self.add_raw(bytes) + } +} + +macro_rules! impl_size_int { + ($ser_method:ident($ty:ty) = $size_method:ident()) => { + fn $ser_method(self, v: $ty) -> Result<()> { + self.add_raw(O::IntEncoding::$size_method(v)) + } + }; +} + +impl<'a, O: Options> serde::Serializer for &'a mut SizeChecker { + type Ok = (); + type Error = Error; + type SerializeSeq = SizeCompound<'a, O>; + type SerializeTuple = SizeCompound<'a, O>; + type SerializeTupleStruct = SizeCompound<'a, O>; + type SerializeTupleVariant = SizeCompound<'a, O>; + type SerializeMap = SizeCompound<'a, O>; + type SerializeStruct = SizeCompound<'a, O>; + type SerializeStructVariant = SizeCompound<'a, O>; + + fn serialize_unit(self) -> Result<()> { + Ok(()) + } + + fn serialize_unit_struct(self, _: &'static str) -> Result<()> { + Ok(()) + } + + fn serialize_bool(self, _: bool) -> Result<()> { + self.add_raw(1) + } + + fn serialize_u8(self, _: u8) -> Result<()> { + self.add_raw(1) + } + fn serialize_i8(self, _: i8) -> Result<()> { + self.add_raw(1) + } + + impl_size_int! {serialize_u16(u16) = u16_size()} + impl_size_int! {serialize_u32(u32) = u32_size()} + impl_size_int! {serialize_u64(u64) = u64_size()} + impl_size_int! {serialize_i16(i16) = i16_size()} + impl_size_int! {serialize_i32(i32) = i32_size()} + impl_size_int! {serialize_i64(i64) = i64_size()} + + serde_if_integer128! { + impl_size_int!{serialize_u128(u128) = u128_size()} + impl_size_int!{serialize_i128(i128) = i128_size()} + } + + fn serialize_f32(self, _: f32) -> Result<()> { + self.add_raw(size_of::() as u64) + } + + fn serialize_f64(self, _: f64) -> Result<()> { + self.add_raw(size_of::() as u64) + } + + fn serialize_str(self, v: &str) -> Result<()> { + self.add_len(v.len())?; + self.add_raw(v.len() as u64) + } + + fn serialize_char(self, c: char) -> Result<()> { + self.add_raw(encode_utf8(c).as_slice().len() as u64) + } + + fn serialize_bytes(self, v: &[u8]) -> Result<()> { + self.add_len(v.len())?; + self.add_raw(v.len() as u64) + } + + fn serialize_none(self) -> Result<()> { + self.add_raw(1) + } + + fn serialize_some(self, v: &T) -> Result<()> + where + T: serde::Serialize, + { + self.add_raw(1)?; + v.serialize(self) + } + + fn serialize_seq(self, len: Option) -> Result { + let len = len.ok_or(ErrorKind::SequenceMustHaveLength)?; + + self.add_len(len)?; + Ok(SizeCompound { ser: self }) + } + + fn serialize_tuple(self, _len: usize) -> Result { + Ok(SizeCompound { ser: self }) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result { + Ok(SizeCompound { ser: self }) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + self.add_raw(O::IntEncoding::u32_size(variant_index))?; + Ok(SizeCompound { ser: self }) + } + + fn serialize_map(self, len: Option) -> Result { + let len = len.ok_or(ErrorKind::SequenceMustHaveLength)?; + + self.add_len(len)?; + Ok(SizeCompound { ser: self }) + } + + fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { + Ok(SizeCompound { ser: self }) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + self.add_discriminant(variant_index)?; + Ok(SizeCompound { ser: self }) + } + + fn serialize_newtype_struct( + self, + _name: &'static str, + v: &V, + ) -> Result<()> { + v.serialize(self) + } + + fn serialize_unit_variant( + self, + _name: &'static str, + variant_index: u32, + _variant: &'static str, + ) -> Result<()> { + self.add_discriminant(variant_index) + } + + fn serialize_newtype_variant( + self, + _name: &'static str, + variant_index: u32, + _variant: &'static str, + value: &V, + ) -> Result<()> { + self.add_discriminant(variant_index)?; + value.serialize(self) + } + + fn is_human_readable(&self) -> bool { + false + } +} + +pub struct Compound<'a, W: 'a, O: Options + 'a> { + ser: &'a mut Serializer, +} + +impl<'a, W, O> serde::ser::SerializeSeq for Compound<'a, W, O> +where + W: Write, + O: Options, +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_element(&mut self, value: &T) -> Result<()> + where + T: serde::ser::Serialize, + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl<'a, W, O> serde::ser::SerializeTuple for Compound<'a, W, O> +where + W: Write, + O: Options, +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_element(&mut self, value: &T) -> Result<()> + where + T: serde::ser::Serialize, + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl<'a, W, O> serde::ser::SerializeTupleStruct for Compound<'a, W, O> +where + W: Write, + O: Options, +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_field(&mut self, value: &T) -> Result<()> + where + T: serde::ser::Serialize, + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl<'a, W, O> serde::ser::SerializeTupleVariant for Compound<'a, W, O> +where + W: Write, + O: Options, +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_field(&mut self, value: &T) -> Result<()> + where + T: serde::ser::Serialize, + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl<'a, W, O> serde::ser::SerializeMap for Compound<'a, W, O> +where + W: Write, + O: Options, +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_key(&mut self, value: &K) -> Result<()> + where + K: serde::ser::Serialize, + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn serialize_value(&mut self, value: &V) -> Result<()> + where + V: serde::ser::Serialize, + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl<'a, W, O> serde::ser::SerializeStruct for Compound<'a, W, O> +where + W: Write, + O: Options, +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_field(&mut self, _key: &'static str, value: &T) -> Result<()> + where + T: serde::ser::Serialize, + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl<'a, W, O> serde::ser::SerializeStructVariant for Compound<'a, W, O> +where + W: Write, + O: Options, +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_field(&mut self, _key: &'static str, value: &T) -> Result<()> + where + T: serde::ser::Serialize, + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +pub(crate) struct SizeCompound<'a, S: Options + 'a> { + ser: &'a mut SizeChecker, +} + +impl<'a, O: Options> serde::ser::SerializeSeq for SizeCompound<'a, O> { + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_element(&mut self, value: &T) -> Result<()> + where + T: serde::ser::Serialize, + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl<'a, O: Options> serde::ser::SerializeTuple for SizeCompound<'a, O> { + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_element(&mut self, value: &T) -> Result<()> + where + T: serde::ser::Serialize, + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl<'a, O: Options> serde::ser::SerializeTupleStruct for SizeCompound<'a, O> { + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_field(&mut self, value: &T) -> Result<()> + where + T: serde::ser::Serialize, + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl<'a, O: Options> serde::ser::SerializeTupleVariant for SizeCompound<'a, O> { + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_field(&mut self, value: &T) -> Result<()> + where + T: serde::ser::Serialize, + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl<'a, O: Options + 'a> serde::ser::SerializeMap for SizeCompound<'a, O> { + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_key(&mut self, value: &K) -> Result<()> + where + K: serde::ser::Serialize, + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn serialize_value(&mut self, value: &V) -> Result<()> + where + V: serde::ser::Serialize, + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl<'a, O: Options> serde::ser::SerializeStruct for SizeCompound<'a, O> { + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_field(&mut self, _key: &'static str, value: &T) -> Result<()> + where + T: serde::ser::Serialize, + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl<'a, O: Options> serde::ser::SerializeStructVariant for SizeCompound<'a, O> { + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_field(&mut self, _key: &'static str, value: &T) -> Result<()> + where + T: serde::ser::Serialize, + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} +const TAG_CONT: u8 = 0b1000_0000; +const TAG_TWO_B: u8 = 0b1100_0000; +const TAG_THREE_B: u8 = 0b1110_0000; +const TAG_FOUR_B: u8 = 0b1111_0000; +const MAX_ONE_B: u32 = 0x80; +const MAX_TWO_B: u32 = 0x800; +const MAX_THREE_B: u32 = 0x10000; + +fn encode_utf8(c: char) -> EncodeUtf8 { + let code = c as u32; + let mut buf = [0; 4]; + let pos = if code < MAX_ONE_B { + buf[3] = code as u8; + 3 + } else if code < MAX_TWO_B { + buf[2] = (code >> 6 & 0x1F) as u8 | TAG_TWO_B; + buf[3] = (code & 0x3F) as u8 | TAG_CONT; + 2 + } else if code < MAX_THREE_B { + buf[1] = (code >> 12 & 0x0F) as u8 | TAG_THREE_B; + buf[2] = (code >> 6 & 0x3F) as u8 | TAG_CONT; + buf[3] = (code & 0x3F) as u8 | TAG_CONT; + 1 + } else { + buf[0] = (code >> 18 & 0x07) as u8 | TAG_FOUR_B; + buf[1] = (code >> 12 & 0x3F) as u8 | TAG_CONT; + buf[2] = (code >> 6 & 0x3F) as u8 | TAG_CONT; + buf[3] = (code & 0x3F) as u8 | TAG_CONT; + 0 + }; + EncodeUtf8 { buf, pos } +} + +struct EncodeUtf8 { + buf: [u8; 4], + pos: usize, +} + +impl EncodeUtf8 { + fn as_slice(&self) -> &[u8] { + &self.buf[self.pos..] + } +} -- cgit v1.2.3