/*! This crate provides convenience methods for encoding and decoding numbers in either [big-endian or little-endian order]. The organization of the crate is pretty simple. A trait, [`ByteOrder`], specifies byte conversion methods for each type of number in Rust (sans numbers that have a platform dependent size like `usize` and `isize`). Two types, [`BigEndian`] and [`LittleEndian`] implement these methods. Finally, [`ReadBytesExt`] and [`WriteBytesExt`] provide convenience methods available to all types that implement [`Read`] and [`Write`]. An alias, [`NetworkEndian`], for [`BigEndian`] is provided to help improve code clarity. An additional alias, [`NativeEndian`], is provided for the endianness of the local platform. This is convenient when serializing data for use and conversions are not desired. # Examples Read unsigned 16 bit big-endian integers from a [`Read`] type: ```rust use std::io::Cursor; use byteorder::{BigEndian, ReadBytesExt}; let mut rdr = Cursor::new(vec![2, 5, 3, 0]); // Note that we use type parameters to indicate which kind of byte order // we want! assert_eq!(517, rdr.read_u16::().unwrap()); assert_eq!(768, rdr.read_u16::().unwrap()); ``` Write unsigned 16 bit little-endian integers to a [`Write`] type: ```rust use byteorder::{LittleEndian, WriteBytesExt}; let mut wtr = vec![]; wtr.write_u16::(517).unwrap(); wtr.write_u16::(768).unwrap(); assert_eq!(wtr, vec![5, 2, 0, 3]); ``` # Optional Features This crate optionally provides support for 128 bit values (`i128` and `u128`) when built with the `i128` feature enabled. This crate can also be used without the standard library. # Alternatives Note that as of Rust 1.32, the standard numeric types provide built-in methods like `to_le_bytes` and `from_le_bytes`, which support some of the same use cases. [big-endian or little-endian order]: https://en.wikipedia.org/wiki/Endianness [`ByteOrder`]: trait.ByteOrder.html [`BigEndian`]: enum.BigEndian.html [`LittleEndian`]: enum.LittleEndian.html [`ReadBytesExt`]: trait.ReadBytesExt.html [`WriteBytesExt`]: trait.WriteBytesExt.html [`NetworkEndian`]: type.NetworkEndian.html [`NativeEndian`]: type.NativeEndian.html [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html */ #![deny(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] use core::{ convert::TryInto, fmt::Debug, hash::Hash, ptr::copy_nonoverlapping, slice, }; #[cfg(feature = "std")] pub use crate::io::{ReadBytesExt, WriteBytesExt}; #[cfg(feature = "std")] mod io; #[inline] fn extend_sign(val: u64, nbytes: usize) -> i64 { let shift = (8 - nbytes) * 8; (val << shift) as i64 >> shift } #[inline] fn extend_sign128(val: u128, nbytes: usize) -> i128 { let shift = (16 - nbytes) * 8; (val << shift) as i128 >> shift } #[inline] fn unextend_sign(val: i64, nbytes: usize) -> u64 { let shift = (8 - nbytes) * 8; (val << shift) as u64 >> shift } #[inline] fn unextend_sign128(val: i128, nbytes: usize) -> u128 { let shift = (16 - nbytes) * 8; (val << shift) as u128 >> shift } #[inline] fn pack_size(n: u64) -> usize { if n < 1 << 8 { 1 } else if n < 1 << 16 { 2 } else if n < 1 << 24 { 3 } else if n < 1 << 32 { 4 } else if n < 1 << 40 { 5 } else if n < 1 << 48 { 6 } else if n < 1 << 56 { 7 } else { 8 } } #[inline] fn pack_size128(n: u128) -> usize { if n < 1 << 8 { 1 } else if n < 1 << 16 { 2 } else if n < 1 << 24 { 3 } else if n < 1 << 32 { 4 } else if n < 1 << 40 { 5 } else if n < 1 << 48 { 6 } else if n < 1 << 56 { 7 } else if n < 1 << 64 { 8 } else if n < 1 << 72 { 9 } else if n < 1 << 80 { 10 } else if n < 1 << 88 { 11 } else if n < 1 << 96 { 12 } else if n < 1 << 104 { 13 } else if n < 1 << 112 { 14 } else if n < 1 << 120 { 15 } else { 16 } } mod private { /// Sealed stops crates other than byteorder from implementing any traits /// that use it. pub trait Sealed {} impl Sealed for super::LittleEndian {} impl Sealed for super::BigEndian {} } /// `ByteOrder` describes types that can serialize integers as bytes. /// /// 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::read_u16(&[0, 1])` where `T` implements `ByteOrder`. /// /// This crate provides two types that implement `ByteOrder`: [`BigEndian`] /// and [`LittleEndian`]. /// This trait is sealed and cannot be implemented for callers to avoid /// breaking backwards compatibility when adding new derived traits. /// /// # Examples /// /// Write and read `u32` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut buf = [0; 4]; /// 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: /// /// ```rust /// use byteorder::{ByteOrder, BigEndian}; /// /// let mut buf = [0; 2]; /// BigEndian::write_i16(&mut buf, -5_000); /// assert_eq!(-5_000, BigEndian::read_i16(&buf)); /// ``` /// /// [`BigEndian`]: enum.BigEndian.html /// [`LittleEndian`]: enum.LittleEndian.html pub trait ByteOrder: Clone + Copy + Debug + Default + Eq + Hash + Ord + PartialEq + PartialOrd + private::Sealed { /// Reads an unsigned 16 bit integer from `buf`. /// /// # Panics /// /// Panics when `buf.len() < 2`. fn read_u16(buf: &[u8]) -> u16; /// Reads an unsigned 24 bit integer from `buf`, stored in u32. /// /// # Panics /// /// Panics when `buf.len() < 3`. /// /// # Examples /// /// Write and read 24 bit `u32` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut buf = [0; 3]; /// LittleEndian::write_u24(&mut buf, 1_000_000); /// assert_eq!(1_000_000, LittleEndian::read_u24(&buf)); /// ``` fn read_u24(buf: &[u8]) -> u32 { Self::read_uint(buf, 3) as u32 } /// Reads an unsigned 32 bit integer from `buf`. /// /// # Panics /// /// Panics when `buf.len() < 4`. /// /// # Examples /// /// Write and read `u32` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut buf = [0; 4]; /// LittleEndian::write_u32(&mut buf, 1_000_000); /// assert_eq!(1_000_000, LittleEndian::read_u32(&buf)); /// ``` fn read_u32(buf: &[u8]) -> u32; /// Reads an unsigned 48 bit integer from `buf`, stored in u64. /// /// # Panics /// /// Panics when `buf.len() < 6`. /// /// # Examples /// /// Write and read 48 bit `u64` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut buf = [0; 6]; /// LittleEndian::write_u48(&mut buf, 1_000_000_000_000); /// assert_eq!(1_000_000_000_000, LittleEndian::read_u48(&buf)); /// ``` fn read_u48(buf: &[u8]) -> u64 { Self::read_uint(buf, 6) as u64 } /// Reads an unsigned 64 bit integer from `buf`. /// /// # Panics /// /// Panics when `buf.len() < 8`. /// /// # Examples /// /// Write and read `u64` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut buf = [0; 8]; /// LittleEndian::write_u64(&mut buf, 1_000_000); /// assert_eq!(1_000_000, LittleEndian::read_u64(&buf)); /// ``` fn read_u64(buf: &[u8]) -> u64; /// Reads an unsigned 128 bit integer from `buf`. /// /// # Panics /// /// Panics when `buf.len() < 16`. /// /// # Examples /// /// Write and read `u128` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut buf = [0; 16]; /// LittleEndian::write_u128(&mut buf, 1_000_000); /// assert_eq!(1_000_000, LittleEndian::read_u128(&buf)); /// ``` fn read_u128(buf: &[u8]) -> u128; /// Reads an unsigned n-bytes integer from `buf`. /// /// # Panics /// /// Panics when `nbytes < 1` or `nbytes > 8` or /// `buf.len() < nbytes` /// /// # Examples /// /// Write and read an n-byte number in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut buf = [0; 3]; /// LittleEndian::write_uint(&mut buf, 1_000_000, 3); /// assert_eq!(1_000_000, LittleEndian::read_uint(&buf, 3)); /// ``` fn read_uint(buf: &[u8], nbytes: usize) -> u64; /// Reads an unsigned n-bytes integer from `buf`. /// /// # Panics /// /// Panics when `nbytes < 1` or `nbytes > 16` or /// `buf.len() < nbytes` /// /// # Examples /// /// Write and read an n-byte number in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut buf = [0; 3]; /// LittleEndian::write_uint128(&mut buf, 1_000_000, 3); /// assert_eq!(1_000_000, LittleEndian::read_uint128(&buf, 3)); /// ``` fn read_uint128(buf: &[u8], nbytes: usize) -> u128; /// Writes an unsigned 16 bit integer `n` to `buf`. /// /// # Panics /// /// Panics when `buf.len() < 2`. /// /// # Examples /// /// Write and read `u16` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut buf = [0; 2]; /// LittleEndian::write_u16(&mut buf, 1_000); /// assert_eq!(1_000, LittleEndian::read_u16(&buf)); /// ``` fn write_u16(buf: &mut [u8], n: u16); /// Writes an unsigned 24 bit integer `n` to `buf`, stored in u32. /// /// # Panics /// /// Panics when `buf.len() < 3`. /// /// # Examples /// /// Write and read 24 bit `u32` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut buf = [0; 3]; /// LittleEndian::write_u24(&mut buf, 1_000_000); /// assert_eq!(1_000_000, LittleEndian::read_u24(&buf)); /// ``` fn write_u24(buf: &mut [u8], n: u32) { Self::write_uint(buf, n as u64, 3) } /// Writes an unsigned 32 bit integer `n` to `buf`. /// /// # Panics /// /// Panics when `buf.len() < 4`. /// /// # Examples /// /// Write and read `u32` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut buf = [0; 4]; /// LittleEndian::write_u32(&mut buf, 1_000_000); /// assert_eq!(1_000_000, LittleEndian::read_u32(&buf)); /// ``` fn write_u32(buf: &mut [u8], n: u32); /// Writes an unsigned 48 bit integer `n` to `buf`, stored in u64. /// /// # Panics /// /// Panics when `buf.len() < 6`. /// /// # Examples /// /// Write and read 48 bit `u64` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut buf = [0; 6]; /// LittleEndian::write_u48(&mut buf, 1_000_000_000_000); /// assert_eq!(1_000_000_000_000, LittleEndian::read_u48(&buf)); /// ``` fn write_u48(buf: &mut [u8], n: u64) { Self::write_uint(buf, n as u64, 6) } /// Writes an unsigned 64 bit integer `n` to `buf`. /// /// # Panics /// /// Panics when `buf.len() < 8`. /// /// # Examples /// /// Write and read `u64` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut buf = [0; 8]; /// LittleEndian::write_u64(&mut buf, 1_000_000); /// assert_eq!(1_000_000, LittleEndian::read_u64(&buf)); /// ``` fn write_u64(buf: &mut [u8], n: u64); /// Writes an unsigned 128 bit integer `n` to `buf`. /// /// # Panics /// /// Panics when `buf.len() < 16`. /// /// # Examples /// /// Write and read `u128` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut buf = [0; 16]; /// LittleEndian::write_u128(&mut buf, 1_000_000); /// assert_eq!(1_000_000, LittleEndian::read_u128(&buf)); /// ``` fn write_u128(buf: &mut [u8], n: u128); /// Writes an unsigned integer `n` to `buf` using only `nbytes`. /// /// # Panics /// /// If `n` is not representable in `nbytes`, or if `nbytes` is `> 8`, then /// this method panics. /// /// # Examples /// /// Write and read an n-byte number in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut buf = [0; 3]; /// LittleEndian::write_uint(&mut buf, 1_000_000, 3); /// assert_eq!(1_000_000, LittleEndian::read_uint(&buf, 3)); /// ``` fn write_uint(buf: &mut [u8], n: u64, nbytes: usize); /// Writes an unsigned integer `n` to `buf` using only `nbytes`. /// /// # Panics /// /// If `n` is not representable in `nbytes`, or if `nbytes` is `> 16`, then /// this method panics. /// /// # Examples /// /// Write and read an n-byte number in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut buf = [0; 3]; /// LittleEndian::write_uint128(&mut buf, 1_000_000, 3); /// assert_eq!(1_000_000, LittleEndian::read_uint128(&buf, 3)); /// ``` fn write_uint128(buf: &mut [u8], n: u128, nbytes: usize); /// Reads a signed 16 bit integer from `buf`. /// /// # Panics /// /// Panics when `buf.len() < 2`. /// /// # Examples /// /// Write and read `i16` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut buf = [0; 2]; /// LittleEndian::write_i16(&mut buf, -1_000); /// assert_eq!(-1_000, LittleEndian::read_i16(&buf)); /// ``` #[inline] fn read_i16(buf: &[u8]) -> i16 { Self::read_u16(buf) as i16 } /// Reads a signed 24 bit integer from `buf`, stored in i32. /// /// # Panics /// /// Panics when `buf.len() < 3`. /// /// # Examples /// /// Write and read 24 bit `i32` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut buf = [0; 3]; /// LittleEndian::write_i24(&mut buf, -1_000_000); /// assert_eq!(-1_000_000, LittleEndian::read_i24(&buf)); /// ``` #[inline] fn read_i24(buf: &[u8]) -> i32 { Self::read_int(buf, 3) as i32 } /// Reads a signed 32 bit integer from `buf`. /// /// # Panics /// /// Panics when `buf.len() < 4`. /// /// # Examples /// /// Write and read `i32` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut buf = [0; 4]; /// LittleEndian::write_i32(&mut buf, -1_000_000); /// assert_eq!(-1_000_000, LittleEndian::read_i32(&buf)); /// ``` #[inline] fn read_i32(buf: &[u8]) -> i32 { Self::read_u32(buf) as i32 } /// Reads a signed 48 bit integer from `buf`, stored in i64. /// /// # Panics /// /// Panics when `buf.len() < 6`. /// /// # Examples /// /// Write and read 48 bit `i64` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut buf = [0; 6]; /// LittleEndian::write_i48(&mut buf, -1_000_000_000_000); /// assert_eq!(-1_000_000_000_000, LittleEndian::read_i48(&buf)); /// ``` #[inline] fn read_i48(buf: &[u8]) -> i64 { Self::read_int(buf, 6) as i64 } /// Reads a signed 64 bit integer from `buf`. /// /// # Panics /// /// Panics when `buf.len() < 8`. /// /// # Examples /// /// Write and read `i64` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut buf = [0; 8]; /// LittleEndian::write_i64(&mut buf, -1_000_000_000); /// assert_eq!(-1_000_000_000, LittleEndian::read_i64(&buf)); /// ``` #[inline] fn read_i64(buf: &[u8]) -> i64 { Self::read_u64(buf) as i64 } /// Reads a signed 128 bit integer from `buf`. /// /// # Panics /// /// Panics when `buf.len() < 16`. /// /// # Examples /// /// Write and read `i128` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut buf = [0; 16]; /// LittleEndian::write_i128(&mut buf, -1_000_000_000); /// assert_eq!(-1_000_000_000, LittleEndian::read_i128(&buf)); /// ``` #[inline] fn read_i128(buf: &[u8]) -> i128 { Self::read_u128(buf) as i128 } /// Reads a signed n-bytes integer from `buf`. /// /// # Panics /// /// Panics when `nbytes < 1` or `nbytes > 8` or /// `buf.len() < nbytes` /// /// # Examples /// /// Write and read n-length signed numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut buf = [0; 3]; /// LittleEndian::write_int(&mut buf, -1_000, 3); /// assert_eq!(-1_000, LittleEndian::read_int(&buf, 3)); /// ``` #[inline] fn read_int(buf: &[u8], nbytes: usize) -> i64 { extend_sign(Self::read_uint(buf, nbytes), nbytes) } /// Reads a signed n-bytes integer from `buf`. /// /// # Panics /// /// Panics when `nbytes < 1` or `nbytes > 16` or /// `buf.len() < nbytes` /// /// # Examples /// /// Write and read n-length signed numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut buf = [0; 3]; /// LittleEndian::write_int128(&mut buf, -1_000, 3); /// assert_eq!(-1_000, LittleEndian::read_int128(&buf, 3)); /// ``` #[inline] fn read_int128(buf: &[u8], nbytes: usize) -> i128 { extend_sign128(Self::read_uint128(buf, nbytes), nbytes) } /// Reads a IEEE754 single-precision (4 bytes) floating point number. /// /// # Panics /// /// Panics when `buf.len() < 4`. /// /// # Examples /// /// Write and read `f32` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let e = 2.71828; /// let mut buf = [0; 4]; /// LittleEndian::write_f32(&mut buf, e); /// assert_eq!(e, LittleEndian::read_f32(&buf)); /// ``` #[inline] fn read_f32(buf: &[u8]) -> f32 { f32::from_bits(Self::read_u32(buf)) } /// Reads a IEEE754 double-precision (8 bytes) floating point number. /// /// # Panics /// /// Panics when `buf.len() < 8`. /// /// # Examples /// /// Write and read `f64` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let phi = 1.6180339887; /// let mut buf = [0; 8]; /// LittleEndian::write_f64(&mut buf, phi); /// assert_eq!(phi, LittleEndian::read_f64(&buf)); /// ``` #[inline] fn read_f64(buf: &[u8]) -> f64 { f64::from_bits(Self::read_u64(buf)) } /// Writes a signed 16 bit integer `n` to `buf`. /// /// # Panics /// /// Panics when `buf.len() < 2`. /// /// # Examples /// /// Write and read `i16` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut buf = [0; 2]; /// LittleEndian::write_i16(&mut buf, -1_000); /// assert_eq!(-1_000, LittleEndian::read_i16(&buf)); /// ``` #[inline] fn write_i16(buf: &mut [u8], n: i16) { Self::write_u16(buf, n as u16) } /// Writes a signed 24 bit integer `n` to `buf`, stored in i32. /// /// # Panics /// /// Panics when `buf.len() < 3`. /// /// # Examples /// /// Write and read 24 bit `i32` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut buf = [0; 3]; /// LittleEndian::write_i24(&mut buf, -1_000_000); /// assert_eq!(-1_000_000, LittleEndian::read_i24(&buf)); /// ``` #[inline] fn write_i24(buf: &mut [u8], n: i32) { Self::write_int(buf, n as i64, 3) } /// Writes a signed 32 bit integer `n` to `buf`. /// /// # Panics /// /// Panics when `buf.len() < 4`. /// /// # Examples /// /// Write and read `i32` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut buf = [0; 4]; /// LittleEndian::write_i32(&mut buf, -1_000_000); /// assert_eq!(-1_000_000, LittleEndian::read_i32(&buf)); /// ``` #[inline] fn write_i32(buf: &mut [u8], n: i32) { Self::write_u32(buf, n as u32) } /// Writes a signed 48 bit integer `n` to `buf`, stored in i64. /// /// # Panics /// /// Panics when `buf.len() < 6`. /// /// # Examples /// /// Write and read 48 bit `i64` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut buf = [0; 6]; /// LittleEndian::write_i48(&mut buf, -1_000_000_000_000); /// assert_eq!(-1_000_000_000_000, LittleEndian::read_i48(&buf)); /// ``` #[inline] fn write_i48(buf: &mut [u8], n: i64) { Self::write_int(buf, n as i64, 6) } /// Writes a signed 64 bit integer `n` to `buf`. /// /// # Panics /// /// Panics when `buf.len() < 8`. /// /// # Examples /// /// Write and read `i64` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut buf = [0; 8]; /// LittleEndian::write_i64(&mut buf, -1_000_000_000); /// assert_eq!(-1_000_000_000, LittleEndian::read_i64(&buf)); /// ``` #[inline] fn write_i64(buf: &mut [u8], n: i64) { Self::write_u64(buf, n as u64) } /// Writes a signed 128 bit integer `n` to `buf`. /// /// # Panics /// /// Panics when `buf.len() < 16`. /// /// # Examples /// /// Write and read n-byte `i128` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut buf = [0; 16]; /// LittleEndian::write_i128(&mut buf, -1_000_000_000); /// assert_eq!(-1_000_000_000, LittleEndian::read_i128(&buf)); /// ``` #[inline] fn write_i128(buf: &mut [u8], n: i128) { Self::write_u128(buf, n as u128) } /// Writes a signed integer `n` to `buf` using only `nbytes`. /// /// # Panics /// /// If `n` is not representable in `nbytes`, or if `nbytes` is `> 8`, then /// this method panics. /// /// # Examples /// /// Write and read an n-byte number in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut buf = [0; 3]; /// LittleEndian::write_int(&mut buf, -1_000, 3); /// assert_eq!(-1_000, LittleEndian::read_int(&buf, 3)); /// ``` #[inline] fn write_int(buf: &mut [u8], n: i64, nbytes: usize) { Self::write_uint(buf, unextend_sign(n, nbytes), nbytes) } /// Writes a signed integer `n` to `buf` using only `nbytes`. /// /// # Panics /// /// If `n` is not representable in `nbytes`, or if `nbytes` is `> 16`, then /// this method panics. /// /// # Examples /// /// Write and read n-length signed numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut buf = [0; 3]; /// LittleEndian::write_int128(&mut buf, -1_000, 3); /// assert_eq!(-1_000, LittleEndian::read_int128(&buf, 3)); /// ``` #[inline] fn write_int128(buf: &mut [u8], n: i128, nbytes: usize) { Self::write_uint128(buf, unextend_sign128(n, nbytes), nbytes) } /// Writes a IEEE754 single-precision (4 bytes) floating point number. /// /// # Panics /// /// Panics when `buf.len() < 4`. /// /// # Examples /// /// Write and read `f32` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let e = 2.71828; /// let mut buf = [0; 4]; /// LittleEndian::write_f32(&mut buf, e); /// assert_eq!(e, LittleEndian::read_f32(&buf)); /// ``` #[inline] fn write_f32(buf: &mut [u8], n: f32) { Self::write_u32(buf, n.to_bits()) } /// Writes a IEEE754 double-precision (8 bytes) floating point number. /// /// # Panics /// /// Panics when `buf.len() < 8`. /// /// # Examples /// /// Write and read `f64` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let phi = 1.6180339887; /// let mut buf = [0; 8]; /// LittleEndian::write_f64(&mut buf, phi); /// assert_eq!(phi, LittleEndian::read_f64(&buf)); /// ``` #[inline] fn write_f64(buf: &mut [u8], n: f64) { Self::write_u64(buf, n.to_bits()) } /// Reads unsigned 16 bit integers from `src` into `dst`. /// /// # Panics /// /// Panics when `src.len() != 2*dst.len()`. /// /// # Examples /// /// Write and read `u16` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut bytes = [0; 8]; /// let numbers_given = [1, 2, 0xf00f, 0xffee]; /// LittleEndian::write_u16_into(&numbers_given, &mut bytes); /// /// let mut numbers_got = [0; 4]; /// LittleEndian::read_u16_into(&bytes, &mut numbers_got); /// assert_eq!(numbers_given, numbers_got); /// ``` fn read_u16_into(src: &[u8], dst: &mut [u16]); /// Reads unsigned 32 bit integers from `src` into `dst`. /// /// # Panics /// /// Panics when `src.len() != 4*dst.len()`. /// /// # Examples /// /// Write and read `u32` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut bytes = [0; 16]; /// let numbers_given = [1, 2, 0xf00f, 0xffee]; /// LittleEndian::write_u32_into(&numbers_given, &mut bytes); /// /// let mut numbers_got = [0; 4]; /// LittleEndian::read_u32_into(&bytes, &mut numbers_got); /// assert_eq!(numbers_given, numbers_got); /// ``` fn read_u32_into(src: &[u8], dst: &mut [u32]); /// Reads unsigned 64 bit integers from `src` into `dst`. /// /// # Panics /// /// Panics when `src.len() != 8*dst.len()`. /// /// # Examples /// /// Write and read `u64` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut bytes = [0; 32]; /// let numbers_given = [1, 2, 0xf00f, 0xffee]; /// LittleEndian::write_u64_into(&numbers_given, &mut bytes); /// /// let mut numbers_got = [0; 4]; /// LittleEndian::read_u64_into(&bytes, &mut numbers_got); /// assert_eq!(numbers_given, numbers_got); /// ``` fn read_u64_into(src: &[u8], dst: &mut [u64]); /// Reads unsigned 128 bit integers from `src` into `dst`. /// /// # Panics /// /// Panics when `src.len() != 16*dst.len()`. /// /// # Examples /// /// Write and read `u128` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut bytes = [0; 64]; /// let numbers_given = [1, 2, 0xf00f, 0xffee]; /// LittleEndian::write_u128_into(&numbers_given, &mut bytes); /// /// let mut numbers_got = [0; 4]; /// LittleEndian::read_u128_into(&bytes, &mut numbers_got); /// assert_eq!(numbers_given, numbers_got); /// ``` fn read_u128_into(src: &[u8], dst: &mut [u128]); /// Reads signed 16 bit integers from `src` to `dst`. /// /// # Panics /// /// Panics when `buf.len() != 2*dst.len()`. /// /// # Examples /// /// Write and read `i16` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut bytes = [0; 8]; /// let numbers_given = [1, 2, 0x0f, 0xee]; /// LittleEndian::write_i16_into(&numbers_given, &mut bytes); /// /// let mut numbers_got = [0; 4]; /// LittleEndian::read_i16_into(&bytes, &mut numbers_got); /// assert_eq!(numbers_given, numbers_got); /// ``` #[inline] fn read_i16_into(src: &[u8], dst: &mut [i16]) { let dst = unsafe { slice::from_raw_parts_mut(dst.as_mut_ptr() as *mut u16, dst.len()) }; Self::read_u16_into(src, dst) } /// Reads signed 32 bit integers from `src` into `dst`. /// /// # Panics /// /// Panics when `src.len() != 4*dst.len()`. /// /// # Examples /// /// Write and read `i32` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut bytes = [0; 16]; /// let numbers_given = [1, 2, 0xf00f, 0xffee]; /// LittleEndian::write_i32_into(&numbers_given, &mut bytes); /// /// let mut numbers_got = [0; 4]; /// LittleEndian::read_i32_into(&bytes, &mut numbers_got); /// assert_eq!(numbers_given, numbers_got); /// ``` #[inline] fn read_i32_into(src: &[u8], dst: &mut [i32]) { let dst = unsafe { slice::from_raw_parts_mut(dst.as_mut_ptr() as *mut u32, dst.len()) }; Self::read_u32_into(src, dst); } /// Reads signed 64 bit integers from `src` into `dst`. /// /// # Panics /// /// Panics when `src.len() != 8*dst.len()`. /// /// # Examples /// /// Write and read `i64` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut bytes = [0; 32]; /// let numbers_given = [1, 2, 0xf00f, 0xffee]; /// LittleEndian::write_i64_into(&numbers_given, &mut bytes); /// /// let mut numbers_got = [0; 4]; /// LittleEndian::read_i64_into(&bytes, &mut numbers_got); /// assert_eq!(numbers_given, numbers_got); /// ``` #[inline] fn read_i64_into(src: &[u8], dst: &mut [i64]) { let dst = unsafe { slice::from_raw_parts_mut(dst.as_mut_ptr() as *mut u64, dst.len()) }; Self::read_u64_into(src, dst); } /// Reads signed 128 bit integers from `src` into `dst`. /// /// # Panics /// /// Panics when `src.len() != 16*dst.len()`. /// /// # Examples /// /// Write and read `i128` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut bytes = [0; 64]; /// let numbers_given = [1, 2, 0xf00f, 0xffee]; /// LittleEndian::write_i128_into(&numbers_given, &mut bytes); /// /// let mut numbers_got = [0; 4]; /// LittleEndian::read_i128_into(&bytes, &mut numbers_got); /// assert_eq!(numbers_given, numbers_got); /// ``` #[inline] fn read_i128_into(src: &[u8], dst: &mut [i128]) { let dst = unsafe { slice::from_raw_parts_mut(dst.as_mut_ptr() as *mut u128, dst.len()) }; Self::read_u128_into(src, dst); } /// Reads IEEE754 single-precision (4 bytes) floating point numbers from /// `src` into `dst`. /// /// # Panics /// /// Panics when `src.len() != 4*dst.len()`. /// /// # Examples /// /// Write and read `f32` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut bytes = [0; 16]; /// let numbers_given = [1.0, 2.0, 31.312e31, -11.32e19]; /// LittleEndian::write_f32_into(&numbers_given, &mut bytes); /// /// let mut numbers_got = [0.0; 4]; /// LittleEndian::read_f32_into(&bytes, &mut numbers_got); /// assert_eq!(numbers_given, numbers_got); /// ``` #[inline] fn read_f32_into(src: &[u8], dst: &mut [f32]) { let dst = unsafe { slice::from_raw_parts_mut(dst.as_mut_ptr() as *mut u32, dst.len()) }; Self::read_u32_into(src, dst); } /// **DEPRECATED**. /// /// This method is deprecated. Use `read_f32_into` instead. /// Reads IEEE754 single-precision (4 bytes) floating point numbers from /// `src` into `dst`. /// /// # Panics /// /// Panics when `src.len() != 4*dst.len()`. /// /// # Examples /// /// Write and read `f32` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut bytes = [0; 16]; /// let numbers_given = [1.0, 2.0, 31.312e31, -11.32e19]; /// LittleEndian::write_f32_into(&numbers_given, &mut bytes); /// /// let mut numbers_got = [0.0; 4]; /// LittleEndian::read_f32_into_unchecked(&bytes, &mut numbers_got); /// assert_eq!(numbers_given, numbers_got); /// ``` #[inline] #[deprecated(since = "1.3.0", note = "please use `read_f32_into` instead")] fn read_f32_into_unchecked(src: &[u8], dst: &mut [f32]) { Self::read_f32_into(src, dst); } /// Reads IEEE754 single-precision (4 bytes) floating point numbers from /// `src` into `dst`. /// /// # Panics /// /// Panics when `src.len() != 8*dst.len()`. /// /// # Examples /// /// Write and read `f64` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut bytes = [0; 32]; /// let numbers_given = [1.0, 2.0, 31.312e211, -11.32e91]; /// LittleEndian::write_f64_into(&numbers_given, &mut bytes); /// /// let mut numbers_got = [0.0; 4]; /// LittleEndian::read_f64_into(&bytes, &mut numbers_got); /// assert_eq!(numbers_given, numbers_got); /// ``` #[inline] fn read_f64_into(src: &[u8], dst: &mut [f64]) { let dst = unsafe { slice::from_raw_parts_mut(dst.as_mut_ptr() as *mut u64, dst.len()) }; Self::read_u64_into(src, dst); } /// **DEPRECATED**. /// /// This method is deprecated. Use `read_f64_into` instead. /// /// Reads IEEE754 single-precision (4 bytes) floating point numbers from /// `src` into `dst`. /// /// # Panics /// /// Panics when `src.len() != 8*dst.len()`. /// /// # Examples /// /// Write and read `f64` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut bytes = [0; 32]; /// let numbers_given = [1.0, 2.0, 31.312e211, -11.32e91]; /// LittleEndian::write_f64_into(&numbers_given, &mut bytes); /// /// let mut numbers_got = [0.0; 4]; /// LittleEndian::read_f64_into_unchecked(&bytes, &mut numbers_got); /// assert_eq!(numbers_given, numbers_got); /// ``` #[inline] #[deprecated(since = "1.3.0", note = "please use `read_f64_into` instead")] fn read_f64_into_unchecked(src: &[u8], dst: &mut [f64]) { Self::read_f64_into(src, dst); } /// Writes unsigned 16 bit integers from `src` into `dst`. /// /// # Panics /// /// Panics when `dst.len() != 2*src.len()`. /// /// # Examples /// /// Write and read `u16` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut bytes = [0; 8]; /// let numbers_given = [1, 2, 0xf00f, 0xffee]; /// LittleEndian::write_u16_into(&numbers_given, &mut bytes); /// /// let mut numbers_got = [0; 4]; /// LittleEndian::read_u16_into(&bytes, &mut numbers_got); /// assert_eq!(numbers_given, numbers_got); /// ``` fn write_u16_into(src: &[u16], dst: &mut [u8]); /// Writes unsigned 32 bit integers from `src` into `dst`. /// /// # Panics /// /// Panics when `dst.len() != 4*src.len()`. /// /// # Examples /// /// Write and read `u32` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut bytes = [0; 16]; /// let numbers_given = [1, 2, 0xf00f, 0xffee]; /// LittleEndian::write_u32_into(&numbers_given, &mut bytes); /// /// let mut numbers_got = [0; 4]; /// LittleEndian::read_u32_into(&bytes, &mut numbers_got); /// assert_eq!(numbers_given, numbers_got); /// ``` fn write_u32_into(src: &[u32], dst: &mut [u8]); /// Writes unsigned 64 bit integers from `src` into `dst`. /// /// # Panics /// /// Panics when `dst.len() != 8*src.len()`. /// /// # Examples /// /// Write and read `u64` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut bytes = [0; 32]; /// let numbers_given = [1, 2, 0xf00f, 0xffee]; /// LittleEndian::write_u64_into(&numbers_given, &mut bytes); /// /// let mut numbers_got = [0; 4]; /// LittleEndian::read_u64_into(&bytes, &mut numbers_got); /// assert_eq!(numbers_given, numbers_got); /// ``` fn write_u64_into(src: &[u64], dst: &mut [u8]); /// Writes unsigned 128 bit integers from `src` into `dst`. /// /// # Panics /// /// Panics when `dst.len() != 16*src.len()`. /// /// # Examples /// /// Write and read `u128` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut bytes = [0; 64]; /// let numbers_given = [1, 2, 0xf00f, 0xffee]; /// LittleEndian::write_u128_into(&numbers_given, &mut bytes); /// /// let mut numbers_got = [0; 4]; /// LittleEndian::read_u128_into(&bytes, &mut numbers_got); /// assert_eq!(numbers_given, numbers_got); /// ``` fn write_u128_into(src: &[u128], dst: &mut [u8]); /// Writes signed 8 bit integers from `src` into `dst`. /// /// Note that since each `i8` is a single byte, no byte order conversions /// are used. This method is included because it provides a safe, simple /// way for the caller to write from a `&[i8]` buffer. (Without this /// method, the caller would have to either use `unsafe` code or convert /// each byte to `u8` individually.) /// /// # Panics /// /// Panics when `buf.len() != src.len()`. /// /// # Examples /// /// Write and read `i8` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian, ReadBytesExt}; /// /// let mut bytes = [0; 4]; /// let numbers_given = [1, 2, 0xf, 0xe]; /// LittleEndian::write_i8_into(&numbers_given, &mut bytes); /// /// let mut numbers_got = [0; 4]; /// bytes.as_ref().read_i8_into(&mut numbers_got); /// assert_eq!(numbers_given, numbers_got); /// ``` fn write_i8_into(src: &[i8], dst: &mut [u8]) { let src = unsafe { slice::from_raw_parts(src.as_ptr() as *const u8, src.len()) }; dst.copy_from_slice(src); } /// Writes signed 16 bit integers from `src` into `dst`. /// /// # Panics /// /// Panics when `buf.len() != 2*src.len()`. /// /// # Examples /// /// Write and read `i16` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut bytes = [0; 8]; /// let numbers_given = [1, 2, 0x0f, 0xee]; /// LittleEndian::write_i16_into(&numbers_given, &mut bytes); /// /// let mut numbers_got = [0; 4]; /// LittleEndian::read_i16_into(&bytes, &mut numbers_got); /// assert_eq!(numbers_given, numbers_got); /// ``` fn write_i16_into(src: &[i16], dst: &mut [u8]) { let src = unsafe { slice::from_raw_parts(src.as_ptr() as *const u16, src.len()) }; Self::write_u16_into(src, dst); } /// Writes signed 32 bit integers from `src` into `dst`. /// /// # Panics /// /// Panics when `dst.len() != 4*src.len()`. /// /// # Examples /// /// Write and read `i32` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut bytes = [0; 16]; /// let numbers_given = [1, 2, 0xf00f, 0xffee]; /// LittleEndian::write_i32_into(&numbers_given, &mut bytes); /// /// let mut numbers_got = [0; 4]; /// LittleEndian::read_i32_into(&bytes, &mut numbers_got); /// assert_eq!(numbers_given, numbers_got); /// ``` fn write_i32_into(src: &[i32], dst: &mut [u8]) { let src = unsafe { slice::from_raw_parts(src.as_ptr() as *const u32, src.len()) }; Self::write_u32_into(src, dst); } /// Writes signed 64 bit integers from `src` into `dst`. /// /// # Panics /// /// Panics when `dst.len() != 8*src.len()`. /// /// # Examples /// /// Write and read `i64` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut bytes = [0; 32]; /// let numbers_given = [1, 2, 0xf00f, 0xffee]; /// LittleEndian::write_i64_into(&numbers_given, &mut bytes); /// /// let mut numbers_got = [0; 4]; /// LittleEndian::read_i64_into(&bytes, &mut numbers_got); /// assert_eq!(numbers_given, numbers_got); /// ``` fn write_i64_into(src: &[i64], dst: &mut [u8]) { let src = unsafe { slice::from_raw_parts(src.as_ptr() as *const u64, src.len()) }; Self::write_u64_into(src, dst); } /// Writes signed 128 bit integers from `src` into `dst`. /// /// # Panics /// /// Panics when `dst.len() != 16*src.len()`. /// /// # Examples /// /// Write and read `i128` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut bytes = [0; 64]; /// let numbers_given = [1, 2, 0xf00f, 0xffee]; /// LittleEndian::write_i128_into(&numbers_given, &mut bytes); /// /// let mut numbers_got = [0; 4]; /// LittleEndian::read_i128_into(&bytes, &mut numbers_got); /// assert_eq!(numbers_given, numbers_got); /// ``` fn write_i128_into(src: &[i128], dst: &mut [u8]) { let src = unsafe { slice::from_raw_parts(src.as_ptr() as *const u128, src.len()) }; Self::write_u128_into(src, dst); } /// Writes IEEE754 single-precision (4 bytes) floating point numbers from /// `src` into `dst`. /// /// # Panics /// /// Panics when `src.len() != 4*dst.len()`. /// /// # Examples /// /// Write and read `f32` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut bytes = [0; 16]; /// let numbers_given = [1.0, 2.0, 31.312e31, -11.32e19]; /// LittleEndian::write_f32_into(&numbers_given, &mut bytes); /// /// let mut numbers_got = [0.0; 4]; /// LittleEndian::read_f32_into(&bytes, &mut numbers_got); /// assert_eq!(numbers_given, numbers_got); /// ``` fn write_f32_into(src: &[f32], dst: &mut [u8]) { let src = unsafe { slice::from_raw_parts(src.as_ptr() as *const u32, src.len()) }; Self::write_u32_into(src, dst); } /// Writes IEEE754 double-precision (8 bytes) floating point numbers from /// `src` into `dst`. /// /// # Panics /// /// Panics when `src.len() != 8*dst.len()`. /// /// # Examples /// /// Write and read `f64` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut bytes = [0; 32]; /// let numbers_given = [1.0, 2.0, 31.312e211, -11.32e91]; /// LittleEndian::write_f64_into(&numbers_given, &mut bytes); /// /// let mut numbers_got = [0.0; 4]; /// LittleEndian::read_f64_into(&bytes, &mut numbers_got); /// assert_eq!(numbers_given, numbers_got); /// ``` fn write_f64_into(src: &[f64], dst: &mut [u8]) { let src = unsafe { slice::from_raw_parts(src.as_ptr() as *const u64, src.len()) }; Self::write_u64_into(src, dst); } /// Converts the given slice of unsigned 16 bit integers to a particular /// endianness. /// /// If the endianness matches the endianness of the host platform, then /// this is a no-op. /// /// # Examples /// /// Convert the host platform's endianness to big-endian: /// /// ```rust /// use byteorder::{ByteOrder, BigEndian}; /// /// let mut numbers = [5, 65000]; /// BigEndian::from_slice_u16(&mut numbers); /// assert_eq!(numbers, [5u16.to_be(), 65000u16.to_be()]); /// ``` fn from_slice_u16(numbers: &mut [u16]); /// Converts the given slice of unsigned 32 bit integers to a particular /// endianness. /// /// If the endianness matches the endianness of the host platform, then /// this is a no-op. /// /// # Examples /// /// Convert the host platform's endianness to big-endian: /// /// ```rust /// use byteorder::{ByteOrder, BigEndian}; /// /// let mut numbers = [5, 65000]; /// BigEndian::from_slice_u32(&mut numbers); /// assert_eq!(numbers, [5u32.to_be(), 65000u32.to_be()]); /// ``` fn from_slice_u32(numbers: &mut [u32]); /// Converts the given slice of unsigned 64 bit integers to a particular /// endianness. /// /// If the endianness matches the endianness of the host platform, then /// this is a no-op. /// /// # Examples /// /// Convert the host platform's endianness to big-endian: /// /// ```rust /// use byteorder::{ByteOrder, BigEndian}; /// /// let mut numbers = [5, 65000]; /// BigEndian::from_slice_u64(&mut numbers); /// assert_eq!(numbers, [5u64.to_be(), 65000u64.to_be()]); /// ``` fn from_slice_u64(numbers: &mut [u64]); /// Converts the given slice of unsigned 128 bit integers to a particular /// endianness. /// /// If the endianness matches the endianness of the host platform, then /// this is a no-op. /// /// # Examples /// /// Convert the host platform's endianness to big-endian: /// /// ```rust /// use byteorder::{ByteOrder, BigEndian}; /// /// let mut numbers = [5, 65000]; /// BigEndian::from_slice_u128(&mut numbers); /// assert_eq!(numbers, [5u128.to_be(), 65000u128.to_be()]); /// ``` fn from_slice_u128(numbers: &mut [u128]); /// Converts the given slice of signed 16 bit integers to a particular /// endianness. /// /// If the endianness matches the endianness of the host platform, then /// this is a no-op. /// /// # Examples /// /// Convert the host platform's endianness to big-endian: /// /// ```rust /// use byteorder::{ByteOrder, BigEndian}; /// /// let mut numbers = [5, 6500]; /// BigEndian::from_slice_i16(&mut numbers); /// assert_eq!(numbers, [5i16.to_be(), 6500i16.to_be()]); /// ``` #[inline] fn from_slice_i16(src: &mut [i16]) { let src = unsafe { slice::from_raw_parts_mut(src.as_mut_ptr() as *mut u16, src.len()) }; Self::from_slice_u16(src); } /// Converts the given slice of signed 32 bit integers to a particular /// endianness. /// /// If the endianness matches the endianness of the host platform, then /// this is a no-op. /// /// # Examples /// /// Convert the host platform's endianness to big-endian: /// /// ```rust /// use byteorder::{ByteOrder, BigEndian}; /// /// let mut numbers = [5, 65000]; /// BigEndian::from_slice_i32(&mut numbers); /// assert_eq!(numbers, [5i32.to_be(), 65000i32.to_be()]); /// ``` #[inline] fn from_slice_i32(src: &mut [i32]) { let src = unsafe { slice::from_raw_parts_mut(src.as_mut_ptr() as *mut u32, src.len()) }; Self::from_slice_u32(src); } /// Converts the given slice of signed 64 bit integers to a particular /// endianness. /// /// If the endianness matches the endianness of the host platform, then /// this is a no-op. /// /// # Examples /// /// Convert the host platform's endianness to big-endian: /// /// ```rust /// use byteorder::{ByteOrder, BigEndian}; /// /// let mut numbers = [5, 65000]; /// BigEndian::from_slice_i64(&mut numbers); /// assert_eq!(numbers, [5i64.to_be(), 65000i64.to_be()]); /// ``` #[inline] fn from_slice_i64(src: &mut [i64]) { let src = unsafe { slice::from_raw_parts_mut(src.as_mut_ptr() as *mut u64, src.len()) }; Self::from_slice_u64(src); } /// Converts the given slice of signed 128 bit integers to a particular /// endianness. /// /// If the endianness matches the endianness of the host platform, then /// this is a no-op. /// /// # Examples /// /// Convert the host platform's endianness to big-endian: /// /// ```rust /// use byteorder::{ByteOrder, BigEndian}; /// /// let mut numbers = [5, 65000]; /// BigEndian::from_slice_i128(&mut numbers); /// assert_eq!(numbers, [5i128.to_be(), 65000i128.to_be()]); /// ``` #[inline] fn from_slice_i128(src: &mut [i128]) { let src = unsafe { slice::from_raw_parts_mut(src.as_mut_ptr() as *mut u128, src.len()) }; Self::from_slice_u128(src); } /// Converts the given slice of IEEE754 single-precision (4 bytes) floating /// point numbers to a particular endianness. /// /// If the endianness matches the endianness of the host platform, then /// this is a no-op. fn from_slice_f32(numbers: &mut [f32]); /// Converts the given slice of IEEE754 double-precision (8 bytes) floating /// point numbers to a particular endianness. /// /// If the endianness matches the endianness of the host platform, then /// this is a no-op. fn from_slice_f64(numbers: &mut [f64]); } /// Defines big-endian serialization. /// /// Note that this type has no value constructor. It is used purely at the /// type level. /// /// # Examples /// /// Write and read `u32` numbers in big endian order: /// /// ```rust /// use byteorder::{ByteOrder, BigEndian}; /// /// let mut buf = [0; 4]; /// BigEndian::write_u32(&mut buf, 1_000_000); /// assert_eq!(1_000_000, BigEndian::read_u32(&buf)); /// ``` #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] pub enum BigEndian {} impl Default for BigEndian { fn default() -> BigEndian { panic!("BigEndian default") } } /// A type alias for [`BigEndian`]. /// /// [`BigEndian`]: enum.BigEndian.html pub type BE = BigEndian; /// Defines little-endian serialization. /// /// Note that this type has no value constructor. It is used purely at the /// type level. /// /// # Examples /// /// Write and read `u32` numbers in little endian order: /// /// ```rust /// use byteorder::{ByteOrder, LittleEndian}; /// /// let mut buf = [0; 4]; /// LittleEndian::write_u32(&mut buf, 1_000_000); /// assert_eq!(1_000_000, LittleEndian::read_u32(&buf)); /// ``` #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] pub enum LittleEndian {} impl Default for LittleEndian { fn default() -> LittleEndian { panic!("LittleEndian default") } } /// A type alias for [`LittleEndian`]. /// /// [`LittleEndian`]: enum.LittleEndian.html pub type LE = LittleEndian; /// Defines network byte order serialization. /// /// Network byte order is defined by [RFC 1700][1] to be big-endian, and is /// referred to in several protocol specifications. This type is an alias of /// [`BigEndian`]. /// /// [1]: https://tools.ietf.org/html/rfc1700 /// /// Note that this type has no value constructor. It is used purely at the /// type level. /// /// # Examples /// /// Write and read `i16` numbers in big endian order: /// /// ```rust /// use byteorder::{ByteOrder, NetworkEndian, BigEndian}; /// /// let mut buf = [0; 2]; /// BigEndian::write_i16(&mut buf, -5_000); /// assert_eq!(-5_000, NetworkEndian::read_i16(&buf)); /// ``` /// /// [`BigEndian`]: enum.BigEndian.html pub type NetworkEndian = BigEndian; /// Defines system native-endian serialization. /// /// Note that this type has no value constructor. It is used purely at the /// type level. /// /// On this platform, this is an alias for [`LittleEndian`]. /// /// [`LittleEndian`]: enum.LittleEndian.html #[cfg(target_endian = "little")] pub type NativeEndian = LittleEndian; /// Defines system native-endian serialization. /// /// Note that this type has no value constructor. It is used purely at the /// type level. /// /// On this platform, this is an alias for [`BigEndian`]. /// /// [`BigEndian`]: enum.BigEndian.html #[cfg(target_endian = "big")] pub type NativeEndian = BigEndian; /// Copies $size bytes from a number $n to a &mut [u8] $dst. $ty represents the /// numeric type of $n and $which must be either to_be or to_le, depending on /// which endianness one wants to use when writing to $dst. /// /// This macro is only safe to call when $ty is a numeric type and $size == /// size_of::<$ty>() and where $dst is a &mut [u8]. macro_rules! unsafe_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); } }}; } /// Copies a &[u8] $src into a &mut [] $dst for the endianness given /// by $which (must be either to_be or to_le). /// /// This macro is only safe to call when $src and $dst are &[u8] and &mut [u8], /// respectively. The macro will panic if $src.len() != $size * $dst.len(), /// where $size represents the size of the integers encoded in $src. macro_rules! unsafe_read_slice { ($src:expr, $dst:expr, $size:expr, $which:ident) => {{ assert_eq!($src.len(), $size * $dst.len()); unsafe { copy_nonoverlapping( $src.as_ptr(), $dst.as_mut_ptr() as *mut u8, $src.len(), ); } for v in $dst.iter_mut() { *v = v.$which(); } }}; } /// Copies a &[$ty] $src into a &mut [u8] $dst, where $ty must be a numeric /// type. This panics if size_of::<$ty>() * $src.len() != $dst.len(). /// /// This macro is only safe to call when $src is a slice of numeric types and /// $dst is a &mut [u8] and where $ty represents the type of the integers in /// $src. macro_rules! unsafe_write_slice_native { ($src:expr, $dst:expr, $ty:ty) => {{ let size = core::mem::size_of::<$ty>(); assert_eq!(size * $src.len(), $dst.len()); unsafe { copy_nonoverlapping( $src.as_ptr() as *const u8, $dst.as_mut_ptr(), $dst.len(), ); } }}; } macro_rules! write_slice { ($src:expr, $dst:expr, $ty:ty, $size:expr, $write:expr) => {{ assert!($size == ::core::mem::size_of::<$ty>()); assert_eq!($size * $src.len(), $dst.len()); for (&n, chunk) in $src.iter().zip($dst.chunks_mut($size)) { $write(chunk, n); } }}; } impl ByteOrder for BigEndian { #[inline] fn read_u16(buf: &[u8]) -> u16 { u16::from_be_bytes(buf[..2].try_into().unwrap()) } #[inline] fn read_u32(buf: &[u8]) -> u32 { u32::from_be_bytes(buf[..4].try_into().unwrap()) } #[inline] fn read_u64(buf: &[u8]) -> u64 { u64::from_be_bytes(buf[..8].try_into().unwrap()) } #[inline] fn read_u128(buf: &[u8]) -> u128 { u128::from_be_bytes(buf[..16].try_into().unwrap()) } #[inline] fn read_uint(buf: &[u8], nbytes: usize) -> u64 { assert!(1 <= nbytes && nbytes <= 8 && nbytes <= buf.len()); let mut out = 0u64; let ptr_out = &mut out as *mut u64 as *mut u8; unsafe { copy_nonoverlapping( buf.as_ptr(), ptr_out.offset((8 - nbytes) as isize), nbytes, ); } out.to_be() } #[inline] fn read_uint128(buf: &[u8], nbytes: usize) -> u128 { assert!(1 <= nbytes && nbytes <= 16 && nbytes <= buf.len()); let mut out: u128 = 0; let ptr_out = &mut out as *mut u128 as *mut u8; unsafe { copy_nonoverlapping( buf.as_ptr(), ptr_out.offset((16 - nbytes) as isize), nbytes, ); } out.to_be() } #[inline] fn write_u16(buf: &mut [u8], n: u16) { unsafe_write_num_bytes!(u16, 2, n, buf, to_be); } #[inline] fn write_u32(buf: &mut [u8], n: u32) { unsafe_write_num_bytes!(u32, 4, n, buf, to_be); } #[inline] fn write_u64(buf: &mut [u8], n: u64) { unsafe_write_num_bytes!(u64, 8, n, buf, to_be); } #[inline] fn write_u128(buf: &mut [u8], n: u128) { unsafe_write_num_bytes!(u128, 16, n, buf, to_be); } #[inline] fn write_uint(buf: &mut [u8], n: u64, nbytes: usize) { assert!(pack_size(n) <= nbytes && nbytes <= 8); assert!(nbytes <= buf.len()); unsafe { let bytes = *(&n.to_be() as *const u64 as *const [u8; 8]); copy_nonoverlapping( bytes.as_ptr().offset((8 - nbytes) as isize), buf.as_mut_ptr(), nbytes, ); } } #[inline] fn write_uint128(buf: &mut [u8], n: u128, nbytes: usize) { assert!(pack_size128(n) <= nbytes && nbytes <= 16); assert!(nbytes <= buf.len()); unsafe { let bytes = *(&n.to_be() as *const u128 as *const [u8; 16]); copy_nonoverlapping( bytes.as_ptr().offset((16 - nbytes) as isize), buf.as_mut_ptr(), nbytes, ); } } #[inline] fn read_u16_into(src: &[u8], dst: &mut [u16]) { unsafe_read_slice!(src, dst, 2, to_be); } #[inline] fn read_u32_into(src: &[u8], dst: &mut [u32]) { unsafe_read_slice!(src, dst, 4, to_be); } #[inline] fn read_u64_into(src: &[u8], dst: &mut [u64]) { unsafe_read_slice!(src, dst, 8, to_be); } #[inline] fn read_u128_into(src: &[u8], dst: &mut [u128]) { unsafe_read_slice!(src, dst, 16, to_be); } #[inline] fn write_u16_into(src: &[u16], dst: &mut [u8]) { if cfg!(target_endian = "big") { unsafe_write_slice_native!(src, dst, u16); } else { write_slice!(src, dst, u16, 2, Self::write_u16); } } #[inline] fn write_u32_into(src: &[u32], dst: &mut [u8]) { if cfg!(target_endian = "big") { unsafe_write_slice_native!(src, dst, u32); } else { write_slice!(src, dst, u32, 4, Self::write_u32); } } #[inline] fn write_u64_into(src: &[u64], dst: &mut [u8]) { if cfg!(target_endian = "big") { unsafe_write_slice_native!(src, dst, u64); } else { write_slice!(src, dst, u64, 8, Self::write_u64); } } #[inline] fn write_u128_into(src: &[u128], dst: &mut [u8]) { if cfg!(target_endian = "big") { unsafe_write_slice_native!(src, dst, u128); } else { write_slice!(src, dst, u128, 16, Self::write_u128); } } #[inline] fn from_slice_u16(numbers: &mut [u16]) { if cfg!(target_endian = "little") { for n in numbers { *n = n.to_be(); } } } #[inline] fn from_slice_u32(numbers: &mut [u32]) { if cfg!(target_endian = "little") { for n in numbers { *n = n.to_be(); } } } #[inline] fn from_slice_u64(numbers: &mut [u64]) { if cfg!(target_endian = "little") { for n in numbers { *n = n.to_be(); } } } #[inline] fn from_slice_u128(numbers: &mut [u128]) { if cfg!(target_endian = "little") { for n in numbers { *n = n.to_be(); } } } #[inline] fn from_slice_f32(numbers: &mut [f32]) { if cfg!(target_endian = "little") { for n in numbers { unsafe { let int = *(n as *const f32 as *const u32); *n = *(&int.to_be() as *const u32 as *const f32); } } } } #[inline] fn from_slice_f64(numbers: &mut [f64]) { if cfg!(target_endian = "little") { for n in numbers { unsafe { let int = *(n as *const f64 as *const u64); *n = *(&int.to_be() as *const u64 as *const f64); } } } } } impl ByteOrder for LittleEndian { #[inline] fn read_u16(buf: &[u8]) -> u16 { u16::from_le_bytes(buf[..2].try_into().unwrap()) } #[inline] fn read_u32(buf: &[u8]) -> u32 { u32::from_le_bytes(buf[..4].try_into().unwrap()) } #[inline] fn read_u64(buf: &[u8]) -> u64 { u64::from_le_bytes(buf[..8].try_into().unwrap()) } #[inline] fn read_u128(buf: &[u8]) -> u128 { u128::from_le_bytes(buf[..16].try_into().unwrap()) } #[inline] fn read_uint(buf: &[u8], nbytes: usize) -> u64 { assert!(1 <= nbytes && nbytes <= 8 && nbytes <= buf.len()); let mut out = 0u64; let ptr_out = &mut out as *mut u64 as *mut u8; unsafe { copy_nonoverlapping(buf.as_ptr(), ptr_out, nbytes); } out.to_le() } #[inline] fn read_uint128(buf: &[u8], nbytes: usize) -> u128 { assert!(1 <= nbytes && nbytes <= 16 && nbytes <= buf.len()); let mut out: u128 = 0; let ptr_out = &mut out as *mut u128 as *mut u8; unsafe { copy_nonoverlapping(buf.as_ptr(), ptr_out, nbytes); } out.to_le() } #[inline] fn write_u16(buf: &mut [u8], n: u16) { unsafe_write_num_bytes!(u16, 2, n, buf, to_le); } #[inline] fn write_u32(buf: &mut [u8], n: u32) { unsafe_write_num_bytes!(u32, 4, n, buf, to_le); } #[inline] fn write_u64(buf: &mut [u8], n: u64) { unsafe_write_num_bytes!(u64, 8, n, buf, to_le); } #[inline] fn write_u128(buf: &mut [u8], n: u128) { unsafe_write_num_bytes!(u128, 16, n, buf, to_le); } #[inline] fn write_uint(buf: &mut [u8], n: u64, nbytes: usize) { assert!(pack_size(n as u64) <= nbytes && nbytes <= 8); assert!(nbytes <= buf.len()); unsafe { let bytes = *(&n.to_le() as *const u64 as *const [u8; 8]); copy_nonoverlapping(bytes.as_ptr(), buf.as_mut_ptr(), nbytes); } } #[inline] fn write_uint128(buf: &mut [u8], n: u128, nbytes: usize) { assert!(pack_size128(n as u128) <= nbytes && nbytes <= 16); assert!(nbytes <= buf.len()); unsafe { let bytes = *(&n.to_le() as *const u128 as *const [u8; 16]); copy_nonoverlapping(bytes.as_ptr(), buf.as_mut_ptr(), nbytes); } } #[inline] fn read_u16_into(src: &[u8], dst: &mut [u16]) { unsafe_read_slice!(src, dst, 2, to_le); } #[inline] fn read_u32_into(src: &[u8], dst: &mut [u32]) { unsafe_read_slice!(src, dst, 4, to_le); } #[inline] fn read_u64_into(src: &[u8], dst: &mut [u64]) { unsafe_read_slice!(src, dst, 8, to_le); } #[inline] fn read_u128_into(src: &[u8], dst: &mut [u128]) { unsafe_read_slice!(src, dst, 16, to_le); } #[inline] fn write_u16_into(src: &[u16], dst: &mut [u8]) { if cfg!(target_endian = "little") { unsafe_write_slice_native!(src, dst, u16); } else { write_slice!(src, dst, u16, 2, Self::write_u16); } } #[inline] fn write_u32_into(src: &[u32], dst: &mut [u8]) { if cfg!(target_endian = "little") { unsafe_write_slice_native!(src, dst, u32); } else { write_slice!(src, dst, u32, 4, Self::write_u32); } } #[inline] fn write_u64_into(src: &[u64], dst: &mut [u8]) { if cfg!(target_endian = "little") { unsafe_write_slice_native!(src, dst, u64); } else { write_slice!(src, dst, u64, 8, Self::write_u64); } } #[inline] fn write_u128_into(src: &[u128], dst: &mut [u8]) { if cfg!(target_endian = "little") { unsafe_write_slice_native!(src, dst, u128); } else { write_slice!(src, dst, u128, 16, Self::write_u128); } } #[inline] fn from_slice_u16(numbers: &mut [u16]) { if cfg!(target_endian = "big") { for n in numbers { *n = n.to_le(); } } } #[inline] fn from_slice_u32(numbers: &mut [u32]) { if cfg!(target_endian = "big") { for n in numbers { *n = n.to_le(); } } } #[inline] fn from_slice_u64(numbers: &mut [u64]) { if cfg!(target_endian = "big") { for n in numbers { *n = n.to_le(); } } } #[inline] fn from_slice_u128(numbers: &mut [u128]) { if cfg!(target_endian = "big") { for n in numbers { *n = n.to_le(); } } } #[inline] fn from_slice_f32(numbers: &mut [f32]) { if cfg!(target_endian = "big") { for n in numbers { unsafe { let int = *(n as *const f32 as *const u32); *n = *(&int.to_le() as *const u32 as *const f32); } } } } #[inline] fn from_slice_f64(numbers: &mut [f64]) { if cfg!(target_endian = "big") { for n in numbers { unsafe { let int = *(n as *const f64 as *const u64); *n = *(&int.to_le() as *const u64 as *const f64); } } } } } #[cfg(test)] mod test { use quickcheck::{Arbitrary, Gen, QuickCheck, StdGen, Testable}; use rand::{thread_rng, Rng}; pub const U24_MAX: u32 = 16_777_215; pub const I24_MAX: i32 = 8_388_607; pub const U48_MAX: u64 = 281_474_976_710_655; pub const I48_MAX: i64 = 140_737_488_355_327; pub const U64_MAX: u64 = ::core::u64::MAX; pub const I64_MAX: u64 = ::core::i64::MAX as u64; macro_rules! calc_max { ($max:expr, $bytes:expr) => { calc_max!($max, $bytes, 8) }; ($max:expr, $bytes:expr, $maxbytes:expr) => { ($max - 1) >> (8 * ($maxbytes - $bytes)) }; } #[derive(Clone, Debug)] pub struct Wi128(pub T); impl Wi128 { pub fn clone(&self) -> T { self.0.clone() } } impl PartialEq for Wi128 { fn eq(&self, other: &T) -> bool { self.0.eq(other) } } impl Arbitrary for Wi128 { fn arbitrary(gen: &mut G) -> Wi128 { let max = calc_max!(::core::u128::MAX, gen.size(), 16); let output = (gen.gen::() as u128) | ((gen.gen::() as u128) << 64); Wi128(output & (max - 1)) } } impl Arbitrary for Wi128 { fn arbitrary(gen: &mut G) -> Wi128 { let max = calc_max!(::core::i128::MAX, gen.size(), 16); let output = (gen.gen::() as i128) | ((gen.gen::() as i128) << 64); Wi128(output & (max - 1)) } } pub fn qc_sized(f: A, size: u64) { QuickCheck::new() .gen(StdGen::new(thread_rng(), size as usize)) .tests(1_00) .max_tests(10_000) .quickcheck(f); } macro_rules! qc_byte_order { ($name:ident, $ty_int:ty, $max:expr, $bytes:expr, $read:ident, $write:ident) => { mod $name { #[allow(unused_imports)] use super::{qc_sized, Wi128}; use crate::{ BigEndian, ByteOrder, LittleEndian, NativeEndian, }; #[test] fn big_endian() { fn prop(n: $ty_int) -> bool { let mut buf = [0; 16]; BigEndian::$write(&mut buf, n.clone(), $bytes); n == BigEndian::$read(&buf[..$bytes], $bytes) } qc_sized(prop as fn($ty_int) -> bool, $max); } #[test] fn little_endian() { fn prop(n: $ty_int) -> bool { let mut buf = [0; 16]; LittleEndian::$write(&mut buf, n.clone(), $bytes); n == LittleEndian::$read(&buf[..$bytes], $bytes) } qc_sized(prop as fn($ty_int) -> bool, $max); } #[test] fn native_endian() { fn prop(n: $ty_int) -> bool { let mut buf = [0; 16]; NativeEndian::$write(&mut buf, n.clone(), $bytes); n == NativeEndian::$read(&buf[..$bytes], $bytes) } qc_sized(prop as fn($ty_int) -> bool, $max); } } }; ($name:ident, $ty_int:ty, $max:expr, $read:ident, $write:ident) => { mod $name { #[allow(unused_imports)] use super::{qc_sized, Wi128}; use crate::{ BigEndian, ByteOrder, LittleEndian, NativeEndian, }; use core::mem::size_of; #[test] fn big_endian() { fn prop(n: $ty_int) -> bool { let bytes = size_of::<$ty_int>(); let mut buf = [0; 16]; BigEndian::$write(&mut buf[16 - bytes..], n.clone()); n == BigEndian::$read(&buf[16 - bytes..]) } qc_sized(prop as fn($ty_int) -> bool, $max - 1); } #[test] fn little_endian() { fn prop(n: $ty_int) -> bool { let bytes = size_of::<$ty_int>(); let mut buf = [0; 16]; LittleEndian::$write(&mut buf[..bytes], n.clone()); n == LittleEndian::$read(&buf[..bytes]) } qc_sized(prop as fn($ty_int) -> bool, $max - 1); } #[test] fn native_endian() { fn prop(n: $ty_int) -> bool { let bytes = size_of::<$ty_int>(); let mut buf = [0; 16]; NativeEndian::$write(&mut buf[..bytes], n.clone()); n == NativeEndian::$read(&buf[..bytes]) } qc_sized(prop as fn($ty_int) -> bool, $max - 1); } } }; } qc_byte_order!( prop_u16, u16, ::core::u16::MAX as u64, read_u16, write_u16 ); qc_byte_order!( prop_i16, i16, ::core::i16::MAX as u64, read_i16, write_i16 ); qc_byte_order!( prop_u24, u32, crate::test::U24_MAX as u64, read_u24, write_u24 ); qc_byte_order!( prop_i24, i32, crate::test::I24_MAX as u64, read_i24, write_i24 ); qc_byte_order!( prop_u32, u32, ::core::u32::MAX as u64, read_u32, write_u32 ); qc_byte_order!( prop_i32, i32, ::core::i32::MAX as u64, read_i32, write_i32 ); qc_byte_order!( prop_u48, u64, crate::test::U48_MAX as u64, read_u48, write_u48 ); qc_byte_order!( prop_i48, i64, crate::test::I48_MAX as u64, read_i48, write_i48 ); qc_byte_order!( prop_u64, u64, ::core::u64::MAX as u64, read_u64, write_u64 ); qc_byte_order!( prop_i64, i64, ::core::i64::MAX as u64, read_i64, write_i64 ); qc_byte_order!( prop_f32, f32, ::core::u64::MAX as u64, read_f32, write_f32 ); qc_byte_order!( prop_f64, f64, ::core::i64::MAX as u64, read_f64, write_f64 ); qc_byte_order!(prop_u128, Wi128, 16 + 1, read_u128, write_u128); qc_byte_order!(prop_i128, Wi128, 16 + 1, read_i128, write_i128); qc_byte_order!( prop_uint_1, u64, calc_max!(super::U64_MAX, 1), 1, read_uint, write_uint ); qc_byte_order!( prop_uint_2, u64, calc_max!(super::U64_MAX, 2), 2, read_uint, write_uint ); qc_byte_order!( prop_uint_3, u64, calc_max!(super::U64_MAX, 3), 3, read_uint, write_uint ); qc_byte_order!( prop_uint_4, u64, calc_max!(super::U64_MAX, 4), 4, read_uint, write_uint ); qc_byte_order!( prop_uint_5, u64, calc_max!(super::U64_MAX, 5), 5, read_uint, write_uint ); qc_byte_order!( prop_uint_6, u64, calc_max!(super::U64_MAX, 6), 6, read_uint, write_uint ); qc_byte_order!( prop_uint_7, u64, calc_max!(super::U64_MAX, 7), 7, read_uint, write_uint ); qc_byte_order!( prop_uint_8, u64, calc_max!(super::U64_MAX, 8), 8, read_uint, write_uint ); qc_byte_order!( prop_uint128_1, Wi128, 1, 1, read_uint128, write_uint128 ); qc_byte_order!( prop_uint128_2, Wi128, 2, 2, read_uint128, write_uint128 ); qc_byte_order!( prop_uint128_3, Wi128, 3, 3, read_uint128, write_uint128 ); qc_byte_order!( prop_uint128_4, Wi128, 4, 4, read_uint128, write_uint128 ); qc_byte_order!( prop_uint128_5, Wi128, 5, 5, read_uint128, write_uint128 ); qc_byte_order!( prop_uint128_6, Wi128, 6, 6, read_uint128, write_uint128 ); qc_byte_order!( prop_uint128_7, Wi128, 7, 7, read_uint128, write_uint128 ); qc_byte_order!( prop_uint128_8, Wi128, 8, 8, read_uint128, write_uint128 ); qc_byte_order!( prop_uint128_9, Wi128, 9, 9, read_uint128, write_uint128 ); qc_byte_order!( prop_uint128_10, Wi128, 10, 10, read_uint128, write_uint128 ); qc_byte_order!( prop_uint128_11, Wi128, 11, 11, read_uint128, write_uint128 ); qc_byte_order!( prop_uint128_12, Wi128, 12, 12, read_uint128, write_uint128 ); qc_byte_order!( prop_uint128_13, Wi128, 13, 13, read_uint128, write_uint128 ); qc_byte_order!( prop_uint128_14, Wi128, 14, 14, read_uint128, write_uint128 ); qc_byte_order!( prop_uint128_15, Wi128, 15, 15, read_uint128, write_uint128 ); qc_byte_order!( prop_uint128_16, Wi128, 16, 16, read_uint128, write_uint128 ); qc_byte_order!( prop_int_1, i64, calc_max!(super::I64_MAX, 1), 1, read_int, write_int ); qc_byte_order!( prop_int_2, i64, calc_max!(super::I64_MAX, 2), 2, read_int, write_int ); qc_byte_order!( prop_int_3, i64, calc_max!(super::I64_MAX, 3), 3, read_int, write_int ); qc_byte_order!( prop_int_4, i64, calc_max!(super::I64_MAX, 4), 4, read_int, write_int ); qc_byte_order!( prop_int_5, i64, calc_max!(super::I64_MAX, 5), 5, read_int, write_int ); qc_byte_order!( prop_int_6, i64, calc_max!(super::I64_MAX, 6), 6, read_int, write_int ); qc_byte_order!( prop_int_7, i64, calc_max!(super::I64_MAX, 7), 7, read_int, write_int ); qc_byte_order!( prop_int_8, i64, calc_max!(super::I64_MAX, 8), 8, read_int, write_int ); qc_byte_order!( prop_int128_1, Wi128, 1, 1, read_int128, write_int128 ); qc_byte_order!( prop_int128_2, Wi128, 2, 2, read_int128, write_int128 ); qc_byte_order!( prop_int128_3, Wi128, 3, 3, read_int128, write_int128 ); qc_byte_order!( prop_int128_4, Wi128, 4, 4, read_int128, write_int128 ); qc_byte_order!( prop_int128_5, Wi128, 5, 5, read_int128, write_int128 ); qc_byte_order!( prop_int128_6, Wi128, 6, 6, read_int128, write_int128 ); qc_byte_order!( prop_int128_7, Wi128, 7, 7, read_int128, write_int128 ); qc_byte_order!( prop_int128_8, Wi128, 8, 8, read_int128, write_int128 ); qc_byte_order!( prop_int128_9, Wi128, 9, 9, read_int128, write_int128 ); qc_byte_order!( prop_int128_10, Wi128, 10, 10, read_int128, write_int128 ); qc_byte_order!( prop_int128_11, Wi128, 11, 11, read_int128, write_int128 ); qc_byte_order!( prop_int128_12, Wi128, 12, 12, read_int128, write_int128 ); qc_byte_order!( prop_int128_13, Wi128, 13, 13, read_int128, write_int128 ); qc_byte_order!( prop_int128_14, Wi128, 14, 14, read_int128, write_int128 ); qc_byte_order!( prop_int128_15, Wi128, 15, 15, read_int128, write_int128 ); qc_byte_order!( prop_int128_16, Wi128, 16, 16, read_int128, write_int128 ); // Test that all of the byte conversion functions panic when given a // buffer that is too small. // // These tests are critical to ensure safety, otherwise we might end up // with a buffer overflow. macro_rules! too_small { ($name:ident, $maximally_small:expr, $zero:expr, $read:ident, $write:ident) => { mod $name { use crate::{ BigEndian, ByteOrder, LittleEndian, NativeEndian, }; #[test] #[should_panic] fn read_big_endian() { let buf = [0; $maximally_small]; BigEndian::$read(&buf); } #[test] #[should_panic] fn read_little_endian() { let buf = [0; $maximally_small]; LittleEndian::$read(&buf); } #[test] #[should_panic] fn read_native_endian() { let buf = [0; $maximally_small]; NativeEndian::$read(&buf); } #[test] #[should_panic] fn write_big_endian() { let mut buf = [0; $maximally_small]; BigEndian::$write(&mut buf, $zero); } #[test] #[should_panic] fn write_little_endian() { let mut buf = [0; $maximally_small]; LittleEndian::$write(&mut buf, $zero); } #[test] #[should_panic] fn write_native_endian() { let mut buf = [0; $maximally_small]; NativeEndian::$write(&mut buf, $zero); } } }; ($name:ident, $maximally_small:expr, $read:ident) => { mod $name { use crate::{ BigEndian, ByteOrder, LittleEndian, NativeEndian, }; #[test] #[should_panic] fn read_big_endian() { let buf = [0; $maximally_small]; BigEndian::$read(&buf, $maximally_small + 1); } #[test] #[should_panic] fn read_little_endian() { let buf = [0; $maximally_small]; LittleEndian::$read(&buf, $maximally_small + 1); } #[test] #[should_panic] fn read_native_endian() { let buf = [0; $maximally_small]; NativeEndian::$read(&buf, $maximally_small + 1); } } }; } too_small!(small_u16, 1, 0, read_u16, write_u16); too_small!(small_i16, 1, 0, read_i16, write_i16); too_small!(small_u32, 3, 0, read_u32, write_u32); too_small!(small_i32, 3, 0, read_i32, write_i32); too_small!(small_u64, 7, 0, read_u64, write_u64); too_small!(small_i64, 7, 0, read_i64, write_i64); too_small!(small_f32, 3, 0.0, read_f32, write_f32); too_small!(small_f64, 7, 0.0, read_f64, write_f64); too_small!(small_u128, 15, 0, read_u128, write_u128); too_small!(small_i128, 15, 0, read_i128, write_i128); too_small!(small_uint_1, 1, read_uint); too_small!(small_uint_2, 2, read_uint); too_small!(small_uint_3, 3, read_uint); too_small!(small_uint_4, 4, read_uint); too_small!(small_uint_5, 5, read_uint); too_small!(small_uint_6, 6, read_uint); too_small!(small_uint_7, 7, read_uint); too_small!(small_uint128_1, 1, read_uint128); too_small!(small_uint128_2, 2, read_uint128); too_small!(small_uint128_3, 3, read_uint128); too_small!(small_uint128_4, 4, read_uint128); too_small!(small_uint128_5, 5, read_uint128); too_small!(small_uint128_6, 6, read_uint128); too_small!(small_uint128_7, 7, read_uint128); too_small!(small_uint128_8, 8, read_uint128); too_small!(small_uint128_9, 9, read_uint128); too_small!(small_uint128_10, 10, read_uint128); too_small!(small_uint128_11, 11, read_uint128); too_small!(small_uint128_12, 12, read_uint128); too_small!(small_uint128_13, 13, read_uint128); too_small!(small_uint128_14, 14, read_uint128); too_small!(small_uint128_15, 15, read_uint128); too_small!(small_int_1, 1, read_int); too_small!(small_int_2, 2, read_int); too_small!(small_int_3, 3, read_int); too_small!(small_int_4, 4, read_int); too_small!(small_int_5, 5, read_int); too_small!(small_int_6, 6, read_int); too_small!(small_int_7, 7, read_int); too_small!(small_int128_1, 1, read_int128); too_small!(small_int128_2, 2, read_int128); too_small!(small_int128_3, 3, read_int128); too_small!(small_int128_4, 4, read_int128); too_small!(small_int128_5, 5, read_int128); too_small!(small_int128_6, 6, read_int128); too_small!(small_int128_7, 7, read_int128); too_small!(small_int128_8, 8, read_int128); too_small!(small_int128_9, 9, read_int128); too_small!(small_int128_10, 10, read_int128); too_small!(small_int128_11, 11, read_int128); too_small!(small_int128_12, 12, read_int128); too_small!(small_int128_13, 13, read_int128); too_small!(small_int128_14, 14, read_int128); too_small!(small_int128_15, 15, read_int128); // Test that reading/writing slices enforces the correct lengths. macro_rules! slice_lengths { ($name:ident, $read:ident, $write:ident, $num_bytes:expr, $numbers:expr) => { mod $name { use crate::{ BigEndian, ByteOrder, LittleEndian, NativeEndian, }; #[test] #[should_panic] fn read_big_endian() { let bytes = [0; $num_bytes]; let mut numbers = $numbers; BigEndian::$read(&bytes, &mut numbers); } #[test] #[should_panic] fn read_little_endian() { let bytes = [0; $num_bytes]; let mut numbers = $numbers; LittleEndian::$read(&bytes, &mut numbers); } #[test] #[should_panic] fn read_native_endian() { let bytes = [0; $num_bytes]; let mut numbers = $numbers; NativeEndian::$read(&bytes, &mut numbers); } #[test] #[should_panic] fn write_big_endian() { let mut bytes = [0; $num_bytes]; let numbers = $numbers; BigEndian::$write(&numbers, &mut bytes); } #[test] #[should_panic] fn write_little_endian() { let mut bytes = [0; $num_bytes]; let numbers = $numbers; LittleEndian::$write(&numbers, &mut bytes); } #[test] #[should_panic] fn write_native_endian() { let mut bytes = [0; $num_bytes]; let numbers = $numbers; NativeEndian::$write(&numbers, &mut bytes); } } }; } slice_lengths!( slice_len_too_small_u16, read_u16_into, write_u16_into, 3, [0, 0] ); slice_lengths!( slice_len_too_big_u16, read_u16_into, write_u16_into, 5, [0, 0] ); slice_lengths!( slice_len_too_small_i16, read_i16_into, write_i16_into, 3, [0, 0] ); slice_lengths!( slice_len_too_big_i16, read_i16_into, write_i16_into, 5, [0, 0] ); slice_lengths!( slice_len_too_small_u32, read_u32_into, write_u32_into, 7, [0, 0] ); slice_lengths!( slice_len_too_big_u32, read_u32_into, write_u32_into, 9, [0, 0] ); slice_lengths!( slice_len_too_small_i32, read_i32_into, write_i32_into, 7, [0, 0] ); slice_lengths!( slice_len_too_big_i32, read_i32_into, write_i32_into, 9, [0, 0] ); slice_lengths!( slice_len_too_small_u64, read_u64_into, write_u64_into, 15, [0, 0] ); slice_lengths!( slice_len_too_big_u64, read_u64_into, write_u64_into, 17, [0, 0] ); slice_lengths!( slice_len_too_small_i64, read_i64_into, write_i64_into, 15, [0, 0] ); slice_lengths!( slice_len_too_big_i64, read_i64_into, write_i64_into, 17, [0, 0] ); slice_lengths!( slice_len_too_small_u128, read_u128_into, write_u128_into, 31, [0, 0] ); slice_lengths!( slice_len_too_big_u128, read_u128_into, write_u128_into, 33, [0, 0] ); slice_lengths!( slice_len_too_small_i128, read_i128_into, write_i128_into, 31, [0, 0] ); slice_lengths!( slice_len_too_big_i128, read_i128_into, write_i128_into, 33, [0, 0] ); #[test] fn uint_bigger_buffer() { use crate::{ByteOrder, LittleEndian}; let n = LittleEndian::read_uint(&[1, 2, 3, 4, 5, 6, 7, 8], 5); assert_eq!(n, 0x05_0403_0201); } #[test] fn regression173_array_impl() { use crate::{BigEndian, ByteOrder, LittleEndian}; let xs = [0; 100]; let x = BigEndian::read_u16(&xs); assert_eq!(x, 0); let x = BigEndian::read_u32(&xs); assert_eq!(x, 0); let x = BigEndian::read_u64(&xs); assert_eq!(x, 0); let x = BigEndian::read_u128(&xs); assert_eq!(x, 0); let x = BigEndian::read_i16(&xs); assert_eq!(x, 0); let x = BigEndian::read_i32(&xs); assert_eq!(x, 0); let x = BigEndian::read_i64(&xs); assert_eq!(x, 0); let x = BigEndian::read_i128(&xs); assert_eq!(x, 0); let x = LittleEndian::read_u16(&xs); assert_eq!(x, 0); let x = LittleEndian::read_u32(&xs); assert_eq!(x, 0); let x = LittleEndian::read_u64(&xs); assert_eq!(x, 0); let x = LittleEndian::read_u128(&xs); assert_eq!(x, 0); let x = LittleEndian::read_i16(&xs); assert_eq!(x, 0); let x = LittleEndian::read_i32(&xs); assert_eq!(x, 0); let x = LittleEndian::read_i64(&xs); assert_eq!(x, 0); let x = LittleEndian::read_i128(&xs); assert_eq!(x, 0); } } #[cfg(test)] #[cfg(feature = "std")] mod stdtests { extern crate quickcheck; extern crate rand; use self::quickcheck::{QuickCheck, StdGen, Testable}; use self::rand::thread_rng; fn qc_unsized(f: A) { QuickCheck::new() .gen(StdGen::new(thread_rng(), 16)) .tests(1_00) .max_tests(10_000) .quickcheck(f); } macro_rules! calc_max { ($max:expr, $bytes:expr) => { ($max - 1) >> (8 * (8 - $bytes)) }; } macro_rules! qc_bytes_ext { ($name:ident, $ty_int:ty, $max:expr, $bytes:expr, $read:ident, $write:ident) => { mod $name { #[allow(unused_imports)] use crate::test::{qc_sized, Wi128}; use crate::{ BigEndian, LittleEndian, NativeEndian, ReadBytesExt, WriteBytesExt, }; use std::io::Cursor; #[test] fn big_endian() { fn prop(n: $ty_int) -> bool { let mut wtr = vec![]; wtr.$write::(n.clone()).unwrap(); let offset = wtr.len() - $bytes; let mut rdr = Cursor::new(&mut wtr[offset..]); n == rdr.$read::($bytes).unwrap() } qc_sized(prop as fn($ty_int) -> bool, $max); } #[test] fn little_endian() { fn prop(n: $ty_int) -> bool { let mut wtr = vec![]; wtr.$write::(n.clone()).unwrap(); let mut rdr = Cursor::new(wtr); n == rdr.$read::($bytes).unwrap() } qc_sized(prop as fn($ty_int) -> bool, $max); } #[test] fn native_endian() { fn prop(n: $ty_int) -> bool { let mut wtr = vec![]; wtr.$write::(n.clone()).unwrap(); let offset = if cfg!(target_endian = "big") { wtr.len() - $bytes } else { 0 }; let mut rdr = Cursor::new(&mut wtr[offset..]); n == rdr.$read::($bytes).unwrap() } qc_sized(prop as fn($ty_int) -> bool, $max); } } }; ($name:ident, $ty_int:ty, $max:expr, $read:ident, $write:ident) => { mod $name { #[allow(unused_imports)] use crate::test::{qc_sized, Wi128}; use crate::{ BigEndian, LittleEndian, NativeEndian, ReadBytesExt, WriteBytesExt, }; use std::io::Cursor; #[test] fn big_endian() { fn prop(n: $ty_int) -> bool { let mut wtr = vec![]; wtr.$write::(n.clone()).unwrap(); let mut rdr = Cursor::new(wtr); n == rdr.$read::().unwrap() } qc_sized(prop as fn($ty_int) -> bool, $max - 1); } #[test] fn little_endian() { fn prop(n: $ty_int) -> bool { let mut wtr = vec![]; wtr.$write::(n.clone()).unwrap(); let mut rdr = Cursor::new(wtr); n == rdr.$read::().unwrap() } qc_sized(prop as fn($ty_int) -> bool, $max - 1); } #[test] fn native_endian() { fn prop(n: $ty_int) -> bool { let mut wtr = vec![]; wtr.$write::(n.clone()).unwrap(); let mut rdr = Cursor::new(wtr); n == rdr.$read::().unwrap() } qc_sized(prop as fn($ty_int) -> bool, $max - 1); } } }; } qc_bytes_ext!( prop_ext_u16, u16, ::std::u16::MAX as u64, read_u16, write_u16 ); qc_bytes_ext!( prop_ext_i16, i16, ::std::i16::MAX as u64, read_i16, write_i16 ); qc_bytes_ext!( prop_ext_u32, u32, ::std::u32::MAX as u64, read_u32, write_u32 ); qc_bytes_ext!( prop_ext_i32, i32, ::std::i32::MAX as u64, read_i32, write_i32 ); qc_bytes_ext!( prop_ext_u64, u64, ::std::u64::MAX as u64, read_u64, write_u64 ); qc_bytes_ext!( prop_ext_i64, i64, ::std::i64::MAX as u64, read_i64, write_i64 ); qc_bytes_ext!( prop_ext_f32, f32, ::std::u64::MAX as u64, read_f32, write_f32 ); qc_bytes_ext!( prop_ext_f64, f64, ::std::i64::MAX as u64, read_f64, write_f64 ); qc_bytes_ext!(prop_ext_u128, Wi128, 16 + 1, read_u128, write_u128); qc_bytes_ext!(prop_ext_i128, Wi128, 16 + 1, read_i128, write_i128); qc_bytes_ext!( prop_ext_uint_1, u64, calc_max!(crate::test::U64_MAX, 1), 1, read_uint, write_u64 ); qc_bytes_ext!( prop_ext_uint_2, u64, calc_max!(crate::test::U64_MAX, 2), 2, read_uint, write_u64 ); qc_bytes_ext!( prop_ext_uint_3, u64, calc_max!(crate::test::U64_MAX, 3), 3, read_uint, write_u64 ); qc_bytes_ext!( prop_ext_uint_4, u64, calc_max!(crate::test::U64_MAX, 4), 4, read_uint, write_u64 ); qc_bytes_ext!( prop_ext_uint_5, u64, calc_max!(crate::test::U64_MAX, 5), 5, read_uint, write_u64 ); qc_bytes_ext!( prop_ext_uint_6, u64, calc_max!(crate::test::U64_MAX, 6), 6, read_uint, write_u64 ); qc_bytes_ext!( prop_ext_uint_7, u64, calc_max!(crate::test::U64_MAX, 7), 7, read_uint, write_u64 ); qc_bytes_ext!( prop_ext_uint_8, u64, calc_max!(crate::test::U64_MAX, 8), 8, read_uint, write_u64 ); qc_bytes_ext!( prop_ext_uint128_1, Wi128, 1, 1, read_uint128, write_u128 ); qc_bytes_ext!( prop_ext_uint128_2, Wi128, 2, 2, read_uint128, write_u128 ); qc_bytes_ext!( prop_ext_uint128_3, Wi128, 3, 3, read_uint128, write_u128 ); qc_bytes_ext!( prop_ext_uint128_4, Wi128, 4, 4, read_uint128, write_u128 ); qc_bytes_ext!( prop_ext_uint128_5, Wi128, 5, 5, read_uint128, write_u128 ); qc_bytes_ext!( prop_ext_uint128_6, Wi128, 6, 6, read_uint128, write_u128 ); qc_bytes_ext!( prop_ext_uint128_7, Wi128, 7, 7, read_uint128, write_u128 ); qc_bytes_ext!( prop_ext_uint128_8, Wi128, 8, 8, read_uint128, write_u128 ); qc_bytes_ext!( prop_ext_uint128_9, Wi128, 9, 9, read_uint128, write_u128 ); qc_bytes_ext!( prop_ext_uint128_10, Wi128, 10, 10, read_uint128, write_u128 ); qc_bytes_ext!( prop_ext_uint128_11, Wi128, 11, 11, read_uint128, write_u128 ); qc_bytes_ext!( prop_ext_uint128_12, Wi128, 12, 12, read_uint128, write_u128 ); qc_bytes_ext!( prop_ext_uint128_13, Wi128, 13, 13, read_uint128, write_u128 ); qc_bytes_ext!( prop_ext_uint128_14, Wi128, 14, 14, read_uint128, write_u128 ); qc_bytes_ext!( prop_ext_uint128_15, Wi128, 15, 15, read_uint128, write_u128 ); qc_bytes_ext!( prop_ext_uint128_16, Wi128, 16, 16, read_uint128, write_u128 ); qc_bytes_ext!( prop_ext_int_1, i64, calc_max!(crate::test::I64_MAX, 1), 1, read_int, write_i64 ); qc_bytes_ext!( prop_ext_int_2, i64, calc_max!(crate::test::I64_MAX, 2), 2, read_int, write_i64 ); qc_bytes_ext!( prop_ext_int_3, i64, calc_max!(crate::test::I64_MAX, 3), 3, read_int, write_i64 ); qc_bytes_ext!( prop_ext_int_4, i64, calc_max!(crate::test::I64_MAX, 4), 4, read_int, write_i64 ); qc_bytes_ext!( prop_ext_int_5, i64, calc_max!(crate::test::I64_MAX, 5), 5, read_int, write_i64 ); qc_bytes_ext!( prop_ext_int_6, i64, calc_max!(crate::test::I64_MAX, 6), 6, read_int, write_i64 ); qc_bytes_ext!( prop_ext_int_7, i64, calc_max!(crate::test::I64_MAX, 1), 7, read_int, write_i64 ); qc_bytes_ext!( prop_ext_int_8, i64, calc_max!(crate::test::I64_MAX, 8), 8, read_int, write_i64 ); qc_bytes_ext!( prop_ext_int128_1, Wi128, 1, 1, read_int128, write_i128 ); qc_bytes_ext!( prop_ext_int128_2, Wi128, 2, 2, read_int128, write_i128 ); qc_bytes_ext!( prop_ext_int128_3, Wi128, 3, 3, read_int128, write_i128 ); qc_bytes_ext!( prop_ext_int128_4, Wi128, 4, 4, read_int128, write_i128 ); qc_bytes_ext!( prop_ext_int128_5, Wi128, 5, 5, read_int128, write_i128 ); qc_bytes_ext!( prop_ext_int128_6, Wi128, 6, 6, read_int128, write_i128 ); qc_bytes_ext!( prop_ext_int128_7, Wi128, 7, 7, read_int128, write_i128 ); qc_bytes_ext!( prop_ext_int128_8, Wi128, 8, 8, read_int128, write_i128 ); qc_bytes_ext!( prop_ext_int128_9, Wi128, 9, 9, read_int128, write_i128 ); qc_bytes_ext!( prop_ext_int128_10, Wi128, 10, 10, read_int128, write_i128 ); qc_bytes_ext!( prop_ext_int128_11, Wi128, 11, 11, read_int128, write_i128 ); qc_bytes_ext!( prop_ext_int128_12, Wi128, 12, 12, read_int128, write_i128 ); qc_bytes_ext!( prop_ext_int128_13, Wi128, 13, 13, read_int128, write_i128 ); qc_bytes_ext!( prop_ext_int128_14, Wi128, 14, 14, read_int128, write_i128 ); qc_bytes_ext!( prop_ext_int128_15, Wi128, 15, 15, read_int128, write_i128 ); qc_bytes_ext!( prop_ext_int128_16, Wi128, 16, 16, read_int128, write_i128 ); // Test slice serialization/deserialization. macro_rules! qc_slice { ($name:ident, $ty_int:ty, $read:ident, $write:ident, $zero:expr) => { mod $name { use super::qc_unsized; #[allow(unused_imports)] use crate::test::Wi128; use crate::{ BigEndian, ByteOrder, LittleEndian, NativeEndian, }; use core::mem::size_of; #[test] fn big_endian() { #[allow(unused_unsafe)] fn prop(numbers: Vec<$ty_int>) -> bool { let numbers: Vec<_> = numbers.into_iter().map(|x| x.clone()).collect(); let num_bytes = size_of::<$ty_int>() * numbers.len(); let mut bytes = vec![0; num_bytes]; BigEndian::$write(&numbers, &mut bytes); let mut got = vec![$zero; numbers.len()]; unsafe { BigEndian::$read(&bytes, &mut got); } numbers == got } qc_unsized(prop as fn(_) -> bool); } #[test] fn little_endian() { #[allow(unused_unsafe)] fn prop(numbers: Vec<$ty_int>) -> bool { let numbers: Vec<_> = numbers.into_iter().map(|x| x.clone()).collect(); let num_bytes = size_of::<$ty_int>() * numbers.len(); let mut bytes = vec![0; num_bytes]; LittleEndian::$write(&numbers, &mut bytes); let mut got = vec![$zero; numbers.len()]; unsafe { LittleEndian::$read(&bytes, &mut got); } numbers == got } qc_unsized(prop as fn(_) -> bool); } #[test] fn native_endian() { #[allow(unused_unsafe)] fn prop(numbers: Vec<$ty_int>) -> bool { let numbers: Vec<_> = numbers.into_iter().map(|x| x.clone()).collect(); let num_bytes = size_of::<$ty_int>() * numbers.len(); let mut bytes = vec![0; num_bytes]; NativeEndian::$write(&numbers, &mut bytes); let mut got = vec![$zero; numbers.len()]; unsafe { NativeEndian::$read(&bytes, &mut got); } numbers == got } qc_unsized(prop as fn(_) -> bool); } } }; } qc_slice!(prop_slice_u16, u16, read_u16_into, write_u16_into, 0); qc_slice!(prop_slice_i16, i16, read_i16_into, write_i16_into, 0); qc_slice!(prop_slice_u32, u32, read_u32_into, write_u32_into, 0); qc_slice!(prop_slice_i32, i32, read_i32_into, write_i32_into, 0); qc_slice!(prop_slice_u64, u64, read_u64_into, write_u64_into, 0); qc_slice!(prop_slice_i64, i64, read_i64_into, write_i64_into, 0); qc_slice!( prop_slice_u128, Wi128, read_u128_into, write_u128_into, 0 ); qc_slice!( prop_slice_i128, Wi128, read_i128_into, write_i128_into, 0 ); qc_slice!(prop_slice_f32, f32, read_f32_into, write_f32_into, 0.0); qc_slice!(prop_slice_f64, f64, read_f64_into, write_f64_into, 0.0); }