Skip to content

Commit

Permalink
Remove byteorder dependency (#280)
Browse files Browse the repository at this point in the history
  • Loading branch information
Douman authored and carllerche committed Aug 11, 2019
1 parent b5d4f87 commit 234d814
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 117 deletions.
1 change: 0 additions & 1 deletion Cargo.toml
Expand Up @@ -20,7 +20,6 @@ edition = "2018"
publish = false

[dependencies]
byteorder = "1.3"
serde = { version = "1.0", optional = true }
either = { version = "1.5", default-features = false, optional = true }

Expand Down
90 changes: 48 additions & 42 deletions src/buf/buf.rs
@@ -1,38 +1,44 @@
use super::{IntoBuf, Take, Reader, FromBuf, Chain};
use byteorder::{BigEndian, ByteOrder, LittleEndian};

use std::{cmp, io::IoSlice, ptr};
use std::{cmp, io::IoSlice, ptr, mem};

macro_rules! buf_get_impl {
($this:ident, $size:expr, $conv:path) => ({
($this:ident, $typ:tt::$conv:tt) => ({
const SIZE: usize = mem::size_of::<$typ>();
// try to convert directly from the bytes
let ret = {
// this Option<ret> trick is to avoid keeping a borrow on self
// when advance() is called (mut borrow) and to call bytes() only once
if let Some(src) = $this.bytes().get(..($size)) {
Some($conv(src))
} else {
None
}
};
// this Option<ret> trick is to avoid keeping a borrow on self
// when advance() is called (mut borrow) and to call bytes() only once
let ret = $this.bytes().get(..SIZE).map(|src| unsafe {
$typ::$conv(*(src as *const _ as *const [_; SIZE]))
});

if let Some(ret) = ret {
// if the direct conversion was possible, advance and return
$this.advance($size);
$this.advance(SIZE);
return ret;
} else {
// if not we copy the bytes in a temp buffer then convert
let mut buf = [0; ($size)];
let mut buf = [0; SIZE];
$this.copy_to_slice(&mut buf); // (do the advance)
return $conv(&buf);
return $typ::$conv(buf);
}
});
($this:ident, $buf_size:expr, $conv:path, $len_to_read:expr) => ({
(le => $this:ident, $typ:tt, $len_to_read:expr) => ({
debug_assert!(mem::size_of::<$typ>() >= $len_to_read);

// The same trick as above does not improve the best case speed.
// It seems to be linked to the way the method is optimised by the compiler
let mut buf = [0; ($buf_size)];
let mut buf = [0; (mem::size_of::<$typ>())];
$this.copy_to_slice(&mut buf[..($len_to_read)]);
return $conv(&buf[..($len_to_read)], $len_to_read);
return $typ::from_le_bytes(buf);
});
(be => $this:ident, $typ:tt, $len_to_read:expr) => {{
debug_assert!(mem::size_of::<$typ>() >= $len_to_read);

let mut buf = [0; (mem::size_of::<$typ>())];
$this.copy_to_slice(&mut buf[mem::size_of::<$typ>()-($len_to_read)..]);
return $typ::from_be_bytes(buf);
}};
}

/// Read bytes from a buffer.
Expand Down Expand Up @@ -314,7 +320,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_u16(&mut self) -> u16 {
buf_get_impl!(self, 2, BigEndian::read_u16);
buf_get_impl!(self, u16::from_be_bytes);
}

/// Gets an unsigned 16 bit integer from `self` in little-endian byte order.
Expand All @@ -334,7 +340,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_u16_le(&mut self) -> u16 {
buf_get_impl!(self, 2, LittleEndian::read_u16);
buf_get_impl!(self, u16::from_le_bytes);
}

/// Gets a signed 16 bit integer from `self` in big-endian byte order.
Expand All @@ -354,7 +360,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_i16(&mut self) -> i16 {
buf_get_impl!(self, 2, BigEndian::read_i16);
buf_get_impl!(self, i16::from_be_bytes);
}

/// Gets a signed 16 bit integer from `self` in little-endian byte order.
Expand All @@ -374,7 +380,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_i16_le(&mut self) -> i16 {
buf_get_impl!(self, 2, LittleEndian::read_i16);
buf_get_impl!(self, i16::from_le_bytes);
}

/// Gets an unsigned 32 bit integer from `self` in the big-endian byte order.
Expand All @@ -394,7 +400,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_u32(&mut self) -> u32 {
buf_get_impl!(self, 4, BigEndian::read_u32);
buf_get_impl!(self, u32::from_be_bytes);
}

/// Gets an unsigned 32 bit integer from `self` in the little-endian byte order.
Expand All @@ -414,7 +420,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_u32_le(&mut self) -> u32 {
buf_get_impl!(self, 4, LittleEndian::read_u32);
buf_get_impl!(self, u32::from_le_bytes);
}

/// Gets a signed 32 bit integer from `self` in big-endian byte order.
Expand All @@ -434,7 +440,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_i32(&mut self) -> i32 {
buf_get_impl!(self, 4, BigEndian::read_i32);
buf_get_impl!(self, i32::from_be_bytes);
}

/// Gets a signed 32 bit integer from `self` in little-endian byte order.
Expand All @@ -454,7 +460,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_i32_le(&mut self) -> i32 {
buf_get_impl!(self, 4, LittleEndian::read_i32);
buf_get_impl!(self, i32::from_le_bytes);
}

/// Gets an unsigned 64 bit integer from `self` in big-endian byte order.
Expand All @@ -474,7 +480,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_u64(&mut self) -> u64 {
buf_get_impl!(self, 8, BigEndian::read_u64);
buf_get_impl!(self, u64::from_be_bytes);
}

/// Gets an unsigned 64 bit integer from `self` in little-endian byte order.
Expand All @@ -494,7 +500,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_u64_le(&mut self) -> u64 {
buf_get_impl!(self, 8, LittleEndian::read_u64);
buf_get_impl!(self, u64::from_le_bytes);
}

/// Gets a signed 64 bit integer from `self` in big-endian byte order.
Expand All @@ -514,7 +520,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_i64(&mut self) -> i64 {
buf_get_impl!(self, 8, BigEndian::read_i64);
buf_get_impl!(self, i64::from_be_bytes);
}

/// Gets a signed 64 bit integer from `self` in little-endian byte order.
Expand All @@ -534,7 +540,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_i64_le(&mut self) -> i64 {
buf_get_impl!(self, 8, LittleEndian::read_i64);
buf_get_impl!(self, i64::from_le_bytes);
}

/// Gets an unsigned 128 bit integer from `self` in big-endian byte order.
Expand All @@ -554,7 +560,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_u128(&mut self) -> u128 {
buf_get_impl!(self, 16, BigEndian::read_u128);
buf_get_impl!(self, u128::from_be_bytes);
}

/// Gets an unsigned 128 bit integer from `self` in little-endian byte order.
Expand All @@ -574,7 +580,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_u128_le(&mut self) -> u128 {
buf_get_impl!(self, 16, LittleEndian::read_u128);
buf_get_impl!(self, u128::from_le_bytes);
}

/// Gets a signed 128 bit integer from `self` in big-endian byte order.
Expand All @@ -594,7 +600,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_i128(&mut self) -> i128 {
buf_get_impl!(self, 16, BigEndian::read_i128);
buf_get_impl!(self, i128::from_be_bytes);
}

/// Gets a signed 128 bit integer from `self` in little-endian byte order.
Expand All @@ -614,7 +620,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_i128_le(&mut self) -> i128 {
buf_get_impl!(self, 16, LittleEndian::read_i128);
buf_get_impl!(self, i128::from_le_bytes);
}

/// Gets an unsigned n-byte integer from `self` in big-endian byte order.
Expand All @@ -634,7 +640,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_uint(&mut self, nbytes: usize) -> u64 {
buf_get_impl!(self, 8, BigEndian::read_uint, nbytes);
buf_get_impl!(be => self, u64, nbytes);
}

/// Gets an unsigned n-byte integer from `self` in little-endian byte order.
Expand All @@ -654,7 +660,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_uint_le(&mut self, nbytes: usize) -> u64 {
buf_get_impl!(self, 8, LittleEndian::read_uint, nbytes);
buf_get_impl!(le => self, u64, nbytes);
}

/// Gets a signed n-byte integer from `self` in big-endian byte order.
Expand All @@ -674,7 +680,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_int(&mut self, nbytes: usize) -> i64 {
buf_get_impl!(self, 8, BigEndian::read_int, nbytes);
buf_get_impl!(be => self, i64, nbytes);
}

/// Gets a signed n-byte integer from `self` in little-endian byte order.
Expand All @@ -694,7 +700,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_int_le(&mut self, nbytes: usize) -> i64 {
buf_get_impl!(self, 8, LittleEndian::read_int, nbytes);
buf_get_impl!(le => self, i64, nbytes);
}

/// Gets an IEEE754 single-precision (4 bytes) floating point number from
Expand All @@ -715,7 +721,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_f32(&mut self) -> f32 {
buf_get_impl!(self, 4, BigEndian::read_f32);
f32::from_bits(Self::get_u32(self))
}

/// Gets an IEEE754 single-precision (4 bytes) floating point number from
Expand All @@ -736,7 +742,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_f32_le(&mut self) -> f32 {
buf_get_impl!(self, 4, LittleEndian::read_f32);
f32::from_bits(Self::get_u32_le(self))
}

/// Gets an IEEE754 double-precision (8 bytes) floating point number from
Expand All @@ -757,7 +763,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_f64(&mut self) -> f64 {
buf_get_impl!(self, 8, BigEndian::read_f64);
f64::from_bits(Self::get_u64(self))
}

/// Gets an IEEE754 double-precision (8 bytes) floating point number from
Expand All @@ -778,7 +784,7 @@ pub trait Buf {
///
/// This function panics if there is not enough remaining data in `self`.
fn get_f64_le(&mut self) -> f64 {
buf_get_impl!(self, 8, LittleEndian::read_f64);
f64::from_bits(Self::get_u64_le(self))
}

/// Transforms a `Buf` into a concrete buffer.
Expand Down

0 comments on commit 234d814

Please sign in to comment.