diff options
author | Andrew Gallant <jamslam@gmail.com> | 2015-04-24 23:20:18 -0400 |
---|---|---|
committer | Andrew Gallant <jamslam@gmail.com> | 2015-04-24 23:20:18 -0400 |
commit | d9c9ee3bed2e4839a345a03b429074330902d800 (patch) | |
tree | 21f60af0ffc5a0f43636f7a8014364f942199f70 /src | |
parent | 3fd22fda1c1d4e3af391f5c6c0aab05314ec2bef (diff) | |
download | byteorder-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.rs | 123 | ||||
-rw-r--r-- | src/new.rs | 36 |
2 files changed, 72 insertions, 87 deletions
@@ -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)); } }); } @@ -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) } } |