| /*! |
| 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::<BigEndian>().unwrap()); |
| assert_eq!(768, rdr.read_u16::<BigEndian>().unwrap()); |
| ``` |
| |
| Write unsigned 16 bit little-endian integers to a [`Write`] type: |
| |
| ```rust |
| use byteorder::{LittleEndian, WriteBytesExt}; |
| |
| let mut wtr = vec![]; |
| wtr.write_u16::<LittleEndian>(517).unwrap(); |
| wtr.write_u16::<LittleEndian>(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 [<numeric>] $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<T>(pub T); |
| |
| impl<T: Clone> Wi128<T> { |
| pub fn clone(&self) -> T { |
| self.0.clone() |
| } |
| } |
| |
| impl<T: PartialEq> PartialEq<T> for Wi128<T> { |
| fn eq(&self, other: &T) -> bool { |
| self.0.eq(other) |
| } |
| } |
| |
| impl Arbitrary for Wi128<u128> { |
| fn arbitrary<G: Gen>(gen: &mut G) -> Wi128<u128> { |
| let max = calc_max!(::core::u128::MAX, gen.size(), 16); |
| let output = (gen.gen::<u64>() as u128) |
| | ((gen.gen::<u64>() as u128) << 64); |
| Wi128(output & (max - 1)) |
| } |
| } |
| |
| impl Arbitrary for Wi128<i128> { |
| fn arbitrary<G: Gen>(gen: &mut G) -> Wi128<i128> { |
| let max = calc_max!(::core::i128::MAX, gen.size(), 16); |
| let output = (gen.gen::<i64>() as i128) |
| | ((gen.gen::<i64>() as i128) << 64); |
| Wi128(output & (max - 1)) |
| } |
| } |
| |
| pub fn qc_sized<A: Testable>(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<u128>, 16 + 1, read_u128, write_u128); |
| qc_byte_order!(prop_i128, Wi128<i128>, 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<u128>, |
| 1, |
| 1, |
| read_uint128, |
| write_uint128 |
| ); |
| qc_byte_order!( |
| prop_uint128_2, |
| Wi128<u128>, |
| 2, |
| 2, |
| read_uint128, |
| write_uint128 |
| ); |
| qc_byte_order!( |
| prop_uint128_3, |
| Wi128<u128>, |
| 3, |
| 3, |
| read_uint128, |
| write_uint128 |
| ); |
| qc_byte_order!( |
| prop_uint128_4, |
| Wi128<u128>, |
| 4, |
| 4, |
| read_uint128, |
| write_uint128 |
| ); |
| qc_byte_order!( |
| prop_uint128_5, |
| Wi128<u128>, |
| 5, |
| 5, |
| read_uint128, |
| write_uint128 |
| ); |
| qc_byte_order!( |
| prop_uint128_6, |
| Wi128<u128>, |
| 6, |
| 6, |
| read_uint128, |
| write_uint128 |
| ); |
| qc_byte_order!( |
| prop_uint128_7, |
| Wi128<u128>, |
| 7, |
| 7, |
| read_uint128, |
| write_uint128 |
| ); |
| qc_byte_order!( |
| prop_uint128_8, |
| Wi128<u128>, |
| 8, |
| 8, |
| read_uint128, |
| write_uint128 |
| ); |
| qc_byte_order!( |
| prop_uint128_9, |
| Wi128<u128>, |
| 9, |
| 9, |
| read_uint128, |
| write_uint128 |
| ); |
| qc_byte_order!( |
| prop_uint128_10, |
| Wi128<u128>, |
| 10, |
| 10, |
| read_uint128, |
| write_uint128 |
| ); |
| qc_byte_order!( |
| prop_uint128_11, |
| Wi128<u128>, |
| 11, |
| 11, |
| read_uint128, |
| write_uint128 |
| ); |
| qc_byte_order!( |
| prop_uint128_12, |
| Wi128<u128>, |
| 12, |
| 12, |
| read_uint128, |
| write_uint128 |
| ); |
| qc_byte_order!( |
| prop_uint128_13, |
| Wi128<u128>, |
| 13, |
| 13, |
| read_uint128, |
| write_uint128 |
| ); |
| qc_byte_order!( |
| prop_uint128_14, |
| Wi128<u128>, |
| 14, |
| 14, |
| read_uint128, |
| write_uint128 |
| ); |
| qc_byte_order!( |
| prop_uint128_15, |
| Wi128<u128>, |
| 15, |
| 15, |
| read_uint128, |
| write_uint128 |
| ); |
| qc_byte_order!( |
| prop_uint128_16, |
| Wi128<u128>, |
| 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<i128>, |
| 1, |
| 1, |
| read_int128, |
| write_int128 |
| ); |
| qc_byte_order!( |
| prop_int128_2, |
| Wi128<i128>, |
| 2, |
| 2, |
| read_int128, |
| write_int128 |
| ); |
| qc_byte_order!( |
| prop_int128_3, |
| Wi128<i128>, |
| 3, |
| 3, |
| read_int128, |
| write_int128 |
| ); |
| qc_byte_order!( |
| prop_int128_4, |
| Wi128<i128>, |
| 4, |
| 4, |
| read_int128, |
| write_int128 |
| ); |
| qc_byte_order!( |
| prop_int128_5, |
| Wi128<i128>, |
| 5, |
| 5, |
| read_int128, |
| write_int128 |
| ); |
| qc_byte_order!( |
| prop_int128_6, |
| Wi128<i128>, |
| 6, |
| 6, |
| read_int128, |
| write_int128 |
| ); |
| qc_byte_order!( |
| prop_int128_7, |
| Wi128<i128>, |
| 7, |
| 7, |
| read_int128, |
| write_int128 |
| ); |
| qc_byte_order!( |
| prop_int128_8, |
| Wi128<i128>, |
| 8, |
| 8, |
| read_int128, |
| write_int128 |
| ); |
| qc_byte_order!( |
| prop_int128_9, |
| Wi128<i128>, |
| 9, |
| 9, |
| read_int128, |
| write_int128 |
| ); |
| qc_byte_order!( |
| prop_int128_10, |
| Wi128<i128>, |
| 10, |
| 10, |
| read_int128, |
| write_int128 |
| ); |
| qc_byte_order!( |
| prop_int128_11, |
| Wi128<i128>, |
| 11, |
| 11, |
| read_int128, |
| write_int128 |
| ); |
| qc_byte_order!( |
| prop_int128_12, |
| Wi128<i128>, |
| 12, |
| 12, |
| read_int128, |
| write_int128 |
| ); |
| qc_byte_order!( |
| prop_int128_13, |
| Wi128<i128>, |
| 13, |
| 13, |
| read_int128, |
| write_int128 |
| ); |
| qc_byte_order!( |
| prop_int128_14, |
| Wi128<i128>, |
| 14, |
| 14, |
| read_int128, |
| write_int128 |
| ); |
| qc_byte_order!( |
| prop_int128_15, |
| Wi128<i128>, |
| 15, |
| 15, |
| read_int128, |
| write_int128 |
| ); |
| qc_byte_order!( |
| prop_int128_16, |
| Wi128<i128>, |
| 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<A: Testable>(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::<BigEndian>(n.clone()).unwrap(); |
| let offset = wtr.len() - $bytes; |
| let mut rdr = Cursor::new(&mut wtr[offset..]); |
| n == rdr.$read::<BigEndian>($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::<LittleEndian>(n.clone()).unwrap(); |
| let mut rdr = Cursor::new(wtr); |
| n == rdr.$read::<LittleEndian>($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::<NativeEndian>(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::<NativeEndian>($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::<BigEndian>(n.clone()).unwrap(); |
| let mut rdr = Cursor::new(wtr); |
| n == rdr.$read::<BigEndian>().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::<LittleEndian>(n.clone()).unwrap(); |
| let mut rdr = Cursor::new(wtr); |
| n == rdr.$read::<LittleEndian>().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::<NativeEndian>(n.clone()).unwrap(); |
| let mut rdr = Cursor::new(wtr); |
| n == rdr.$read::<NativeEndian>().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<u128>, 16 + 1, read_u128, write_u128); |
| qc_bytes_ext!(prop_ext_i128, Wi128<i128>, 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<u128>, |
| 1, |
| 1, |
| read_uint128, |
| write_u128 |
| ); |
| qc_bytes_ext!( |
| prop_ext_uint128_2, |
| Wi128<u128>, |
| 2, |
| 2, |
| read_uint128, |
| write_u128 |
| ); |
| qc_bytes_ext!( |
| prop_ext_uint128_3, |
| Wi128<u128>, |
| 3, |
| 3, |
| read_uint128, |
| write_u128 |
| ); |
| qc_bytes_ext!( |
| prop_ext_uint128_4, |
| Wi128<u128>, |
| 4, |
| 4, |
| read_uint128, |
| write_u128 |
| ); |
| qc_bytes_ext!( |
| prop_ext_uint128_5, |
| Wi128<u128>, |
| 5, |
| 5, |
| read_uint128, |
| write_u128 |
| ); |
| qc_bytes_ext!( |
| prop_ext_uint128_6, |
| Wi128<u128>, |
| 6, |
| 6, |
| read_uint128, |
| write_u128 |
| ); |
| qc_bytes_ext!( |
| prop_ext_uint128_7, |
| Wi128<u128>, |
| 7, |
| 7, |
| read_uint128, |
| write_u128 |
| ); |
| qc_bytes_ext!( |
| prop_ext_uint128_8, |
| Wi128<u128>, |
| 8, |
| 8, |
| read_uint128, |
| write_u128 |
| ); |
| qc_bytes_ext!( |
| prop_ext_uint128_9, |
| Wi128<u128>, |
| 9, |
| 9, |
| read_uint128, |
| write_u128 |
| ); |
| qc_bytes_ext!( |
| prop_ext_uint128_10, |
| Wi128<u128>, |
| 10, |
| 10, |
| read_uint128, |
| write_u128 |
| ); |
| qc_bytes_ext!( |
| prop_ext_uint128_11, |
| Wi128<u128>, |
| 11, |
| 11, |
| read_uint128, |
| write_u128 |
| ); |
| qc_bytes_ext!( |
| prop_ext_uint128_12, |
| Wi128<u128>, |
| 12, |
| 12, |
| read_uint128, |
| write_u128 |
| ); |
| qc_bytes_ext!( |
| prop_ext_uint128_13, |
| Wi128<u128>, |
| 13, |
| 13, |
| read_uint128, |
| write_u128 |
| ); |
| qc_bytes_ext!( |
| prop_ext_uint128_14, |
| Wi128<u128>, |
| 14, |
| 14, |
| read_uint128, |
| write_u128 |
| ); |
| qc_bytes_ext!( |
| prop_ext_uint128_15, |
| Wi128<u128>, |
| 15, |
| 15, |
| read_uint128, |
| write_u128 |
| ); |
| qc_bytes_ext!( |
| prop_ext_uint128_16, |
| Wi128<u128>, |
| 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<i128>, |
| 1, |
| 1, |
| read_int128, |
| write_i128 |
| ); |
| qc_bytes_ext!( |
| prop_ext_int128_2, |
| Wi128<i128>, |
| 2, |
| 2, |
| read_int128, |
| write_i128 |
| ); |
| qc_bytes_ext!( |
| prop_ext_int128_3, |
| Wi128<i128>, |
| 3, |
| 3, |
| read_int128, |
| write_i128 |
| ); |
| qc_bytes_ext!( |
| prop_ext_int128_4, |
| Wi128<i128>, |
| 4, |
| 4, |
| read_int128, |
| write_i128 |
| ); |
| qc_bytes_ext!( |
| prop_ext_int128_5, |
| Wi128<i128>, |
| 5, |
| 5, |
| read_int128, |
| write_i128 |
| ); |
| qc_bytes_ext!( |
| prop_ext_int128_6, |
| Wi128<i128>, |
| 6, |
| 6, |
| read_int128, |
| write_i128 |
| ); |
| qc_bytes_ext!( |
| prop_ext_int128_7, |
| Wi128<i128>, |
| 7, |
| 7, |
| read_int128, |
| write_i128 |
| ); |
| qc_bytes_ext!( |
| prop_ext_int128_8, |
| Wi128<i128>, |
| 8, |
| 8, |
| read_int128, |
| write_i128 |
| ); |
| qc_bytes_ext!( |
| prop_ext_int128_9, |
| Wi128<i128>, |
| 9, |
| 9, |
| read_int128, |
| write_i128 |
| ); |
| qc_bytes_ext!( |
| prop_ext_int128_10, |
| Wi128<i128>, |
| 10, |
| 10, |
| read_int128, |
| write_i128 |
| ); |
| qc_bytes_ext!( |
| prop_ext_int128_11, |
| Wi128<i128>, |
| 11, |
| 11, |
| read_int128, |
| write_i128 |
| ); |
| qc_bytes_ext!( |
| prop_ext_int128_12, |
| Wi128<i128>, |
| 12, |
| 12, |
| read_int128, |
| write_i128 |
| ); |
| qc_bytes_ext!( |
| prop_ext_int128_13, |
| Wi128<i128>, |
| 13, |
| 13, |
| read_int128, |
| write_i128 |
| ); |
| qc_bytes_ext!( |
| prop_ext_int128_14, |
| Wi128<i128>, |
| 14, |
| 14, |
| read_int128, |
| write_i128 |
| ); |
| qc_bytes_ext!( |
| prop_ext_int128_15, |
| Wi128<i128>, |
| 15, |
| 15, |
| read_int128, |
| write_i128 |
| ); |
| qc_bytes_ext!( |
| prop_ext_int128_16, |
| Wi128<i128>, |
| 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<u128>, |
| read_u128_into, |
| write_u128_into, |
| 0 |
| ); |
| qc_slice!( |
| prop_slice_i128, |
| Wi128<i128>, |
| 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); |
| } |