From c44b5e364e7084cdbabf9f94b63a3c7f32b8fb68 Mon Sep 17 00:00:00 2001 From: Zoey Riordan Date: Sat, 10 Apr 2021 12:56:36 +0200 Subject: [PATCH] remove byteorder as a dependency (#390) * remove byteorder as a dependency * fix module imports --- Cargo.toml | 3 +- src/byteorder.rs | 385 +++++++++++++++++++++++++++++++++++++++++++ src/config/endian.rs | 10 +- src/lib.rs | 4 +- tests/test.rs | 1 - 5 files changed, 392 insertions(+), 11 deletions(-) create mode 100644 src/byteorder.rs diff --git a/Cargo.toml b/Cargo.toml index 1627f4783..0fa360436 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bincode" -version = "1.3.2" # remember to update html_root_url +version = "1.3.3" # remember to update html_root_url authors = ["Ty Overby ", "Francesco Mazzoli ", "David Tolnay ", "Zoey Riordan "] exclude = ["logo.png", "examples/*", ".gitignore", ".travis.yml"] @@ -16,7 +16,6 @@ license = "MIT" description = "A binary serialization / deserialization strategy that uses Serde for transforming structs into bytes and vice versa!" [dependencies] -byteorder = ">=1.3.0, < 1.4.0" serde = "1.0.63" [dev-dependencies] diff --git a/src/byteorder.rs b/src/byteorder.rs new file mode 100644 index 000000000..67fc4626c --- /dev/null +++ b/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/src/config/endian.rs b/src/config/endian.rs index 4d924bf0d..1493252be 100644 --- a/src/config/endian.rs +++ b/src/config/endian.rs @@ -1,7 +1,5 @@ -use byteorder::{self, ByteOrder}; - pub trait BincodeByteOrder { - type Endian: ByteOrder + 'static; + type Endian: ::byteorder::ByteOrder + 'static; } /// Little-endian byte ordering. @@ -17,13 +15,13 @@ pub struct BigEndian; pub struct NativeEndian; impl BincodeByteOrder for LittleEndian { - type Endian = byteorder::LittleEndian; + type Endian = ::byteorder::LittleEndian; } impl BincodeByteOrder for BigEndian { - type Endian = byteorder::BigEndian; + type Endian = ::byteorder::BigEndian; } impl BincodeByteOrder for NativeEndian { - type Endian = byteorder::NativeEndian; + type Endian = ::byteorder::NativeEndian; } diff --git a/src/lib.rs b/src/lib.rs index c1e19bac6..773dee0d8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -24,12 +24,11 @@ //! 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.2")] +#![doc(html_root_url = "https://docs.rs/bincode/1.3.3")] #![crate_name = "bincode"] #![crate_type = "rlib"] #![crate_type = "dylib"] -extern crate byteorder; #[macro_use] extern crate serde; @@ -37,6 +36,7 @@ pub mod config; /// Deserialize bincode data to a Rust data structure. pub mod de; +mod byteorder; mod error; mod internal; mod ser; diff --git a/tests/test.rs b/tests/test.rs index 82fba86c6..d0b147de5 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -2,7 +2,6 @@ extern crate serde_derive; extern crate bincode; -extern crate byteorder; #[macro_use] extern crate serde; extern crate serde_bytes;