aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Gallant <jamslam@gmail.com>2015-04-24 23:20:18 -0400
committerAndrew Gallant <jamslam@gmail.com>2015-04-24 23:20:18 -0400
commitd9c9ee3bed2e4839a345a03b429074330902d800 (patch)
tree21f60af0ffc5a0f43636f7a8014364f942199f70 /src
parent3fd22fda1c1d4e3af391f5c6c0aab05314ec2bef (diff)
downloadbyteorder-d9c9ee3bed2e4839a345a03b429074330902d800.tar.gz
Improvements after being poked by @joshtriplett. Thanks!
1. The syntax <T as ByteOrder>::foo() is no longer needed. The docs/code has been updated to just use T::foo(). 2. An extraneous `copy_nonoverlapping` was removed in some cases. Benchmarks show no difference (probably due to llvm being smart to elide it in the first place). 3. A regression test was added to ensure that the `uint` case for little endian decoding remains correct even when decoding a smaller integer from a larger buffer.
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs123
-rw-r--r--src/new.rs36
2 files changed, 72 insertions, 87 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 0cdfc02..52cab1b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -58,7 +58,7 @@ fn extend_sign(val: u64, nbytes: usize) -> i64 {
///
/// Note that `Self` does not appear anywhere in this trait's definition!
/// Therefore, in order to use it, you'll need to use syntax like
-/// `<T as ByteOrder>::read_u16(&[0, 1])` where `T` implements `ByteOrder`.
+/// `T::read_u16(&[0, 1])` where `T` implements `ByteOrder`.
///
/// This crate provides two types that implement `ByteOrder`: `BigEndian`
/// and `LittleEndian`.
@@ -71,8 +71,8 @@ fn extend_sign(val: u64, nbytes: usize) -> i64 {
/// use byteorder::{ByteOrder, LittleEndian};
///
/// let mut buf = [0; 4];
-/// <LittleEndian as ByteOrder>::write_u32(&mut buf, 1_000_000);
-/// assert_eq!(1_000_000, <LittleEndian as ByteOrder>::read_u32(&buf));
+/// LittleEndian::write_u32(&mut buf, 1_000_000);
+/// assert_eq!(1_000_000, LittleEndian::read_u32(&buf));
/// ```
///
/// Write and read `i16` numbers in big endian order:
@@ -81,8 +81,8 @@ fn extend_sign(val: u64, nbytes: usize) -> i64 {
/// use byteorder::{ByteOrder, BigEndian};
///
/// let mut buf = [0; 2];
-/// <BigEndian as ByteOrder>::write_i16(&mut buf, -50_000);
-/// assert_eq!(-50_000, <BigEndian as ByteOrder>::read_i16(&buf));
+/// BigEndian::write_i16(&mut buf, -50_000);
+/// assert_eq!(-50_000, BigEndian::read_i16(&buf));
/// ```
pub trait ByteOrder {
/// Reads an unsigned 16 bit integer from `buf`.
@@ -125,21 +125,21 @@ pub trait ByteOrder {
///
/// Task failure occurs when `buf.len() < 2`.
fn read_i16(buf: &[u8]) -> i16 {
- <Self as ByteOrder>::read_u16(buf) as i16
+ Self::read_u16(buf) as i16
}
/// Reads a signed 32 bit integer from `buf`.
///
/// Task failure occurs when `buf.len() < 4`.
fn read_i32(buf: &[u8]) -> i32 {
- <Self as ByteOrder>::read_u32(buf) as i32
+ Self::read_u32(buf) as i32
}
/// Reads a signed 64 bit integer from `buf`.
///
/// Task failure occurs when `buf.len() < 8`.
fn read_i64(buf: &[u8]) -> i64 {
- <Self as ByteOrder>::read_u64(buf) as i64
+ Self::read_u64(buf) as i64
}
/// Reads a signed n-bytes integer from `buf`.
@@ -147,56 +147,56 @@ pub trait ByteOrder {
/// Task failure occurs when `nbytes < 1` or `nbytes > 8` or
/// `buf.len() < nbytes`
fn read_int(buf: &[u8], nbytes: usize) -> i64 {
- extend_sign(<Self as ByteOrder>::read_uint(buf, nbytes), nbytes)
+ extend_sign(Self::read_uint(buf, nbytes), nbytes)
}
/// Reads a IEEE754 single-precision (4 bytes) floating point number.
///
/// Task failure occurs when `buf.len() < 4`.
fn read_f32(buf: &[u8]) -> f32 {
- unsafe { transmute(<Self as ByteOrder>::read_u32(buf)) }
+ unsafe { transmute(Self::read_u32(buf)) }
}
/// Reads a IEEE754 double-precision (8 bytes) floating point number.
///
/// Task failure occurs when `buf.len() < 8`.
fn read_f64(buf: &[u8]) -> f64 {
- unsafe { transmute(<Self as ByteOrder>::read_u64(buf)) }
+ unsafe { transmute(Self::read_u64(buf)) }
}
/// Writes a signed 16 bit integer `n` to `buf`.
///
/// Task failure occurs when `buf.len() < 2`.
fn write_i16(buf: &mut [u8], n: i16) {
- <Self as ByteOrder>::write_u16(buf, n as u16)
+ Self::write_u16(buf, n as u16)
}
/// Writes a signed 32 bit integer `n` to `buf`.
///
/// Task failure occurs when `buf.len() < 4`.
fn write_i32(buf: &mut [u8], n: i32) {
- <Self as ByteOrder>::write_u32(buf, n as u32)
+ Self::write_u32(buf, n as u32)
}
/// Writes a signed 64 bit integer `n` to `buf`.
///
/// Task failure occurs when `buf.len() < 8`.
fn write_i64(buf: &mut [u8], n: i64) {
- <Self as ByteOrder>::write_u64(buf, n as u64)
+ Self::write_u64(buf, n as u64)
}
/// Writes a IEEE754 single-precision (4 bytes) floating point number.
///
/// Task failure occurs when `buf.len() < 4`.
fn write_f32(buf: &mut [u8], n: f32) {
- <Self as ByteOrder>::write_u32(buf, unsafe { transmute(n) })
+ Self::write_u32(buf, unsafe { transmute(n) })
}
/// Writes a IEEE754 double-precision (8 bytes) floating point number.
///
/// Task failure occurs when `buf.len() < 8`.
fn write_f64(buf: &mut [u8], n: f64) {
- <Self as ByteOrder>::write_u64(buf, unsafe { transmute(n) })
+ Self::write_u64(buf, unsafe { transmute(n) })
}
}
@@ -228,14 +228,9 @@ pub type NativeEndian = BigEndian;
macro_rules! read_num_bytes {
($ty:ty, $size:expr, $src:expr, $which:ident) => ({
- use std::ptr::copy_nonoverlapping;
-
assert!($src.len() >= $size); // critical for memory safety!
- let mut out = [0u8; $size];
- let ptr_out = out.as_mut_ptr();
unsafe {
- copy_nonoverlapping($src.as_ptr(), ptr_out, $size);
- (*(ptr_out as *const $ty)).$which()
+ (*($src.as_ptr() as *const $ty)).$which()
}
});
($ty:ty, $size:expr, le $bytes:expr, $src:expr, $which:ident) => ({
@@ -367,9 +362,8 @@ mod test {
let max = ($max - 1) >> (8 * (8 - $bytes));
fn prop(n: $ty_int) -> bool {
let mut buf = [0; 8];
- <BigEndian as ByteOrder>::$write(&mut buf, n);
- n == <BigEndian as ByteOrder>::$read(
- &mut buf[8 - $bytes..], $bytes)
+ BigEndian::$write(&mut buf, n);
+ n == BigEndian::$read(&mut buf[8 - $bytes..], $bytes)
}
qc_sized(prop as fn($ty_int) -> bool, max);
}
@@ -379,9 +373,8 @@ mod test {
let max = ($max - 1) >> (8 * (8 - $bytes));
fn prop(n: $ty_int) -> bool {
let mut buf = [0; 8];
- <LittleEndian as ByteOrder>::$write(&mut buf, n);
- n == <LittleEndian as ByteOrder>::$read(
- &mut buf[..$bytes], $bytes)
+ LittleEndian::$write(&mut buf, n);
+ n == LittleEndian::$read(&mut buf[..$bytes], $bytes)
}
qc_sized(prop as fn($ty_int) -> bool, max);
}
@@ -391,9 +384,8 @@ mod test {
let max = ($max - 1) >> (8 * (8 - $bytes));
fn prop(n: $ty_int) -> bool {
let mut buf = [0; 8];
- <NativeEndian as ByteOrder>::$write(&mut buf, n);
- n == <NativeEndian as ByteOrder>::$read(
- &mut buf[..$bytes], $bytes)
+ NativeEndian::$write(&mut buf, n);
+ n == NativeEndian::$read(&mut buf[..$bytes], $bytes)
}
qc_sized(prop as fn($ty_int) -> bool, max);
}
@@ -411,10 +403,8 @@ mod test {
fn prop(n: $ty_int) -> bool {
let bytes = size_of::<$ty_int>();
let mut buf = [0; 8];
- <BigEndian as ByteOrder>::$write(
- &mut buf[8 - bytes..], n);
- n == <BigEndian as ByteOrder>::$read(
- &mut buf[8 - bytes..])
+ BigEndian::$write(&mut buf[8 - bytes..], n);
+ n == BigEndian::$read(&mut buf[8 - bytes..])
}
qc_sized(prop as fn($ty_int) -> bool, $max - 1);
}
@@ -424,10 +414,8 @@ mod test {
fn prop(n: $ty_int) -> bool {
let bytes = size_of::<$ty_int>();
let mut buf = [0; 8];
- <LittleEndian as ByteOrder>::$write(
- &mut buf[..bytes], n);
- n == <LittleEndian as ByteOrder>::$read(
- &mut buf[..bytes])
+ LittleEndian::$write(&mut buf[..bytes], n);
+ n == LittleEndian::$read(&mut buf[..bytes])
}
qc_sized(prop as fn($ty_int) -> bool, $max - 1);
}
@@ -437,10 +425,8 @@ mod test {
fn prop(n: $ty_int) -> bool {
let bytes = size_of::<$ty_int>();
let mut buf = [0; 8];
- <NativeEndian as ByteOrder>::$write(
- &mut buf[..bytes], n);
- n == <NativeEndian as ByteOrder>::$read(
- &mut buf[..bytes])
+ NativeEndian::$write(&mut buf[..bytes], n);
+ n == NativeEndian::$read(&mut buf[..bytes])
}
qc_sized(prop as fn($ty_int) -> bool, $max - 1);
}
@@ -612,42 +598,42 @@ mod test {
#[should_panic]
fn read_big_endian() {
let buf = [0; $maximally_small];
- <BigEndian as ByteOrder>::$read(&buf);
+ BigEndian::$read(&buf);
}
#[test]
#[should_panic]
fn read_little_endian() {
let buf = [0; $maximally_small];
- <LittleEndian as ByteOrder>::$read(&buf);
+ LittleEndian::$read(&buf);
}
#[test]
#[should_panic]
fn read_native_endian() {
let buf = [0; $maximally_small];
- <NativeEndian as ByteOrder>::$read(&buf);
+ NativeEndian::$read(&buf);
}
#[test]
#[should_panic]
fn write_big_endian() {
let mut buf = [0; $maximally_small];
- <BigEndian as ByteOrder>::$write(&mut buf, $zero);
+ BigEndian::$write(&mut buf, $zero);
}
#[test]
#[should_panic]
fn write_little_endian() {
let mut buf = [0; $maximally_small];
- <LittleEndian as ByteOrder>::$write(&mut buf, $zero);
+ LittleEndian::$write(&mut buf, $zero);
}
#[test]
#[should_panic]
fn write_native_endian() {
let mut buf = [0; $maximally_small];
- <NativeEndian as ByteOrder>::$write(&mut buf, $zero);
+ NativeEndian::$write(&mut buf, $zero);
}
}
);
@@ -659,24 +645,21 @@ mod test {
#[should_panic]
fn read_big_endian() {
let buf = [0; $maximally_small];
- <BigEndian as ByteOrder>::$read(&buf,
- $maximally_small + 1);
+ BigEndian::$read(&buf, $maximally_small + 1);
}
#[test]
#[should_panic]
fn read_little_endian() {
let buf = [0; $maximally_small];
- <LittleEndian as ByteOrder>::$read(&buf,
- $maximally_small + 1);
+ LittleEndian::$read(&buf, $maximally_small + 1);
}
#[test]
#[should_panic]
fn read_native_endian() {
let buf = [0; $maximally_small];
- <NativeEndian as ByteOrder>::$read(&buf,
- $maximally_small + 1);
+ NativeEndian::$read(&buf, $maximally_small + 1);
}
}
);
@@ -706,6 +689,13 @@ mod test {
too_small!(small_int_5, 5, read_int);
too_small!(small_int_6, 6, read_int);
too_small!(small_int_7, 7, read_int);
+
+ #[test]
+ fn uint_bigger_buffer() {
+ use {ByteOrder, LittleEndian};
+ let n = LittleEndian::read_uint(&[1, 2, 3, 4, 5, 6, 7, 8], 5);
+ assert_eq!(n, 0x0504030201);
+ }
}
#[cfg(test)]
@@ -726,8 +716,7 @@ mod bench {
let buf = $data;
b.iter(|| {
for _ in 0..NITER {
- bb(<BigEndian as ByteOrder>::$read(&buf,
- $bytes));
+ bb(BigEndian::$read(&buf, $bytes));
}
});
}
@@ -737,8 +726,7 @@ mod bench {
let buf = $data;
b.iter(|| {
for _ in 0..NITER {
- bb(<LittleEndian as ByteOrder>::$read(&buf,
- $bytes));
+ bb(LittleEndian::$read(&buf, $bytes));
}
});
}
@@ -748,8 +736,7 @@ mod bench {
let buf = $data;
b.iter(|| {
for _ in 0..NITER {
- bb(<NativeEndian as ByteOrder>::$read(&buf,
- $bytes));
+ bb(NativeEndian::$read(&buf, $bytes));
}
});
}
@@ -770,7 +757,7 @@ mod bench {
let buf = $data;
b.iter(|| {
for _ in 0..NITER {
- bb(<BigEndian as ByteOrder>::$read(&buf));
+ bb(BigEndian::$read(&buf));
}
});
}
@@ -780,7 +767,7 @@ mod bench {
let buf = $data;
b.iter(|| {
for _ in 0..NITER {
- bb(<LittleEndian as ByteOrder>::$read(&buf));
+ bb(LittleEndian::$read(&buf));
}
});
}
@@ -790,7 +777,7 @@ mod bench {
let buf = $data;
b.iter(|| {
for _ in 0..NITER {
- bb(<NativeEndian as ByteOrder>::$read(&buf));
+ bb(NativeEndian::$read(&buf));
}
});
}
@@ -801,7 +788,7 @@ mod bench {
let n = $ty::$max;
b.iter(|| {
for _ in 0..NITER {
- bb(<BigEndian as ByteOrder>::$write(&mut buf, n));
+ bb(BigEndian::$write(&mut buf, n));
}
});
}
@@ -812,8 +799,7 @@ mod bench {
let n = $ty::$max;
b.iter(|| {
for _ in 0..NITER {
- bb(<LittleEndian as ByteOrder>::$write(&mut buf,
- n));
+ bb(LittleEndian::$write(&mut buf, n));
}
});
}
@@ -824,8 +810,7 @@ mod bench {
let n = $ty::$max;
b.iter(|| {
for _ in 0..NITER {
- bb(<NativeEndian as ByteOrder>::$write(&mut buf,
- n));
+ bb(NativeEndian::$write(&mut buf, n));
}
});
}
diff --git a/src/new.rs b/src/new.rs
index 5a2fcb0..03b94cb 100644
--- a/src/new.rs
+++ b/src/new.rs
@@ -108,56 +108,56 @@ pub trait ReadBytesExt: io::Read {
fn read_u16<T: ByteOrder>(&mut self) -> Result<u16> {
let mut buf = [0; 2];
try!(read_full(self, &mut buf));
- Ok(<T as ByteOrder>::read_u16(&buf))
+ Ok(T::read_u16(&buf))
}
/// Reads a signed 16 bit integer from the underlying reader.
fn read_i16<T: ByteOrder>(&mut self) -> Result<i16> {
let mut buf = [0; 2];
try!(read_full(self, &mut buf));
- Ok(<T as ByteOrder>::read_i16(&buf))
+ Ok(T::read_i16(&buf))
}
/// Reads an unsigned 32 bit integer from the underlying reader.
fn read_u32<T: ByteOrder>(&mut self) -> Result<u32> {
let mut buf = [0; 4];
try!(read_full(self, &mut buf));
- Ok(<T as ByteOrder>::read_u32(&buf))
+ Ok(T::read_u32(&buf))
}
/// Reads a signed 32 bit integer from the underlying reader.
fn read_i32<T: ByteOrder>(&mut self) -> Result<i32> {
let mut buf = [0; 4];
try!(read_full(self, &mut buf));
- Ok(<T as ByteOrder>::read_i32(&buf))
+ Ok(T::read_i32(&buf))
}
/// Reads an unsigned 64 bit integer from the underlying reader.
fn read_u64<T: ByteOrder>(&mut self) -> Result<u64> {
let mut buf = [0; 8];
try!(read_full(self, &mut buf));
- Ok(<T as ByteOrder>::read_u64(&buf))
+ Ok(T::read_u64(&buf))
}
/// Reads a signed 64 bit integer from the underlying reader.
fn read_i64<T: ByteOrder>(&mut self) -> Result<i64> {
let mut buf = [0; 8];
try!(read_full(self, &mut buf));
- Ok(<T as ByteOrder>::read_i64(&buf))
+ Ok(T::read_i64(&buf))
}
/// Reads an unsigned n-bytes integer from the underlying reader.
fn read_uint<T: ByteOrder>(&mut self, nbytes: usize) -> Result<u64> {
let mut buf = [0; 8];
try!(read_full(self, &mut buf[..nbytes]));
- Ok(<T as ByteOrder>::read_uint(&buf[..nbytes], nbytes))
+ Ok(T::read_uint(&buf[..nbytes], nbytes))
}
/// Reads a signed n-bytes integer from the underlying reader.
fn read_int<T: ByteOrder>(&mut self, nbytes: usize) -> Result<i64> {
let mut buf = [0; 8];
try!(read_full(self, &mut buf[..nbytes]));
- Ok(<T as ByteOrder>::read_int(&buf[..nbytes], nbytes))
+ Ok(T::read_int(&buf[..nbytes], nbytes))
}
/// Reads a IEEE754 single-precision (4 bytes) floating point number from
@@ -165,7 +165,7 @@ pub trait ReadBytesExt: io::Read {
fn read_f32<T: ByteOrder>(&mut self) -> Result<f32> {
let mut buf = [0; 4];
try!(read_full(self, &mut buf));
- Ok(<T as ByteOrder>::read_f32(&buf))
+ Ok(T::read_f32(&buf))
}
/// Reads a IEEE754 double-precision (8 bytes) floating point number from
@@ -173,7 +173,7 @@ pub trait ReadBytesExt: io::Read {
fn read_f64<T: ByteOrder>(&mut self) -> Result<f64> {
let mut buf = [0; 8];
try!(read_full(self, &mut buf));
- Ok(<T as ByteOrder>::read_f64(&buf))
+ Ok(T::read_f64(&buf))
}
}
@@ -236,42 +236,42 @@ pub trait WriteBytesExt: io::Write {
/// Writes an unsigned 16 bit integer to the underlying writer.
fn write_u16<T: ByteOrder>(&mut self, n: u16) -> Result<()> {
let mut buf = [0; 2];
- <T as ByteOrder>::write_u16(&mut buf, n);
+ T::write_u16(&mut buf, n);
write_all(self, &buf)
}
/// Writes a signed 16 bit integer to the underlying writer.
fn write_i16<T: ByteOrder>(&mut self, n: i16) -> Result<()> {
let mut buf = [0; 2];
- <T as ByteOrder>::write_i16(&mut buf, n);
+ T::write_i16(&mut buf, n);
write_all(self, &buf)
}
/// Writes an unsigned 32 bit integer to the underlying writer.
fn write_u32<T: ByteOrder>(&mut self, n: u32) -> Result<()> {
let mut buf = [0; 4];
- <T as ByteOrder>::write_u32(&mut buf, n);
+ T::write_u32(&mut buf, n);
write_all(self, &buf)
}
/// Writes a signed 32 bit integer to the underlying writer.
fn write_i32<T: ByteOrder>(&mut self, n: i32) -> Result<()> {
let mut buf = [0; 4];
- <T as ByteOrder>::write_i32(&mut buf, n);
+ T::write_i32(&mut buf, n);
write_all(self, &buf)
}
/// Writes an unsigned 64 bit integer to the underlying writer.
fn write_u64<T: ByteOrder>(&mut self, n: u64) -> Result<()> {
let mut buf = [0; 8];
- <T as ByteOrder>::write_u64(&mut buf, n);
+ T::write_u64(&mut buf, n);
write_all(self, &buf)
}
/// Writes a signed 64 bit integer to the underlying writer.
fn write_i64<T: ByteOrder>(&mut self, n: i64) -> Result<()> {
let mut buf = [0; 8];
- <T as ByteOrder>::write_i64(&mut buf, n);
+ T::write_i64(&mut buf, n);
write_all(self, &buf)
}
@@ -279,7 +279,7 @@ pub trait WriteBytesExt: io::Write {
/// the underlying writer.
fn write_f32<T: ByteOrder>(&mut self, n: f32) -> Result<()> {
let mut buf = [0; 4];
- <T as ByteOrder>::write_f32(&mut buf, n);
+ T::write_f32(&mut buf, n);
write_all(self, &buf)
}
@@ -287,7 +287,7 @@ pub trait WriteBytesExt: io::Write {
/// the underlying writer.
fn write_f64<T: ByteOrder>(&mut self, n: f64) -> Result<()> {
let mut buf = [0; 8];
- <T as ByteOrder>::write_f64(&mut buf, n);
+ T::write_f64(&mut buf, n);
write_all(self, &buf)
}
}