byteorder-1.5.0/.cargo_vcs_info.json0000644000000001360000000000100130360ustar { "git": { "sha1": "ec068eefa042d494475db125c4b034bd8e9e34dd" }, "path_in_vcs": "" }byteorder-1.5.0/.github/workflows/ci.yml000064400000000000000000000141431046102023000163440ustar 00000000000000name: ci on: pull_request: branches: - master push: branches: - master schedule: - cron: '00 01 * * *' # The section is needed to drop write-all permissions that are granted on # `schedule` event. By specifying any permission explicitly all others are set # to none. By using the principle of least privilege the damage a compromised # workflow can do (because of an injection or compromised third party tool or # action) is restricted. Currently the worklow doesn't need any additional # permission except for pulling the code. Adding labels to issues, commenting # on pull-requests, etc. may need additional permissions: # # Syntax for this section: # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions # # Reference for how to assign permissions on a job-by-job basis: # https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs # # Reference for available permissions that we can enable if needed: # https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token permissions: # to fetch code (actions/checkout) contents: read jobs: test: name: test env: # For some builds, we use cross to test on 32-bit and big-endian # systems. CARGO: cargo # When CARGO is set to CROSS, TARGET is set to `--target matrix.target`. # Note that we only use cross on Linux, so setting a target on a # different OS will just use normal cargo. TARGET: # Bump this as appropriate. We pin to a version to make sure CI # continues to work as cross releases in the past have broken things # in subtle ways. CROSS_VERSION: v0.2.5 runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: include: - build: pinned os: ubuntu-latest rust: 1.60.0 - build: stable os: ubuntu-latest rust: stable - build: beta os: ubuntu-latest rust: beta - build: nightly os: ubuntu-latest rust: nightly - build: macos os: macos-latest rust: stable - build: win-msvc os: windows-latest rust: stable - build: win-gnu os: windows-latest rust: stable-x86_64-gnu - build: stable-x86 os: ubuntu-latest rust: stable target: i686-unknown-linux-gnu - build: stable-aarch64 os: ubuntu-latest rust: stable target: aarch64-unknown-linux-gnu - build: stable-powerpc64 os: ubuntu-latest rust: stable target: powerpc64-unknown-linux-gnu - build: stable-s390x os: ubuntu-latest rust: stable target: s390x-unknown-linux-gnu steps: - name: Checkout repository uses: actions/checkout@v4 - name: Install Rust uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.rust }} - name: Use Cross if: matrix.os == 'ubuntu-latest' && matrix.target != '' run: | # In the past, new releases of 'cross' have broken CI. So for now, we # pin it. We also use their pre-compiled binary releases because cross # has over 100 dependencies and takes a bit to compile. dir="$RUNNER_TEMP/cross-download" mkdir "$dir" echo "$dir" >> $GITHUB_PATH cd "$dir" curl -LO "https://github.com/cross-rs/cross/releases/download/$CROSS_VERSION/cross-x86_64-unknown-linux-musl.tar.gz" tar xf cross-x86_64-unknown-linux-musl.tar.gz echo "CARGO=cross" >> $GITHUB_ENV echo "TARGET=--target ${{ matrix.target }}" >> $GITHUB_ENV - name: Show command used for Cargo run: | echo "cargo command is: ${{ env.CARGO }}" echo "target flag is: ${{ env.TARGET }}" - name: Show CPU info for debugging if: matrix.os == 'ubuntu-latest' run: lscpu - name: Build run: ${{ env.CARGO }} build --verbose $TARGET - name: Build (no default) run: ${{ env.CARGO }} build --verbose $TARGET --no-default-features - name: Build docs run: ${{ env.CARGO }} doc --verbose $TARGET # Our dev dependencies evolve more rapidly than we'd like, so only run # tests when we aren't pinning the Rust version. - name: Tests if: matrix.build != 'pinned' run: ${{ env.CARGO }} test --verbose $TARGET - name: Tests (no default, lib only) if: matrix.build != 'pinned' run: ${{ env.CARGO }} test --verbose --no-default-features --lib $TARGET - name: Tests (i128) if: matrix.build != 'pinned' run: ${{ env.CARGO }} test --verbose --features i128 $TARGET - name: Tests (no default, lib only, i128) if: matrix.build != 'pinned' run: ${{ env.CARGO }} test --verbose --no-default-features --features i128 --lib $TARGET - name: Compile benchmarks if: matrix.build == 'nightly' run: cargo bench --verbose --no-run $TARGET - name: Compile benchmarks (no default) if: matrix.build == 'nightly' run: cargo bench --verbose --no-run --no-default-features $TARGET - name: Compile benchmarks (i128) if: matrix.build == 'nightly' run: cargo bench --verbose --no-run --features i128 $TARGET - name: Compile benchmarks (no default, i128) if: matrix.build == 'nightly' run: cargo bench --verbose --no-run --no-default-features --features i128 $TARGET miri: runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 - name: Install Rust uses: dtolnay/rust-toolchain@master with: # We use nightly here so that we can use miri I guess? toolchain: nightly components: miri - name: Run full test suite run: cargo miri test --verbose rustfmt: runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 - name: Install Rust uses: dtolnay/rust-toolchain@master with: toolchain: stable components: rustfmt - name: Check formatting run: cargo fmt -- --check byteorder-1.5.0/.gitignore000064400000000000000000000000501046102023000136110ustar 00000000000000.*.swp doc tags build target Cargo.lock byteorder-1.5.0/CHANGELOG.md000064400000000000000000000113551046102023000134440ustar 00000000000000**WARNING:** This CHANGELOG is no longer updated. The activity for this project is sparse enough that you should refer to the commit log instead. 1.3.4 ===== This patch release squashes deprecation warnings for the `try!` macro, in accordance with byteorder's minimum supported Rust version (currently at Rust 1.12.0). 1.3.3 ===== This patch release adds `ByteOrder::write_i8_into()` as a simple, safe interface for ordinarily unsafe or tedious code. 1.3.2 ===== This patch release adds `ReadBytesExt::read_i8_into()` as a simple, safe interface for ordinarily unsafe or tedious code. 1.3.1 ===== This minor release performs mostly small internal changes. Going forward, these are not going to be incorporated into the changelog. 1.3.0 ===== This new minor release now enables `i128` support automatically on Rust compilers that support 128-bit integers. The `i128` feature is now a no-op, but continues to exist for backward compatibility purposes. The crate continues to maintain compatibility with Rust 1.12.0. This release also deprecates the `ByteOrder` trait methods `read_f32_into_unchecked` and `read_f64_into_unchecked` in favor of `read_f32_into` and `read_f64_into`. This was an oversight from the 1.2 release where the corresponding methods on `ReadBytesExt` were deprecated. `quickcheck` and `rand` were bumped to `0.8` and `0.6`, respectively. A few small documentation related bugs have been fixed. 1.2.7 ===== This patch release excludes some CI files from the crate release and updates the license field to use `OR` instead of `/`. 1.2.6 ===== This patch release fixes some test compilation errors introduced by an over-eager release of 1.2.5. 1.2.5 ===== This patch release fixes some typos in the docs, adds doc tests to methods on `WriteByteExt` and bumps the quickcheck dependency to `0.7`. 1.2.4 ===== This patch release adds support for 48-bit integers by adding the following methods to the `ByteOrder` trait: `read_u48`, `read_i48`, `write_u48` and `write_i48`. Corresponding methods have been added to the `ReadBytesExt` and `WriteBytesExt` traits as well. 1.2.3 ===== This patch release removes the use of `feature(i128_type)` from byteorder, since it has been stabilized. We leave byteorder's `i128` feature in place in order to continue supporting compilation on older versions of Rust. 1.2.2 ===== This patch release only consists of internal improvements and refactorings. Notably, this removes all uses of `transmute` and instead uses pointer casts. 1.2.1 ===== This patch release removes more unnecessary uses of `unsafe` that were overlooked in the prior `1.2.0` release. In particular, the `ReadBytesExt::read_{f32,f64}_into_checked` methods have been deprecated and replaced by more appropriately named `read_{f32,f64}_into` methods. 1.2.0 ===== The most prominent change in this release of `byteorder` is the removal of unnecessary signaling NaN masking, and in turn, the `unsafe` annotations associated with methods that didn't do masking. See [#103](https://github.com/BurntSushi/byteorder/issues/103) for more details. * [BUG #102](https://github.com/BurntSushi/byteorder/issues/102): Fix big endian tests. * [BUG #103](https://github.com/BurntSushi/byteorder/issues/103): Remove sNaN masking. 1.1.0 ===== This release of `byteorder` features a number of fixes and improvements, mostly as a result of the [Litz Blitz evaluation](https://public.etherpad-mozilla.org/p/rust-crate-eval-byteorder). Feature enhancements: * [FEATURE #63](https://github.com/BurntSushi/byteorder/issues/63): Add methods for reading/writing slices of numbers for a specific endianness. * [FEATURE #65](https://github.com/BurntSushi/byteorder/issues/65): Add support for `u128`/`i128` types. (Behind the nightly only `i128` feature.) * [FEATURE #72](https://github.com/BurntSushi/byteorder/issues/72): Add "panics" and "errors" sections for each relevant public API item. * [FEATURE #74](https://github.com/BurntSushi/byteorder/issues/74): Add CI badges to Cargo.toml. * [FEATURE #75](https://github.com/BurntSushi/byteorder/issues/75): Add more examples to public API items. * Add 24-bit read/write methods. * Add `BE` and `LE` type aliases for `BigEndian` and `LittleEndian`, respectively. Bug fixes: * [BUG #68](https://github.com/BurntSushi/byteorder/issues/68): Panic in {BigEndian,LittleEndian}::default. * [BUG #69](https://github.com/BurntSushi/byteorder/issues/69): Seal the `ByteOrder` trait to prevent out-of-crate implementations. * [BUG #71](https://github.com/BurntSushi/byteorder/issues/71): Guarantee that the results of `read_f32`/`read_f64` are always defined. * [BUG #73](https://github.com/BurntSushi/byteorder/issues/73): Add crates.io categories. * [BUG #77](https://github.com/BurntSushi/byteorder/issues/77): Add `html_root` doc attribute. byteorder-1.5.0/COPYING000064400000000000000000000001761046102023000126650ustar 00000000000000This project is dual-licensed under the Unlicense and MIT licenses. You may use this code under the terms of either license. byteorder-1.5.0/Cargo.toml0000644000000024000000000000100110300ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2021" rust-version = "1.60" name = "byteorder" version = "1.5.0" authors = ["Andrew Gallant "] description = "Library for reading/writing numbers in big-endian and little-endian." homepage = "https://github.com/BurntSushi/byteorder" documentation = "https://docs.rs/byteorder" readme = "README.md" keywords = [ "byte", "endian", "big-endian", "little-endian", "binary", ] categories = [ "encoding", "parsing", "no-std", ] license = "Unlicense OR MIT" repository = "https://github.com/BurntSushi/byteorder" [profile.bench] opt-level = 3 [lib] name = "byteorder" bench = false [dev-dependencies.quickcheck] version = "0.9.2" default-features = false [dev-dependencies.rand] version = "0.7" [features] default = ["std"] i128 = [] std = [] byteorder-1.5.0/Cargo.toml.orig000064400000000000000000000017251046102023000145220ustar 00000000000000[package] name = "byteorder" version = "1.5.0" #:version authors = ["Andrew Gallant "] description = "Library for reading/writing numbers in big-endian and little-endian." documentation = "https://docs.rs/byteorder" homepage = "https://github.com/BurntSushi/byteorder" repository = "https://github.com/BurntSushi/byteorder" readme = "README.md" categories = ["encoding", "parsing", "no-std"] keywords = ["byte", "endian", "big-endian", "little-endian", "binary"] license = "Unlicense OR MIT" edition = "2021" rust-version = "1.60" [lib] name = "byteorder" bench = false [dev-dependencies] quickcheck = { version = "0.9.2", default-features = false } rand = "0.7" [features] default = ["std"] std = [] # This feature is no longer used and is DEPRECATED. This crate now # automatically enables i128 support for Rust compilers that support it. The # feature will be removed if and when a new major version is released. i128 = [] [profile.bench] opt-level = 3 byteorder-1.5.0/LICENSE-MIT000064400000000000000000000020711046102023000132620ustar 00000000000000The MIT License (MIT) Copyright (c) 2015 Andrew Gallant Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. byteorder-1.5.0/README.md000064400000000000000000000041431046102023000131070ustar 00000000000000byteorder ========= This crate provides convenience methods for encoding and decoding numbers in either big-endian or little-endian order. [![Build status](https://github.com/BurntSushi/byteorder/workflows/ci/badge.svg)](https://github.com/BurntSushi/byteorder/actions) [![crates.io](https://img.shields.io/crates/v/byteorder.svg)](https://crates.io/crates/byteorder) Dual-licensed under MIT or the [UNLICENSE](https://unlicense.org/). ### Documentation https://docs.rs/byteorder ### Installation This crate works with Cargo and is on [crates.io](https://crates.io/crates/byteorder). Add it to your `Cargo.toml` like so: ```toml [dependencies] byteorder = "1" ``` If you want to augment existing `Read` and `Write` traits, then import the extension methods like so: ```rust use byteorder::{ReadBytesExt, WriteBytesExt, BigEndian, LittleEndian}; ``` For example: ```rust use std::io::Cursor; use byteorder::{BigEndian, ReadBytesExt}; let mut rdr = Cursor::new(vec![2, 5, 3, 0]); // Note that we use type parameters to indicate which kind of byte order // we want! assert_eq!(517, rdr.read_u16::().unwrap()); assert_eq!(768, rdr.read_u16::().unwrap()); ``` ### `no_std` crates This crate has a feature, `std`, that is enabled by default. To use this crate in a `no_std` context, add the following to your `Cargo.toml`: ```toml [dependencies] byteorder = { version = "1", default-features = false } ``` ### Minimum Rust version policy This crate's minimum supported `rustc` version is `1.60.0`. The current policy is that the minimum Rust version required to use this crate can be increased in minor version updates. For example, if `crate 1.0` requires Rust 1.20.0, then `crate 1.0.z` for all values of `z` will also require Rust 1.20.0 or newer. However, `crate 1.y` for `y > 0` may require a newer minimum version of Rust. In general, this crate will be conservative with respect to the minimum supported version of Rust. ### 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. byteorder-1.5.0/UNLICENSE000064400000000000000000000022731046102023000131020ustar 00000000000000This is free and unencumbered software released into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. For more information, please refer to byteorder-1.5.0/benches/bench.rs000064400000000000000000000236061046102023000146710ustar 00000000000000#![feature(test)] extern crate test; macro_rules! bench_num { ($name:ident, $read:ident, $bytes:expr, $data:expr) => { mod $name { use byteorder::{ BigEndian, ByteOrder, LittleEndian, NativeEndian, }; use test::black_box as bb; use test::Bencher; const NITER: usize = 100_000; #[bench] fn read_big_endian(b: &mut Bencher) { let buf = $data; b.iter(|| { for _ in 0..NITER { bb(BigEndian::$read(&buf, $bytes)); } }); } #[bench] fn read_little_endian(b: &mut Bencher) { let buf = $data; b.iter(|| { for _ in 0..NITER { bb(LittleEndian::$read(&buf, $bytes)); } }); } #[bench] fn read_native_endian(b: &mut Bencher) { let buf = $data; b.iter(|| { for _ in 0..NITER { bb(NativeEndian::$read(&buf, $bytes)); } }); } } }; ($ty:ident, $max:ident, $read:ident, $write:ident, $size:expr, $data:expr) => { mod $ty { use byteorder::{ BigEndian, ByteOrder, LittleEndian, NativeEndian, }; use std::$ty; use test::black_box as bb; use test::Bencher; const NITER: usize = 100_000; #[bench] fn read_big_endian(b: &mut Bencher) { let buf = $data; b.iter(|| { for _ in 0..NITER { bb(BigEndian::$read(&buf)); } }); } #[bench] fn read_little_endian(b: &mut Bencher) { let buf = $data; b.iter(|| { for _ in 0..NITER { bb(LittleEndian::$read(&buf)); } }); } #[bench] fn read_native_endian(b: &mut Bencher) { let buf = $data; b.iter(|| { for _ in 0..NITER { bb(NativeEndian::$read(&buf)); } }); } #[bench] fn write_big_endian(b: &mut Bencher) { let mut buf = $data; let n = $ty::$max; b.iter(|| { for _ in 0..NITER { bb(BigEndian::$write(&mut buf, n)); } }); } #[bench] fn write_little_endian(b: &mut Bencher) { let mut buf = $data; let n = $ty::$max; b.iter(|| { for _ in 0..NITER { bb(LittleEndian::$write(&mut buf, n)); } }); } #[bench] fn write_native_endian(b: &mut Bencher) { let mut buf = $data; let n = $ty::$max; b.iter(|| { for _ in 0..NITER { bb(NativeEndian::$write(&mut buf, n)); } }); } } }; } bench_num!(u16, MAX, read_u16, write_u16, 2, [1, 2]); bench_num!(i16, MAX, read_i16, write_i16, 2, [1, 2]); bench_num!(u32, MAX, read_u32, write_u32, 4, [1, 2, 3, 4]); bench_num!(i32, MAX, read_i32, write_i32, 4, [1, 2, 3, 4]); bench_num!(u64, MAX, read_u64, write_u64, 8, [1, 2, 3, 4, 5, 6, 7, 8]); bench_num!(i64, MAX, read_i64, write_i64, 8, [1, 2, 3, 4, 5, 6, 7, 8]); bench_num!(f32, MAX, read_f32, write_f32, 4, [1, 2, 3, 4]); bench_num!(f64, MAX, read_f64, write_f64, 8, [1, 2, 3, 4, 5, 6, 7, 8]); bench_num!(uint_1, read_uint, 1, [1]); bench_num!(uint_2, read_uint, 2, [1, 2]); bench_num!(uint_3, read_uint, 3, [1, 2, 3]); bench_num!(uint_4, read_uint, 4, [1, 2, 3, 4]); bench_num!(uint_5, read_uint, 5, [1, 2, 3, 4, 5]); bench_num!(uint_6, read_uint, 6, [1, 2, 3, 4, 5, 6]); bench_num!(uint_7, read_uint, 7, [1, 2, 3, 4, 5, 6, 7]); bench_num!(uint_8, read_uint, 8, [1, 2, 3, 4, 5, 6, 7, 8]); bench_num!(int_1, read_int, 1, [1]); bench_num!(int_2, read_int, 2, [1, 2]); bench_num!(int_3, read_int, 3, [1, 2, 3]); bench_num!(int_4, read_int, 4, [1, 2, 3, 4]); bench_num!(int_5, read_int, 5, [1, 2, 3, 4, 5]); bench_num!(int_6, read_int, 6, [1, 2, 3, 4, 5, 6]); bench_num!(int_7, read_int, 7, [1, 2, 3, 4, 5, 6, 7]); bench_num!(int_8, read_int, 8, [1, 2, 3, 4, 5, 6, 7, 8]); bench_num!( u128, MAX, read_u128, write_u128, 16, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] ); bench_num!( i128, MAX, read_i128, write_i128, 16, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] ); bench_num!(uint128_1, read_uint128, 1, [1]); bench_num!(uint128_2, read_uint128, 2, [1, 2]); bench_num!(uint128_3, read_uint128, 3, [1, 2, 3]); bench_num!(uint128_4, read_uint128, 4, [1, 2, 3, 4]); bench_num!(uint128_5, read_uint128, 5, [1, 2, 3, 4, 5]); bench_num!(uint128_6, read_uint128, 6, [1, 2, 3, 4, 5, 6]); bench_num!(uint128_7, read_uint128, 7, [1, 2, 3, 4, 5, 6, 7]); bench_num!(uint128_8, read_uint128, 8, [1, 2, 3, 4, 5, 6, 7, 8]); bench_num!(uint128_9, read_uint128, 9, [1, 2, 3, 4, 5, 6, 7, 8, 9]); bench_num!(uint128_10, read_uint128, 10, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); bench_num!(uint128_11, read_uint128, 11, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]); bench_num!( uint128_12, read_uint128, 12, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] ); bench_num!( uint128_13, read_uint128, 13, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] ); bench_num!( uint128_14, read_uint128, 14, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] ); bench_num!( uint128_15, read_uint128, 15, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] ); bench_num!( uint128_16, read_uint128, 16, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] ); bench_num!(int128_1, read_int128, 1, [1]); bench_num!(int128_2, read_int128, 2, [1, 2]); bench_num!(int128_3, read_int128, 3, [1, 2, 3]); bench_num!(int128_4, read_int128, 4, [1, 2, 3, 4]); bench_num!(int128_5, read_int128, 5, [1, 2, 3, 4, 5]); bench_num!(int128_6, read_int128, 6, [1, 2, 3, 4, 5, 6]); bench_num!(int128_7, read_int128, 7, [1, 2, 3, 4, 5, 6, 7]); bench_num!(int128_8, read_int128, 8, [1, 2, 3, 4, 5, 6, 7, 8]); bench_num!(int128_9, read_int128, 9, [1, 2, 3, 4, 5, 6, 7, 8, 9]); bench_num!(int128_10, read_int128, 10, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); bench_num!(int128_11, read_int128, 11, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]); bench_num!( int128_12, read_int128, 12, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] ); bench_num!( int128_13, read_int128, 13, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] ); bench_num!( int128_14, read_int128, 14, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] ); bench_num!( int128_15, read_int128, 15, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] ); bench_num!( int128_16, read_int128, 16, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] ); macro_rules! bench_slice { ($name:ident, $numty:ty, $read:ident, $write:ident) => { mod $name { use std::mem::size_of; use byteorder::{BigEndian, ByteOrder, LittleEndian}; use rand::distributions; use rand::{self, Rng}; use test::Bencher; #[bench] fn read_big_endian(b: &mut Bencher) { let mut numbers: Vec<$numty> = rand::thread_rng() .sample_iter(&distributions::Standard) .take(100000) .collect(); let mut bytes = vec![0; numbers.len() * size_of::<$numty>()]; BigEndian::$write(&numbers, &mut bytes); b.bytes = bytes.len() as u64; b.iter(|| { BigEndian::$read(&bytes, &mut numbers); }); } #[bench] fn read_little_endian(b: &mut Bencher) { let mut numbers: Vec<$numty> = rand::thread_rng() .sample_iter(&distributions::Standard) .take(100000) .collect(); let mut bytes = vec![0; numbers.len() * size_of::<$numty>()]; LittleEndian::$write(&numbers, &mut bytes); b.bytes = bytes.len() as u64; b.iter(|| { LittleEndian::$read(&bytes, &mut numbers); }); } #[bench] fn write_big_endian(b: &mut Bencher) { let numbers: Vec<$numty> = rand::thread_rng() .sample_iter(&distributions::Standard) .take(100000) .collect(); let mut bytes = vec![0; numbers.len() * size_of::<$numty>()]; b.bytes = bytes.len() as u64; b.iter(|| { BigEndian::$write(&numbers, &mut bytes); }); } #[bench] fn write_little_endian(b: &mut Bencher) { let numbers: Vec<$numty> = rand::thread_rng() .sample_iter(&distributions::Standard) .take(100000) .collect(); let mut bytes = vec![0; numbers.len() * size_of::<$numty>()]; b.bytes = bytes.len() as u64; b.iter(|| { LittleEndian::$write(&numbers, &mut bytes); }); } } }; } bench_slice!(slice_u16, u16, read_u16_into, write_u16_into); bench_slice!(slice_u64, u64, read_u64_into, write_u64_into); bench_slice!(slice_i64, i64, read_i64_into, write_i64_into); byteorder-1.5.0/rustfmt.toml000064400000000000000000000000541046102023000142260ustar 00000000000000max_width = 79 use_small_heuristics = "max" byteorder-1.5.0/src/io.rs000064400000000000000000001427711046102023000134060ustar 00000000000000use std::{ io::{self, Result}, slice, }; use crate::ByteOrder; /// Extends [`Read`] with methods for reading numbers. (For `std::io`.) /// /// Most of the methods defined here have an unconstrained type parameter that /// must be explicitly instantiated. Typically, it is instantiated with either /// the [`BigEndian`] or [`LittleEndian`] types defined in this crate. /// /// # Examples /// /// Read unsigned 16 bit big-endian integers from a [`Read`]: /// /// ```rust /// use std::io::Cursor; /// use byteorder::{BigEndian, ReadBytesExt}; /// /// let mut rdr = Cursor::new(vec![2, 5, 3, 0]); /// assert_eq!(517, rdr.read_u16::().unwrap()); /// assert_eq!(768, rdr.read_u16::().unwrap()); /// ``` /// /// [`BigEndian`]: enum.BigEndian.html /// [`LittleEndian`]: enum.LittleEndian.html /// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html pub trait ReadBytesExt: io::Read { /// Reads an unsigned 8 bit integer from the underlying reader. /// /// Note that since this reads a single byte, no byte order conversions /// are used. It is included for completeness. /// /// # Errors /// /// This method returns the same errors as [`Read::read_exact`]. /// /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact /// /// # Examples /// /// Read unsigned 8 bit integers from a `Read`: /// /// ```rust /// use std::io::Cursor; /// use byteorder::ReadBytesExt; /// /// let mut rdr = Cursor::new(vec![2, 5]); /// assert_eq!(2, rdr.read_u8().unwrap()); /// assert_eq!(5, rdr.read_u8().unwrap()); /// ``` #[inline] fn read_u8(&mut self) -> Result { let mut buf = [0; 1]; self.read_exact(&mut buf)?; Ok(buf[0]) } /// Reads a signed 8 bit integer from the underlying reader. /// /// Note that since this reads a single byte, no byte order conversions /// are used. It is included for completeness. /// /// # Errors /// /// This method returns the same errors as [`Read::read_exact`]. /// /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact /// /// # Examples /// /// Read signed 8 bit integers from a `Read`: /// /// ```rust /// use std::io::Cursor; /// use byteorder::ReadBytesExt; /// /// let mut rdr = Cursor::new(vec![0x02, 0xfb]); /// assert_eq!(2, rdr.read_i8().unwrap()); /// assert_eq!(-5, rdr.read_i8().unwrap()); /// ``` #[inline] fn read_i8(&mut self) -> Result { let mut buf = [0; 1]; self.read_exact(&mut buf)?; Ok(buf[0] as i8) } /// Reads an unsigned 16 bit integer from the underlying reader. /// /// # Errors /// /// This method returns the same errors as [`Read::read_exact`]. /// /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact /// /// # Examples /// /// Read unsigned 16 bit big-endian integers from a `Read`: /// /// ```rust /// use std::io::Cursor; /// use byteorder::{BigEndian, ReadBytesExt}; /// /// let mut rdr = Cursor::new(vec![2, 5, 3, 0]); /// assert_eq!(517, rdr.read_u16::().unwrap()); /// assert_eq!(768, rdr.read_u16::().unwrap()); /// ``` #[inline] fn read_u16(&mut self) -> Result { let mut buf = [0; 2]; self.read_exact(&mut buf)?; Ok(T::read_u16(&buf)) } /// Reads a signed 16 bit integer from the underlying reader. /// /// # Errors /// /// This method returns the same errors as [`Read::read_exact`]. /// /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact /// /// # Examples /// /// Read signed 16 bit big-endian integers from a `Read`: /// /// ```rust /// use std::io::Cursor; /// use byteorder::{BigEndian, ReadBytesExt}; /// /// let mut rdr = Cursor::new(vec![0x00, 0xc1, 0xff, 0x7c]); /// assert_eq!(193, rdr.read_i16::().unwrap()); /// assert_eq!(-132, rdr.read_i16::().unwrap()); /// ``` #[inline] fn read_i16(&mut self) -> Result { let mut buf = [0; 2]; self.read_exact(&mut buf)?; Ok(T::read_i16(&buf)) } /// Reads an unsigned 24 bit integer from the underlying reader. /// /// # Errors /// /// This method returns the same errors as [`Read::read_exact`]. /// /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact /// /// # Examples /// /// Read unsigned 24 bit big-endian integers from a `Read`: /// /// ```rust /// use std::io::Cursor; /// use byteorder::{BigEndian, ReadBytesExt}; /// /// let mut rdr = Cursor::new(vec![0x00, 0x01, 0x0b]); /// assert_eq!(267, rdr.read_u24::().unwrap()); /// ``` #[inline] fn read_u24(&mut self) -> Result { let mut buf = [0; 3]; self.read_exact(&mut buf)?; Ok(T::read_u24(&buf)) } /// Reads a signed 24 bit integer from the underlying reader. /// /// # Errors /// /// This method returns the same errors as [`Read::read_exact`]. /// /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact /// /// # Examples /// /// Read signed 24 bit big-endian integers from a `Read`: /// /// ```rust /// use std::io::Cursor; /// use byteorder::{BigEndian, ReadBytesExt}; /// /// let mut rdr = Cursor::new(vec![0xff, 0x7a, 0x33]); /// assert_eq!(-34253, rdr.read_i24::().unwrap()); /// ``` #[inline] fn read_i24(&mut self) -> Result { let mut buf = [0; 3]; self.read_exact(&mut buf)?; Ok(T::read_i24(&buf)) } /// Reads an unsigned 32 bit integer from the underlying reader. /// /// # Errors /// /// This method returns the same errors as [`Read::read_exact`]. /// /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact /// /// # Examples /// /// Read unsigned 32 bit big-endian integers from a `Read`: /// /// ```rust /// use std::io::Cursor; /// use byteorder::{BigEndian, ReadBytesExt}; /// /// let mut rdr = Cursor::new(vec![0x00, 0x00, 0x01, 0x0b]); /// assert_eq!(267, rdr.read_u32::().unwrap()); /// ``` #[inline] fn read_u32(&mut self) -> Result { let mut buf = [0; 4]; self.read_exact(&mut buf)?; Ok(T::read_u32(&buf)) } /// Reads a signed 32 bit integer from the underlying reader. /// /// # Errors /// /// This method returns the same errors as [`Read::read_exact`]. /// /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact /// /// # Examples /// /// Read signed 32 bit big-endian integers from a `Read`: /// /// ```rust /// use std::io::Cursor; /// use byteorder::{BigEndian, ReadBytesExt}; /// /// let mut rdr = Cursor::new(vec![0xff, 0xff, 0x7a, 0x33]); /// assert_eq!(-34253, rdr.read_i32::().unwrap()); /// ``` #[inline] fn read_i32(&mut self) -> Result { let mut buf = [0; 4]; self.read_exact(&mut buf)?; Ok(T::read_i32(&buf)) } /// Reads an unsigned 48 bit integer from the underlying reader. /// /// # Errors /// /// This method returns the same errors as [`Read::read_exact`]. /// /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact /// /// # Examples /// /// Read unsigned 48 bit big-endian integers from a `Read`: /// /// ```rust /// use std::io::Cursor; /// use byteorder::{BigEndian, ReadBytesExt}; /// /// let mut rdr = Cursor::new(vec![0xb6, 0x71, 0x6b, 0xdc, 0x2b, 0x31]); /// assert_eq!(200598257150769, rdr.read_u48::().unwrap()); /// ``` #[inline] fn read_u48(&mut self) -> Result { let mut buf = [0; 6]; self.read_exact(&mut buf)?; Ok(T::read_u48(&buf)) } /// Reads a signed 48 bit integer from the underlying reader. /// /// # Errors /// /// This method returns the same errors as [`Read::read_exact`]. /// /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact /// /// # Examples /// /// Read signed 48 bit big-endian integers from a `Read`: /// /// ```rust /// use std::io::Cursor; /// use byteorder::{BigEndian, ReadBytesExt}; /// /// let mut rdr = Cursor::new(vec![0x9d, 0x71, 0xab, 0xe7, 0x97, 0x8f]); /// assert_eq!(-108363435763825, rdr.read_i48::().unwrap()); /// ``` #[inline] fn read_i48(&mut self) -> Result { let mut buf = [0; 6]; self.read_exact(&mut buf)?; Ok(T::read_i48(&buf)) } /// Reads an unsigned 64 bit integer from the underlying reader. /// /// # Errors /// /// This method returns the same errors as [`Read::read_exact`]. /// /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact /// /// # Examples /// /// Read an unsigned 64 bit big-endian integer from a `Read`: /// /// ```rust /// use std::io::Cursor; /// use byteorder::{BigEndian, ReadBytesExt}; /// /// let mut rdr = Cursor::new(vec![0x00, 0x03, 0x43, 0x95, 0x4d, 0x60, 0x86, 0x83]); /// assert_eq!(918733457491587, rdr.read_u64::().unwrap()); /// ``` #[inline] fn read_u64(&mut self) -> Result { let mut buf = [0; 8]; self.read_exact(&mut buf)?; Ok(T::read_u64(&buf)) } /// Reads a signed 64 bit integer from the underlying reader. /// /// # Errors /// /// This method returns the same errors as [`Read::read_exact`]. /// /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact /// /// # Examples /// /// Read a signed 64 bit big-endian integer from a `Read`: /// /// ```rust /// use std::io::Cursor; /// use byteorder::{BigEndian, ReadBytesExt}; /// /// let mut rdr = Cursor::new(vec![0x80, 0, 0, 0, 0, 0, 0, 0]); /// assert_eq!(i64::min_value(), rdr.read_i64::().unwrap()); /// ``` #[inline] fn read_i64(&mut self) -> Result { let mut buf = [0; 8]; self.read_exact(&mut buf)?; Ok(T::read_i64(&buf)) } /// Reads an unsigned 128 bit integer from the underlying reader. /// /// # Errors /// /// This method returns the same errors as [`Read::read_exact`]. /// /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact /// /// # Examples /// /// Read an unsigned 128 bit big-endian integer from a `Read`: /// /// ```rust /// use std::io::Cursor; /// use byteorder::{BigEndian, ReadBytesExt}; /// /// let mut rdr = Cursor::new(vec![ /// 0x00, 0x03, 0x43, 0x95, 0x4d, 0x60, 0x86, 0x83, /// 0x00, 0x03, 0x43, 0x95, 0x4d, 0x60, 0x86, 0x83 /// ]); /// assert_eq!(16947640962301618749969007319746179, rdr.read_u128::().unwrap()); /// ``` #[inline] fn read_u128(&mut self) -> Result { let mut buf = [0; 16]; self.read_exact(&mut buf)?; Ok(T::read_u128(&buf)) } /// Reads a signed 128 bit integer from the underlying reader. /// /// # Errors /// /// This method returns the same errors as [`Read::read_exact`]. /// /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact /// /// # Examples /// /// Read a signed 128 bit big-endian integer from a `Read`: /// /// ```rust /// use std::io::Cursor; /// use byteorder::{BigEndian, ReadBytesExt}; /// /// let mut rdr = Cursor::new(vec![0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); /// assert_eq!(i128::min_value(), rdr.read_i128::().unwrap()); /// ``` #[inline] fn read_i128(&mut self) -> Result { let mut buf = [0; 16]; self.read_exact(&mut buf)?; Ok(T::read_i128(&buf)) } /// Reads an unsigned n-bytes integer from the underlying reader. /// /// # Errors /// /// This method returns the same errors as [`Read::read_exact`]. /// /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact /// /// # Examples /// /// Read an unsigned n-byte big-endian integer from a `Read`: /// /// ```rust /// use std::io::Cursor; /// use byteorder::{BigEndian, ReadBytesExt}; /// /// let mut rdr = Cursor::new(vec![0x80, 0x74, 0xfa]); /// assert_eq!(8418554, rdr.read_uint::(3).unwrap()); #[inline] fn read_uint(&mut self, nbytes: usize) -> Result { let mut buf = [0; 8]; self.read_exact(&mut buf[..nbytes])?; Ok(T::read_uint(&buf[..nbytes], nbytes)) } /// Reads a signed n-bytes integer from the underlying reader. /// /// # Errors /// /// This method returns the same errors as [`Read::read_exact`]. /// /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact /// /// # Examples /// /// Read an unsigned n-byte big-endian integer from a `Read`: /// /// ```rust /// use std::io::Cursor; /// use byteorder::{BigEndian, ReadBytesExt}; /// /// let mut rdr = Cursor::new(vec![0xc1, 0xff, 0x7c]); /// assert_eq!(-4063364, rdr.read_int::(3).unwrap()); #[inline] fn read_int(&mut self, nbytes: usize) -> Result { let mut buf = [0; 8]; self.read_exact(&mut buf[..nbytes])?; Ok(T::read_int(&buf[..nbytes], nbytes)) } /// Reads an unsigned n-bytes integer from the underlying reader. #[inline] fn read_uint128(&mut self, nbytes: usize) -> Result { let mut buf = [0; 16]; self.read_exact(&mut buf[..nbytes])?; Ok(T::read_uint128(&buf[..nbytes], nbytes)) } /// Reads a signed n-bytes integer from the underlying reader. #[inline] fn read_int128(&mut self, nbytes: usize) -> Result { let mut buf = [0; 16]; self.read_exact(&mut buf[..nbytes])?; Ok(T::read_int128(&buf[..nbytes], nbytes)) } /// Reads a IEEE754 single-precision (4 bytes) floating point number from /// the underlying reader. /// /// # Errors /// /// This method returns the same errors as [`Read::read_exact`]. /// /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact /// /// # Examples /// /// Read a big-endian single-precision floating point number from a `Read`: /// /// ```rust /// use std::f32; /// use std::io::Cursor; /// /// use byteorder::{BigEndian, ReadBytesExt}; /// /// let mut rdr = Cursor::new(vec![ /// 0x40, 0x49, 0x0f, 0xdb, /// ]); /// assert_eq!(f32::consts::PI, rdr.read_f32::().unwrap()); /// ``` #[inline] fn read_f32(&mut self) -> Result { let mut buf = [0; 4]; self.read_exact(&mut buf)?; Ok(T::read_f32(&buf)) } /// Reads a IEEE754 double-precision (8 bytes) floating point number from /// the underlying reader. /// /// # Errors /// /// This method returns the same errors as [`Read::read_exact`]. /// /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact /// /// # Examples /// /// Read a big-endian double-precision floating point number from a `Read`: /// /// ```rust /// use std::f64; /// use std::io::Cursor; /// /// use byteorder::{BigEndian, ReadBytesExt}; /// /// let mut rdr = Cursor::new(vec![ /// 0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18, /// ]); /// assert_eq!(f64::consts::PI, rdr.read_f64::().unwrap()); /// ``` #[inline] fn read_f64(&mut self) -> Result { let mut buf = [0; 8]; self.read_exact(&mut buf)?; Ok(T::read_f64(&buf)) } /// Reads a sequence of unsigned 16 bit integers from the underlying /// reader. /// /// The given buffer is either filled completely or an error is returned. /// If an error is returned, the contents of `dst` are unspecified. /// /// # Errors /// /// This method returns the same errors as [`Read::read_exact`]. /// /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact /// /// # Examples /// /// Read a sequence of unsigned 16 bit big-endian integers from a `Read`: /// /// ```rust /// use std::io::Cursor; /// use byteorder::{BigEndian, ReadBytesExt}; /// /// let mut rdr = Cursor::new(vec![2, 5, 3, 0]); /// let mut dst = [0; 2]; /// rdr.read_u16_into::(&mut dst).unwrap(); /// assert_eq!([517, 768], dst); /// ``` #[inline] fn read_u16_into(&mut self, dst: &mut [u16]) -> Result<()> { { let buf = unsafe { slice_to_u8_mut(dst) }; self.read_exact(buf)?; } T::from_slice_u16(dst); Ok(()) } /// Reads a sequence of unsigned 32 bit integers from the underlying /// reader. /// /// The given buffer is either filled completely or an error is returned. /// If an error is returned, the contents of `dst` are unspecified. /// /// # Errors /// /// This method returns the same errors as [`Read::read_exact`]. /// /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact /// /// # Examples /// /// Read a sequence of unsigned 32 bit big-endian integers from a `Read`: /// /// ```rust /// use std::io::Cursor; /// use byteorder::{BigEndian, ReadBytesExt}; /// /// let mut rdr = Cursor::new(vec![0, 0, 2, 5, 0, 0, 3, 0]); /// let mut dst = [0; 2]; /// rdr.read_u32_into::(&mut dst).unwrap(); /// assert_eq!([517, 768], dst); /// ``` #[inline] fn read_u32_into(&mut self, dst: &mut [u32]) -> Result<()> { { let buf = unsafe { slice_to_u8_mut(dst) }; self.read_exact(buf)?; } T::from_slice_u32(dst); Ok(()) } /// Reads a sequence of unsigned 64 bit integers from the underlying /// reader. /// /// The given buffer is either filled completely or an error is returned. /// If an error is returned, the contents of `dst` are unspecified. /// /// # Errors /// /// This method returns the same errors as [`Read::read_exact`]. /// /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact /// /// # Examples /// /// Read a sequence of unsigned 64 bit big-endian integers from a `Read`: /// /// ```rust /// use std::io::Cursor; /// use byteorder::{BigEndian, ReadBytesExt}; /// /// let mut rdr = Cursor::new(vec![ /// 0, 0, 0, 0, 0, 0, 2, 5, /// 0, 0, 0, 0, 0, 0, 3, 0, /// ]); /// let mut dst = [0; 2]; /// rdr.read_u64_into::(&mut dst).unwrap(); /// assert_eq!([517, 768], dst); /// ``` #[inline] fn read_u64_into(&mut self, dst: &mut [u64]) -> Result<()> { { let buf = unsafe { slice_to_u8_mut(dst) }; self.read_exact(buf)?; } T::from_slice_u64(dst); Ok(()) } /// Reads a sequence of unsigned 128 bit integers from the underlying /// reader. /// /// The given buffer is either filled completely or an error is returned. /// If an error is returned, the contents of `dst` are unspecified. /// /// # Errors /// /// This method returns the same errors as [`Read::read_exact`]. /// /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact /// /// # Examples /// /// Read a sequence of unsigned 128 bit big-endian integers from a `Read`: /// /// ```rust /// use std::io::Cursor; /// use byteorder::{BigEndian, ReadBytesExt}; /// /// let mut rdr = Cursor::new(vec![ /// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 5, /// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, /// ]); /// let mut dst = [0; 2]; /// rdr.read_u128_into::(&mut dst).unwrap(); /// assert_eq!([517, 768], dst); /// ``` #[inline] fn read_u128_into( &mut self, dst: &mut [u128], ) -> Result<()> { { let buf = unsafe { slice_to_u8_mut(dst) }; self.read_exact(buf)?; } T::from_slice_u128(dst); Ok(()) } /// Reads a sequence of signed 8 bit integers from the underlying reader. /// /// The given buffer is either filled completely or an error is returned. /// If an error is returned, the contents of `dst` are unspecified. /// /// 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 read into a `&mut [i8]` buffer. (Without this /// method, the caller would have to either use `unsafe` code or convert /// each byte to `i8` individually.) /// /// # Errors /// /// This method returns the same errors as [`Read::read_exact`]. /// /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact /// /// # Examples /// /// Read a sequence of signed 8 bit integers from a `Read`: /// /// ```rust /// use std::io::Cursor; /// use byteorder::{BigEndian, ReadBytesExt}; /// /// let mut rdr = Cursor::new(vec![2, 251, 3]); /// let mut dst = [0; 3]; /// rdr.read_i8_into(&mut dst).unwrap(); /// assert_eq!([2, -5, 3], dst); /// ``` #[inline] fn read_i8_into(&mut self, dst: &mut [i8]) -> Result<()> { let buf = unsafe { slice_to_u8_mut(dst) }; self.read_exact(buf) } /// Reads a sequence of signed 16 bit integers from the underlying /// reader. /// /// The given buffer is either filled completely or an error is returned. /// If an error is returned, the contents of `dst` are unspecified. /// /// # Errors /// /// This method returns the same errors as [`Read::read_exact`]. /// /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact /// /// # Examples /// /// Read a sequence of signed 16 bit big-endian integers from a `Read`: /// /// ```rust /// use std::io::Cursor; /// use byteorder::{BigEndian, ReadBytesExt}; /// /// let mut rdr = Cursor::new(vec![2, 5, 3, 0]); /// let mut dst = [0; 2]; /// rdr.read_i16_into::(&mut dst).unwrap(); /// assert_eq!([517, 768], dst); /// ``` #[inline] fn read_i16_into(&mut self, dst: &mut [i16]) -> Result<()> { { let buf = unsafe { slice_to_u8_mut(dst) }; self.read_exact(buf)?; } T::from_slice_i16(dst); Ok(()) } /// Reads a sequence of signed 32 bit integers from the underlying /// reader. /// /// The given buffer is either filled completely or an error is returned. /// If an error is returned, the contents of `dst` are unspecified. /// /// # Errors /// /// This method returns the same errors as [`Read::read_exact`]. /// /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact /// /// # Examples /// /// Read a sequence of signed 32 bit big-endian integers from a `Read`: /// /// ```rust /// use std::io::Cursor; /// use byteorder::{BigEndian, ReadBytesExt}; /// /// let mut rdr = Cursor::new(vec![0, 0, 2, 5, 0, 0, 3, 0]); /// let mut dst = [0; 2]; /// rdr.read_i32_into::(&mut dst).unwrap(); /// assert_eq!([517, 768], dst); /// ``` #[inline] fn read_i32_into(&mut self, dst: &mut [i32]) -> Result<()> { { let buf = unsafe { slice_to_u8_mut(dst) }; self.read_exact(buf)?; } T::from_slice_i32(dst); Ok(()) } /// Reads a sequence of signed 64 bit integers from the underlying /// reader. /// /// The given buffer is either filled completely or an error is returned. /// If an error is returned, the contents of `dst` are unspecified. /// /// # Errors /// /// This method returns the same errors as [`Read::read_exact`]. /// /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact /// /// # Examples /// /// Read a sequence of signed 64 bit big-endian integers from a `Read`: /// /// ```rust /// use std::io::Cursor; /// use byteorder::{BigEndian, ReadBytesExt}; /// /// let mut rdr = Cursor::new(vec![ /// 0, 0, 0, 0, 0, 0, 2, 5, /// 0, 0, 0, 0, 0, 0, 3, 0, /// ]); /// let mut dst = [0; 2]; /// rdr.read_i64_into::(&mut dst).unwrap(); /// assert_eq!([517, 768], dst); /// ``` #[inline] fn read_i64_into(&mut self, dst: &mut [i64]) -> Result<()> { { let buf = unsafe { slice_to_u8_mut(dst) }; self.read_exact(buf)?; } T::from_slice_i64(dst); Ok(()) } /// Reads a sequence of signed 128 bit integers from the underlying /// reader. /// /// The given buffer is either filled completely or an error is returned. /// If an error is returned, the contents of `dst` are unspecified. /// /// # Errors /// /// This method returns the same errors as [`Read::read_exact`]. /// /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact /// /// # Examples /// /// Read a sequence of signed 128 bit big-endian integers from a `Read`: /// /// ```rust /// use std::io::Cursor; /// use byteorder::{BigEndian, ReadBytesExt}; /// /// let mut rdr = Cursor::new(vec![ /// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 5, /// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, /// ]); /// let mut dst = [0; 2]; /// rdr.read_i128_into::(&mut dst).unwrap(); /// assert_eq!([517, 768], dst); /// ``` #[inline] fn read_i128_into( &mut self, dst: &mut [i128], ) -> Result<()> { { let buf = unsafe { slice_to_u8_mut(dst) }; self.read_exact(buf)?; } T::from_slice_i128(dst); Ok(()) } /// Reads a sequence of IEEE754 single-precision (4 bytes) floating /// point numbers from the underlying reader. /// /// The given buffer is either filled completely or an error is returned. /// If an error is returned, the contents of `dst` are unspecified. /// /// # Errors /// /// This method returns the same errors as [`Read::read_exact`]. /// /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact /// /// # Examples /// /// Read a sequence of big-endian single-precision floating point number /// from a `Read`: /// /// ```rust /// use std::f32; /// use std::io::Cursor; /// /// use byteorder::{BigEndian, ReadBytesExt}; /// /// let mut rdr = Cursor::new(vec![ /// 0x40, 0x49, 0x0f, 0xdb, /// 0x3f, 0x80, 0x00, 0x00, /// ]); /// let mut dst = [0.0; 2]; /// rdr.read_f32_into::(&mut dst).unwrap(); /// assert_eq!([f32::consts::PI, 1.0], dst); /// ``` #[inline] fn read_f32_into(&mut self, dst: &mut [f32]) -> Result<()> { { let buf = unsafe { slice_to_u8_mut(dst) }; self.read_exact(buf)?; } T::from_slice_f32(dst); Ok(()) } /// **DEPRECATED**. /// /// This method is deprecated. Use `read_f32_into` instead. /// /// Reads a sequence of IEEE754 single-precision (4 bytes) floating /// point numbers from the underlying reader. /// /// The given buffer is either filled completely or an error is returned. /// If an error is returned, the contents of `dst` are unspecified. /// /// # Errors /// /// This method returns the same errors as [`Read::read_exact`]. /// /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact /// /// # Examples /// /// Read a sequence of big-endian single-precision floating point number /// from a `Read`: /// /// ```rust /// use std::f32; /// use std::io::Cursor; /// /// use byteorder::{BigEndian, ReadBytesExt}; /// /// let mut rdr = Cursor::new(vec![ /// 0x40, 0x49, 0x0f, 0xdb, /// 0x3f, 0x80, 0x00, 0x00, /// ]); /// let mut dst = [0.0; 2]; /// rdr.read_f32_into_unchecked::(&mut dst).unwrap(); /// assert_eq!([f32::consts::PI, 1.0], dst); /// ``` #[inline] #[deprecated(since = "1.2.0", note = "please use `read_f32_into` instead")] fn read_f32_into_unchecked( &mut self, dst: &mut [f32], ) -> Result<()> { self.read_f32_into::(dst) } /// Reads a sequence of IEEE754 double-precision (8 bytes) floating /// point numbers from the underlying reader. /// /// The given buffer is either filled completely or an error is returned. /// If an error is returned, the contents of `dst` are unspecified. /// /// # Errors /// /// This method returns the same errors as [`Read::read_exact`]. /// /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact /// /// # Examples /// /// Read a sequence of big-endian single-precision floating point number /// from a `Read`: /// /// ```rust /// use std::f64; /// use std::io::Cursor; /// /// use byteorder::{BigEndian, ReadBytesExt}; /// /// let mut rdr = Cursor::new(vec![ /// 0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18, /// 0x3f, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /// ]); /// let mut dst = [0.0; 2]; /// rdr.read_f64_into::(&mut dst).unwrap(); /// assert_eq!([f64::consts::PI, 1.0], dst); /// ``` #[inline] fn read_f64_into(&mut self, dst: &mut [f64]) -> Result<()> { { let buf = unsafe { slice_to_u8_mut(dst) }; self.read_exact(buf)?; } T::from_slice_f64(dst); Ok(()) } /// **DEPRECATED**. /// /// This method is deprecated. Use `read_f64_into` instead. /// /// Reads a sequence of IEEE754 double-precision (8 bytes) floating /// point numbers from the underlying reader. /// /// The given buffer is either filled completely or an error is returned. /// If an error is returned, the contents of `dst` are unspecified. /// /// # Safety /// /// This method is unsafe because there are no guarantees made about the /// floating point values. In particular, this method does not check for /// signaling NaNs, which may result in undefined behavior. /// /// # Errors /// /// This method returns the same errors as [`Read::read_exact`]. /// /// [`Read::read_exact`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact /// /// # Examples /// /// Read a sequence of big-endian single-precision floating point number /// from a `Read`: /// /// ```rust /// use std::f64; /// use std::io::Cursor; /// /// use byteorder::{BigEndian, ReadBytesExt}; /// /// let mut rdr = Cursor::new(vec![ /// 0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18, /// 0x3f, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /// ]); /// let mut dst = [0.0; 2]; /// rdr.read_f64_into_unchecked::(&mut dst).unwrap(); /// assert_eq!([f64::consts::PI, 1.0], dst); /// ``` #[inline] #[deprecated(since = "1.2.0", note = "please use `read_f64_into` instead")] fn read_f64_into_unchecked( &mut self, dst: &mut [f64], ) -> Result<()> { self.read_f64_into::(dst) } } /// All types that implement `Read` get methods defined in `ReadBytesExt` /// for free. impl ReadBytesExt for R {} /// Extends [`Write`] with methods for writing numbers. (For `std::io`.) /// /// Most of the methods defined here have an unconstrained type parameter that /// must be explicitly instantiated. Typically, it is instantiated with either /// the [`BigEndian`] or [`LittleEndian`] types defined in this crate. /// /// # Examples /// /// Write unsigned 16 bit big-endian integers to a [`Write`]: /// /// ```rust /// use byteorder::{BigEndian, WriteBytesExt}; /// /// let mut wtr = vec![]; /// wtr.write_u16::(517).unwrap(); /// wtr.write_u16::(768).unwrap(); /// assert_eq!(wtr, vec![2, 5, 3, 0]); /// ``` /// /// [`BigEndian`]: enum.BigEndian.html /// [`LittleEndian`]: enum.LittleEndian.html /// [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html pub trait WriteBytesExt: io::Write { /// Writes an unsigned 8 bit integer to the underlying writer. /// /// Note that since this writes a single byte, no byte order conversions /// are used. It is included for completeness. /// /// # Errors /// /// This method returns the same errors as [`Write::write_all`]. /// /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all /// /// # Examples /// /// Write unsigned 8 bit integers to a `Write`: /// /// ```rust /// use byteorder::WriteBytesExt; /// /// let mut wtr = Vec::new(); /// wtr.write_u8(2).unwrap(); /// wtr.write_u8(5).unwrap(); /// assert_eq!(wtr, b"\x02\x05"); /// ``` #[inline] fn write_u8(&mut self, n: u8) -> Result<()> { self.write_all(&[n]) } /// Writes a signed 8 bit integer to the underlying writer. /// /// Note that since this writes a single byte, no byte order conversions /// are used. It is included for completeness. /// /// # Errors /// /// This method returns the same errors as [`Write::write_all`]. /// /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all /// /// # Examples /// /// Write signed 8 bit integers to a `Write`: /// /// ```rust /// use byteorder::WriteBytesExt; /// /// let mut wtr = Vec::new(); /// wtr.write_i8(2).unwrap(); /// wtr.write_i8(-5).unwrap(); /// assert_eq!(wtr, b"\x02\xfb"); /// ``` #[inline] fn write_i8(&mut self, n: i8) -> Result<()> { self.write_all(&[n as u8]) } /// Writes an unsigned 16 bit integer to the underlying writer. /// /// # Errors /// /// This method returns the same errors as [`Write::write_all`]. /// /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all /// /// # Examples /// /// Write unsigned 16 bit big-endian integers to a `Write`: /// /// ```rust /// use byteorder::{BigEndian, WriteBytesExt}; /// /// let mut wtr = Vec::new(); /// wtr.write_u16::(517).unwrap(); /// wtr.write_u16::(768).unwrap(); /// assert_eq!(wtr, b"\x02\x05\x03\x00"); /// ``` #[inline] fn write_u16(&mut self, n: u16) -> Result<()> { let mut buf = [0; 2]; T::write_u16(&mut buf, n); self.write_all(&buf) } /// Writes a signed 16 bit integer to the underlying writer. /// /// # Errors /// /// This method returns the same errors as [`Write::write_all`]. /// /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all /// /// # Examples /// /// Write signed 16 bit big-endian integers to a `Write`: /// /// ```rust /// use byteorder::{BigEndian, WriteBytesExt}; /// /// let mut wtr = Vec::new(); /// wtr.write_i16::(193).unwrap(); /// wtr.write_i16::(-132).unwrap(); /// assert_eq!(wtr, b"\x00\xc1\xff\x7c"); /// ``` #[inline] fn write_i16(&mut self, n: i16) -> Result<()> { let mut buf = [0; 2]; T::write_i16(&mut buf, n); self.write_all(&buf) } /// Writes an unsigned 24 bit integer to the underlying writer. /// /// # Errors /// /// This method returns the same errors as [`Write::write_all`]. /// /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all /// /// # Examples /// /// Write unsigned 24 bit big-endian integers to a `Write`: /// /// ```rust /// use byteorder::{BigEndian, WriteBytesExt}; /// /// let mut wtr = Vec::new(); /// wtr.write_u24::(267).unwrap(); /// wtr.write_u24::(120111).unwrap(); /// assert_eq!(wtr, b"\x00\x01\x0b\x01\xd5\x2f"); /// ``` #[inline] fn write_u24(&mut self, n: u32) -> Result<()> { let mut buf = [0; 3]; T::write_u24(&mut buf, n); self.write_all(&buf) } /// Writes a signed 24 bit integer to the underlying writer. /// /// # Errors /// /// This method returns the same errors as [`Write::write_all`]. /// /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all /// /// # Examples /// /// Write signed 24 bit big-endian integers to a `Write`: /// /// ```rust /// use byteorder::{BigEndian, WriteBytesExt}; /// /// let mut wtr = Vec::new(); /// wtr.write_i24::(-34253).unwrap(); /// wtr.write_i24::(120111).unwrap(); /// assert_eq!(wtr, b"\xff\x7a\x33\x01\xd5\x2f"); /// ``` #[inline] fn write_i24(&mut self, n: i32) -> Result<()> { let mut buf = [0; 3]; T::write_i24(&mut buf, n); self.write_all(&buf) } /// Writes an unsigned 32 bit integer to the underlying writer. /// /// # Errors /// /// This method returns the same errors as [`Write::write_all`]. /// /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all /// /// # Examples /// /// Write unsigned 32 bit big-endian integers to a `Write`: /// /// ```rust /// use byteorder::{BigEndian, WriteBytesExt}; /// /// let mut wtr = Vec::new(); /// wtr.write_u32::(267).unwrap(); /// wtr.write_u32::(1205419366).unwrap(); /// assert_eq!(wtr, b"\x00\x00\x01\x0b\x47\xd9\x3d\x66"); /// ``` #[inline] fn write_u32(&mut self, n: u32) -> Result<()> { let mut buf = [0; 4]; T::write_u32(&mut buf, n); self.write_all(&buf) } /// Writes a signed 32 bit integer to the underlying writer. /// /// # Errors /// /// This method returns the same errors as [`Write::write_all`]. /// /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all /// /// # Examples /// /// Write signed 32 bit big-endian integers to a `Write`: /// /// ```rust /// use byteorder::{BigEndian, WriteBytesExt}; /// /// let mut wtr = Vec::new(); /// wtr.write_i32::(-34253).unwrap(); /// wtr.write_i32::(1205419366).unwrap(); /// assert_eq!(wtr, b"\xff\xff\x7a\x33\x47\xd9\x3d\x66"); /// ``` #[inline] fn write_i32(&mut self, n: i32) -> Result<()> { let mut buf = [0; 4]; T::write_i32(&mut buf, n); self.write_all(&buf) } /// Writes an unsigned 48 bit integer to the underlying writer. /// /// # Errors /// /// This method returns the same errors as [`Write::write_all`]. /// /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all /// /// # Examples /// /// Write unsigned 48 bit big-endian integers to a `Write`: /// /// ```rust /// use byteorder::{BigEndian, WriteBytesExt}; /// /// let mut wtr = Vec::new(); /// wtr.write_u48::(52360336390828).unwrap(); /// wtr.write_u48::(541).unwrap(); /// assert_eq!(wtr, b"\x2f\x9f\x17\x40\x3a\xac\x00\x00\x00\x00\x02\x1d"); /// ``` #[inline] fn write_u48(&mut self, n: u64) -> Result<()> { let mut buf = [0; 6]; T::write_u48(&mut buf, n); self.write_all(&buf) } /// Writes a signed 48 bit integer to the underlying writer. /// /// # Errors /// /// This method returns the same errors as [`Write::write_all`]. /// /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all /// /// # Examples /// /// Write signed 48 bit big-endian integers to a `Write`: /// /// ```rust /// use byteorder::{BigEndian, WriteBytesExt}; /// /// let mut wtr = Vec::new(); /// wtr.write_i48::(-108363435763825).unwrap(); /// wtr.write_i48::(77).unwrap(); /// assert_eq!(wtr, b"\x9d\x71\xab\xe7\x97\x8f\x00\x00\x00\x00\x00\x4d"); /// ``` #[inline] fn write_i48(&mut self, n: i64) -> Result<()> { let mut buf = [0; 6]; T::write_i48(&mut buf, n); self.write_all(&buf) } /// Writes an unsigned 64 bit integer to the underlying writer. /// /// # Errors /// /// This method returns the same errors as [`Write::write_all`]. /// /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all /// /// # Examples /// /// Write unsigned 64 bit big-endian integers to a `Write`: /// /// ```rust /// use byteorder::{BigEndian, WriteBytesExt}; /// /// let mut wtr = Vec::new(); /// wtr.write_u64::(918733457491587).unwrap(); /// wtr.write_u64::(143).unwrap(); /// assert_eq!(wtr, b"\x00\x03\x43\x95\x4d\x60\x86\x83\x00\x00\x00\x00\x00\x00\x00\x8f"); /// ``` #[inline] fn write_u64(&mut self, n: u64) -> Result<()> { let mut buf = [0; 8]; T::write_u64(&mut buf, n); self.write_all(&buf) } /// Writes a signed 64 bit integer to the underlying writer. /// /// # Errors /// /// This method returns the same errors as [`Write::write_all`]. /// /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all /// /// # Examples /// /// Write signed 64 bit big-endian integers to a `Write`: /// /// ```rust /// use byteorder::{BigEndian, WriteBytesExt}; /// /// let mut wtr = Vec::new(); /// wtr.write_i64::(i64::min_value()).unwrap(); /// wtr.write_i64::(i64::max_value()).unwrap(); /// assert_eq!(wtr, b"\x80\x00\x00\x00\x00\x00\x00\x00\x7f\xff\xff\xff\xff\xff\xff\xff"); /// ``` #[inline] fn write_i64(&mut self, n: i64) -> Result<()> { let mut buf = [0; 8]; T::write_i64(&mut buf, n); self.write_all(&buf) } /// Writes an unsigned 128 bit integer to the underlying writer. #[inline] fn write_u128(&mut self, n: u128) -> Result<()> { let mut buf = [0; 16]; T::write_u128(&mut buf, n); self.write_all(&buf) } /// Writes a signed 128 bit integer to the underlying writer. #[inline] fn write_i128(&mut self, n: i128) -> Result<()> { let mut buf = [0; 16]; T::write_i128(&mut buf, n); self.write_all(&buf) } /// Writes an unsigned n-bytes integer to the underlying writer. /// /// # Errors /// /// This method returns the same errors as [`Write::write_all`]. /// /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all /// /// # Panics /// /// If the given integer is not representable in the given number of bytes, /// this method panics. If `nbytes > 8`, this method panics. /// /// # Examples /// /// Write unsigned 40 bit big-endian integers to a `Write`: /// /// ```rust /// use byteorder::{BigEndian, WriteBytesExt}; /// /// let mut wtr = Vec::new(); /// wtr.write_uint::(312550384361, 5).unwrap(); /// wtr.write_uint::(43, 5).unwrap(); /// assert_eq!(wtr, b"\x48\xc5\x74\x62\xe9\x00\x00\x00\x00\x2b"); /// ``` #[inline] fn write_uint( &mut self, n: u64, nbytes: usize, ) -> Result<()> { let mut buf = [0; 8]; T::write_uint(&mut buf, n, nbytes); self.write_all(&buf[0..nbytes]) } /// Writes a signed n-bytes integer to the underlying writer. /// /// # Errors /// /// This method returns the same errors as [`Write::write_all`]. /// /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all /// /// # Panics /// /// If the given integer is not representable in the given number of bytes, /// this method panics. If `nbytes > 8`, this method panics. /// /// # Examples /// /// Write signed 56 bit big-endian integers to a `Write`: /// /// ```rust /// use byteorder::{BigEndian, WriteBytesExt}; /// /// let mut wtr = Vec::new(); /// wtr.write_int::(-3548172039376767, 7).unwrap(); /// wtr.write_int::(43, 7).unwrap(); /// assert_eq!(wtr, b"\xf3\x64\xf4\xd1\xfd\xb0\x81\x00\x00\x00\x00\x00\x00\x2b"); /// ``` #[inline] fn write_int( &mut self, n: i64, nbytes: usize, ) -> Result<()> { let mut buf = [0; 8]; T::write_int(&mut buf, n, nbytes); self.write_all(&buf[0..nbytes]) } /// Writes an unsigned n-bytes integer to the underlying writer. /// /// If the given integer is not representable in the given number of bytes, /// this method panics. If `nbytes > 16`, this method panics. #[inline] fn write_uint128( &mut self, n: u128, nbytes: usize, ) -> Result<()> { let mut buf = [0; 16]; T::write_uint128(&mut buf, n, nbytes); self.write_all(&buf[0..nbytes]) } /// Writes a signed n-bytes integer to the underlying writer. /// /// If the given integer is not representable in the given number of bytes, /// this method panics. If `nbytes > 16`, this method panics. #[inline] fn write_int128( &mut self, n: i128, nbytes: usize, ) -> Result<()> { let mut buf = [0; 16]; T::write_int128(&mut buf, n, nbytes); self.write_all(&buf[0..nbytes]) } /// Writes a IEEE754 single-precision (4 bytes) floating point number to /// the underlying writer. /// /// # Errors /// /// This method returns the same errors as [`Write::write_all`]. /// /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all /// /// # Examples /// /// Write a big-endian single-precision floating point number to a `Write`: /// /// ```rust /// use std::f32; /// /// use byteorder::{BigEndian, WriteBytesExt}; /// /// let mut wtr = Vec::new(); /// wtr.write_f32::(f32::consts::PI).unwrap(); /// assert_eq!(wtr, b"\x40\x49\x0f\xdb"); /// ``` #[inline] fn write_f32(&mut self, n: f32) -> Result<()> { let mut buf = [0; 4]; T::write_f32(&mut buf, n); self.write_all(&buf) } /// Writes a IEEE754 double-precision (8 bytes) floating point number to /// the underlying writer. /// /// # Errors /// /// This method returns the same errors as [`Write::write_all`]. /// /// [`Write::write_all`]: https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all /// /// # Examples /// /// Write a big-endian double-precision floating point number to a `Write`: /// /// ```rust /// use std::f64; /// /// use byteorder::{BigEndian, WriteBytesExt}; /// /// let mut wtr = Vec::new(); /// wtr.write_f64::(f64::consts::PI).unwrap(); /// assert_eq!(wtr, b"\x40\x09\x21\xfb\x54\x44\x2d\x18"); /// ``` #[inline] fn write_f64(&mut self, n: f64) -> Result<()> { let mut buf = [0; 8]; T::write_f64(&mut buf, n); self.write_all(&buf) } } /// All types that implement `Write` get methods defined in `WriteBytesExt` /// for free. impl WriteBytesExt for W {} /// Convert a slice of T (where T is plain old data) to its mutable binary /// representation. /// /// This function is wildly unsafe because it permits arbitrary modification of /// the binary representation of any `Copy` type. Use with care. It's intended /// to be called only where `T` is a numeric type. unsafe fn slice_to_u8_mut(slice: &mut [T]) -> &mut [u8] { use std::mem::size_of; let len = size_of::() * slice.len(); slice::from_raw_parts_mut(slice.as_mut_ptr() as *mut u8, len) } byteorder-1.5.0/src/lib.rs000064400000000000000000003201451046102023000135360ustar 00000000000000/*! This crate provides convenience methods for encoding and decoding numbers in either [big-endian or little-endian order]. The organization of the crate is pretty simple. A trait, [`ByteOrder`], specifies byte conversion methods for each type of number in Rust (sans numbers that have a platform dependent size like `usize` and `isize`). Two types, [`BigEndian`] and [`LittleEndian`] implement these methods. Finally, [`ReadBytesExt`] and [`WriteBytesExt`] provide convenience methods available to all types that implement [`Read`] and [`Write`]. An alias, [`NetworkEndian`], for [`BigEndian`] is provided to help improve code clarity. An additional alias, [`NativeEndian`], is provided for the endianness of the local platform. This is convenient when serializing data for use and conversions are not desired. # Examples Read unsigned 16 bit big-endian integers from a [`Read`] type: ```rust use std::io::Cursor; use byteorder::{BigEndian, ReadBytesExt}; let mut rdr = Cursor::new(vec![2, 5, 3, 0]); // Note that we use type parameters to indicate which kind of byte order // we want! assert_eq!(517, rdr.read_u16::().unwrap()); assert_eq!(768, rdr.read_u16::().unwrap()); ``` Write unsigned 16 bit little-endian integers to a [`Write`] type: ```rust use byteorder::{LittleEndian, WriteBytesExt}; let mut wtr = vec![]; wtr.write_u16::(517).unwrap(); wtr.write_u16::(768).unwrap(); assert_eq!(wtr, vec![5, 2, 0, 3]); ``` # Optional Features This crate optionally provides support for 128 bit values (`i128` and `u128`) when built with the `i128` feature enabled. This crate can also be used without the standard library. # Alternatives Note that as of Rust 1.32, the standard numeric types provide built-in methods like `to_le_bytes` and `from_le_bytes`, which support some of the same use cases. [big-endian or little-endian order]: https://en.wikipedia.org/wiki/Endianness [`ByteOrder`]: trait.ByteOrder.html [`BigEndian`]: enum.BigEndian.html [`LittleEndian`]: enum.LittleEndian.html [`ReadBytesExt`]: trait.ReadBytesExt.html [`WriteBytesExt`]: trait.WriteBytesExt.html [`NetworkEndian`]: type.NetworkEndian.html [`NativeEndian`]: type.NativeEndian.html [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html */ #![deny(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] // When testing under miri, we disable tests that take too long. But this // provokes lots of dead code warnings. So we just squash them. #![cfg_attr(miri, allow(dead_code, unused_macros))] use core::{ convert::TryInto, fmt::Debug, hash::Hash, mem::align_of, 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 { const _: () = assert!(align_of::() <= align_of::()); 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 { const _: () = assert!(align_of::() <= align_of::()); 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 a &[u8] $src into a &mut [$ty] $dst for the endianness given by /// $from_bytes (must be either from_be_bytes or from_le_bytes). /// /// Panics if $src.len() != $dst.len() * size_of::<$ty>(). macro_rules! read_slice { ($src:expr, $dst:expr, $ty:ty, $from_bytes:ident) => {{ const SIZE: usize = core::mem::size_of::<$ty>(); // Check types: let src: &[u8] = $src; let dst: &mut [$ty] = $dst; assert_eq!(src.len(), dst.len() * SIZE); for (src, dst) in src.chunks_exact(SIZE).zip(dst.iter_mut()) { *dst = <$ty>::$from_bytes(src.try_into().unwrap()); } }}; } /// Copies a &[$ty] $src into a &mut [u8] $dst for the endianness given by /// $from_bytes (must be either from_be_bytes or from_le_bytes). /// /// Panics if $src.len() * size_of::<$ty>() != $dst.len(). macro_rules! write_slice { ($src:expr, $dst:expr, $ty:ty, $to_bytes:ident) => {{ const SIZE: usize = core::mem::size_of::<$ty>(); // Check types: let src: &[$ty] = $src; let dst: &mut [u8] = $dst; assert_eq!(src.len() * SIZE, dst.len()); for (src, dst) in src.iter().zip(dst.chunks_exact_mut(SIZE)) { dst.copy_from_slice(&src.$to_bytes()); } }}; } 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 { let mut out = [0; 8]; assert!(1 <= nbytes && nbytes <= out.len() && nbytes <= buf.len()); let start = out.len() - nbytes; out[start..].copy_from_slice(&buf[..nbytes]); u64::from_be_bytes(out) } #[inline] fn read_uint128(buf: &[u8], nbytes: usize) -> u128 { let mut out = [0; 16]; assert!(1 <= nbytes && nbytes <= out.len() && nbytes <= buf.len()); let start = out.len() - nbytes; out[start..].copy_from_slice(&buf[..nbytes]); u128::from_be_bytes(out) } #[inline] fn write_u16(buf: &mut [u8], n: u16) { buf[..2].copy_from_slice(&n.to_be_bytes()); } #[inline] fn write_u32(buf: &mut [u8], n: u32) { buf[..4].copy_from_slice(&n.to_be_bytes()); } #[inline] fn write_u64(buf: &mut [u8], n: u64) { buf[..8].copy_from_slice(&n.to_be_bytes()); } #[inline] fn write_u128(buf: &mut [u8], n: u128) { buf[..16].copy_from_slice(&n.to_be_bytes()); } #[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]) { read_slice!(src, dst, u16, from_be_bytes); } #[inline] fn read_u32_into(src: &[u8], dst: &mut [u32]) { read_slice!(src, dst, u32, from_be_bytes); } #[inline] fn read_u64_into(src: &[u8], dst: &mut [u64]) { read_slice!(src, dst, u64, from_be_bytes); } #[inline] fn read_u128_into(src: &[u8], dst: &mut [u128]) { read_slice!(src, dst, u128, from_be_bytes); } #[inline] fn write_u16_into(src: &[u16], dst: &mut [u8]) { write_slice!(src, dst, u16, to_be_bytes); } #[inline] fn write_u32_into(src: &[u32], dst: &mut [u8]) { write_slice!(src, dst, u32, to_be_bytes); } #[inline] fn write_u64_into(src: &[u64], dst: &mut [u8]) { write_slice!(src, dst, u64, to_be_bytes); } #[inline] fn write_u128_into(src: &[u128], dst: &mut [u8]) { write_slice!(src, dst, u128, to_be_bytes); } #[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 { let mut out = [0; 8]; assert!(1 <= nbytes && nbytes <= out.len() && nbytes <= buf.len()); out[..nbytes].copy_from_slice(&buf[..nbytes]); u64::from_le_bytes(out) } #[inline] fn read_uint128(buf: &[u8], nbytes: usize) -> u128 { let mut out = [0; 16]; assert!(1 <= nbytes && nbytes <= out.len() && nbytes <= buf.len()); out[..nbytes].copy_from_slice(&buf[..nbytes]); u128::from_le_bytes(out) } #[inline] fn write_u16(buf: &mut [u8], n: u16) { buf[..2].copy_from_slice(&n.to_le_bytes()); } #[inline] fn write_u32(buf: &mut [u8], n: u32) { buf[..4].copy_from_slice(&n.to_le_bytes()); } #[inline] fn write_u64(buf: &mut [u8], n: u64) { buf[..8].copy_from_slice(&n.to_le_bytes()); } #[inline] fn write_u128(buf: &mut [u8], n: u128) { buf[..16].copy_from_slice(&n.to_le_bytes()); } #[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]) { read_slice!(src, dst, u16, from_le_bytes); } #[inline] fn read_u32_into(src: &[u8], dst: &mut [u32]) { read_slice!(src, dst, u32, from_le_bytes); } #[inline] fn read_u64_into(src: &[u8], dst: &mut [u64]) { read_slice!(src, dst, u64, from_le_bytes); } #[inline] fn read_u128_into(src: &[u8], dst: &mut [u128]) { read_slice!(src, dst, u128, from_le_bytes); } #[inline] fn write_u16_into(src: &[u16], dst: &mut [u8]) { write_slice!(src, dst, u16, to_le_bytes); } #[inline] fn write_u32_into(src: &[u32], dst: &mut [u8]) { write_slice!(src, dst, u32, to_le_bytes); } #[inline] fn write_u64_into(src: &[u64], dst: &mut [u8]) { write_slice!(src, dst, u64, to_le_bytes); } #[inline] fn write_u128_into(src: &[u128], dst: &mut [u8]) { write_slice!(src, dst, u128, to_le_bytes); } #[inline] fn from_slice_u16(numbers: &mut [u16]) { if cfg!(target_endian = "big") { for n in numbers { *n = n.to_le(); } } } #[inline] fn from_slice_u32(numbers: &mut [u32]) { if cfg!(target_endian = "big") { for n in numbers { *n = n.to_le(); } } } #[inline] fn from_slice_u64(numbers: &mut [u64]) { if cfg!(target_endian = "big") { for n in numbers { *n = n.to_le(); } } } #[inline] fn from_slice_u128(numbers: &mut [u128]) { if cfg!(target_endian = "big") { for n in numbers { *n = n.to_le(); } } } #[inline] fn from_slice_f32(numbers: &mut [f32]) { if cfg!(target_endian = "big") { for n in numbers { unsafe { let int = *(n as *const f32 as *const u32); *n = *(&int.to_le() as *const u32 as *const f32); } } } } #[inline] fn from_slice_f64(numbers: &mut [f64]) { if cfg!(target_endian = "big") { for n in numbers { unsafe { let int = *(n as *const f64 as *const u64); *n = *(&int.to_le() as *const u64 as *const f64); } } } } } #[cfg(test)] mod test { use quickcheck::{Arbitrary, Gen, QuickCheck, StdGen, Testable}; use rand::{thread_rng, Rng}; pub const U24_MAX: u32 = 16_777_215; pub const I24_MAX: i32 = 8_388_607; pub const U48_MAX: u64 = 281_474_976_710_655; pub const I48_MAX: i64 = 140_737_488_355_327; pub const U64_MAX: u64 = ::core::u64::MAX; pub const I64_MAX: u64 = ::core::i64::MAX as u64; macro_rules! calc_max { ($max:expr, $bytes:expr) => { calc_max!($max, $bytes, 8) }; ($max:expr, $bytes:expr, $maxbytes:expr) => { ($max - 1) >> (8 * ($maxbytes - $bytes)) }; } #[derive(Clone, Debug)] pub struct Wi128(pub T); impl Wi128 { pub fn clone(&self) -> T { self.0.clone() } } impl PartialEq for Wi128 { fn eq(&self, other: &T) -> bool { self.0.eq(other) } } impl Arbitrary for Wi128 { fn arbitrary(gen: &mut G) -> Wi128 { let max = calc_max!(::core::u128::MAX, gen.size(), 16); let output = (gen.gen::() as u128) | ((gen.gen::() as u128) << 64); Wi128(output & (max - 1)) } } impl Arbitrary for Wi128 { fn arbitrary(gen: &mut G) -> Wi128 { let max = calc_max!(::core::i128::MAX, gen.size(), 16); let output = (gen.gen::() as i128) | ((gen.gen::() as i128) << 64); Wi128(output & (max - 1)) } } pub fn qc_sized(f: A, size: u64) { QuickCheck::new() .gen(StdGen::new(thread_rng(), size as usize)) .tests(1_00) .max_tests(10_000) .quickcheck(f); } macro_rules! qc_byte_order { ($name:ident, $ty_int:ty, $max:expr, $bytes:expr, $read:ident, $write:ident) => { #[cfg(not(miri))] 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) => { #[cfg(not(miri))] mod $name { #[allow(unused_imports)] use super::{qc_sized, Wi128}; use crate::{ BigEndian, ByteOrder, LittleEndian, NativeEndian, }; use core::mem::size_of; #[test] fn big_endian() { fn prop(n: $ty_int) -> bool { let bytes = size_of::<$ty_int>(); let mut buf = [0; 16]; BigEndian::$write(&mut buf[16 - bytes..], n.clone()); n == BigEndian::$read(&buf[16 - bytes..]) } qc_sized(prop as fn($ty_int) -> bool, $max - 1); } #[test] fn little_endian() { fn prop(n: $ty_int) -> bool { let bytes = size_of::<$ty_int>(); let mut buf = [0; 16]; LittleEndian::$write(&mut buf[..bytes], n.clone()); n == LittleEndian::$read(&buf[..bytes]) } qc_sized(prop as fn($ty_int) -> bool, $max - 1); } #[test] fn native_endian() { fn prop(n: $ty_int) -> bool { let bytes = size_of::<$ty_int>(); let mut buf = [0; 16]; NativeEndian::$write(&mut buf[..bytes], n.clone()); n == NativeEndian::$read(&buf[..bytes]) } qc_sized(prop as fn($ty_int) -> bool, $max - 1); } } }; } qc_byte_order!( prop_u16, u16, ::core::u16::MAX as u64, read_u16, write_u16 ); qc_byte_order!( prop_i16, i16, ::core::i16::MAX as u64, read_i16, write_i16 ); qc_byte_order!( prop_u24, u32, crate::test::U24_MAX as u64, read_u24, write_u24 ); qc_byte_order!( prop_i24, i32, crate::test::I24_MAX as u64, read_i24, write_i24 ); qc_byte_order!( prop_u32, u32, ::core::u32::MAX as u64, read_u32, write_u32 ); qc_byte_order!( prop_i32, i32, ::core::i32::MAX as u64, read_i32, write_i32 ); qc_byte_order!( prop_u48, u64, crate::test::U48_MAX as u64, read_u48, write_u48 ); qc_byte_order!( prop_i48, i64, crate::test::I48_MAX as u64, read_i48, write_i48 ); qc_byte_order!( prop_u64, u64, ::core::u64::MAX as u64, read_u64, write_u64 ); qc_byte_order!( prop_i64, i64, ::core::i64::MAX as u64, read_i64, write_i64 ); qc_byte_order!( prop_f32, f32, ::core::u64::MAX as u64, read_f32, write_f32 ); qc_byte_order!( prop_f64, f64, ::core::i64::MAX as u64, read_f64, write_f64 ); qc_byte_order!(prop_u128, Wi128, 16 + 1, read_u128, write_u128); qc_byte_order!(prop_i128, Wi128, 16 + 1, read_i128, write_i128); qc_byte_order!( prop_uint_1, u64, calc_max!(super::U64_MAX, 1), 1, read_uint, write_uint ); qc_byte_order!( prop_uint_2, u64, calc_max!(super::U64_MAX, 2), 2, read_uint, write_uint ); qc_byte_order!( prop_uint_3, u64, calc_max!(super::U64_MAX, 3), 3, read_uint, write_uint ); qc_byte_order!( prop_uint_4, u64, calc_max!(super::U64_MAX, 4), 4, read_uint, write_uint ); qc_byte_order!( prop_uint_5, u64, calc_max!(super::U64_MAX, 5), 5, read_uint, write_uint ); qc_byte_order!( prop_uint_6, u64, calc_max!(super::U64_MAX, 6), 6, read_uint, write_uint ); qc_byte_order!( prop_uint_7, u64, calc_max!(super::U64_MAX, 7), 7, read_uint, write_uint ); qc_byte_order!( prop_uint_8, u64, calc_max!(super::U64_MAX, 8), 8, read_uint, write_uint ); qc_byte_order!( prop_uint128_1, Wi128, 1, 1, read_uint128, write_uint128 ); qc_byte_order!( prop_uint128_2, Wi128, 2, 2, read_uint128, write_uint128 ); qc_byte_order!( prop_uint128_3, Wi128, 3, 3, read_uint128, write_uint128 ); qc_byte_order!( prop_uint128_4, Wi128, 4, 4, read_uint128, write_uint128 ); qc_byte_order!( prop_uint128_5, Wi128, 5, 5, read_uint128, write_uint128 ); qc_byte_order!( prop_uint128_6, Wi128, 6, 6, read_uint128, write_uint128 ); qc_byte_order!( prop_uint128_7, Wi128, 7, 7, read_uint128, write_uint128 ); qc_byte_order!( prop_uint128_8, Wi128, 8, 8, read_uint128, write_uint128 ); qc_byte_order!( prop_uint128_9, Wi128, 9, 9, read_uint128, write_uint128 ); qc_byte_order!( prop_uint128_10, Wi128, 10, 10, read_uint128, write_uint128 ); qc_byte_order!( prop_uint128_11, Wi128, 11, 11, read_uint128, write_uint128 ); qc_byte_order!( prop_uint128_12, Wi128, 12, 12, read_uint128, write_uint128 ); qc_byte_order!( prop_uint128_13, Wi128, 13, 13, read_uint128, write_uint128 ); qc_byte_order!( prop_uint128_14, Wi128, 14, 14, read_uint128, write_uint128 ); qc_byte_order!( prop_uint128_15, Wi128, 15, 15, read_uint128, write_uint128 ); qc_byte_order!( prop_uint128_16, Wi128, 16, 16, read_uint128, write_uint128 ); qc_byte_order!( prop_int_1, i64, calc_max!(super::I64_MAX, 1), 1, read_int, write_int ); qc_byte_order!( prop_int_2, i64, calc_max!(super::I64_MAX, 2), 2, read_int, write_int ); qc_byte_order!( prop_int_3, i64, calc_max!(super::I64_MAX, 3), 3, read_int, write_int ); qc_byte_order!( prop_int_4, i64, calc_max!(super::I64_MAX, 4), 4, read_int, write_int ); qc_byte_order!( prop_int_5, i64, calc_max!(super::I64_MAX, 5), 5, read_int, write_int ); qc_byte_order!( prop_int_6, i64, calc_max!(super::I64_MAX, 6), 6, read_int, write_int ); qc_byte_order!( prop_int_7, i64, calc_max!(super::I64_MAX, 7), 7, read_int, write_int ); qc_byte_order!( prop_int_8, i64, calc_max!(super::I64_MAX, 8), 8, read_int, write_int ); qc_byte_order!( prop_int128_1, Wi128, 1, 1, read_int128, write_int128 ); qc_byte_order!( prop_int128_2, Wi128, 2, 2, read_int128, write_int128 ); qc_byte_order!( prop_int128_3, Wi128, 3, 3, read_int128, write_int128 ); qc_byte_order!( prop_int128_4, Wi128, 4, 4, read_int128, write_int128 ); qc_byte_order!( prop_int128_5, Wi128, 5, 5, read_int128, write_int128 ); qc_byte_order!( prop_int128_6, Wi128, 6, 6, read_int128, write_int128 ); qc_byte_order!( prop_int128_7, Wi128, 7, 7, read_int128, write_int128 ); qc_byte_order!( prop_int128_8, Wi128, 8, 8, read_int128, write_int128 ); qc_byte_order!( prop_int128_9, Wi128, 9, 9, read_int128, write_int128 ); qc_byte_order!( prop_int128_10, Wi128, 10, 10, read_int128, write_int128 ); qc_byte_order!( prop_int128_11, Wi128, 11, 11, read_int128, write_int128 ); qc_byte_order!( prop_int128_12, Wi128, 12, 12, read_int128, write_int128 ); qc_byte_order!( prop_int128_13, Wi128, 13, 13, read_int128, write_int128 ); qc_byte_order!( prop_int128_14, Wi128, 14, 14, read_int128, write_int128 ); qc_byte_order!( prop_int128_15, Wi128, 15, 15, read_int128, write_int128 ); qc_byte_order!( prop_int128_16, Wi128, 16, 16, read_int128, write_int128 ); // Test that all of the byte conversion functions panic when given a // buffer that is too small. // // These tests are critical to ensure safety, otherwise we might end up // with a buffer overflow. macro_rules! too_small { ($name:ident, $maximally_small:expr, $zero:expr, $read:ident, $write:ident) => { mod $name { use crate::{ BigEndian, ByteOrder, LittleEndian, NativeEndian, }; #[test] #[should_panic] fn read_big_endian() { let buf = [0; $maximally_small]; BigEndian::$read(&buf); } #[test] #[should_panic] fn read_little_endian() { let buf = [0; $maximally_small]; LittleEndian::$read(&buf); } #[test] #[should_panic] fn read_native_endian() { let buf = [0; $maximally_small]; NativeEndian::$read(&buf); } #[test] #[should_panic] fn write_big_endian() { let mut buf = [0; $maximally_small]; BigEndian::$write(&mut buf, $zero); } #[test] #[should_panic] fn write_little_endian() { let mut buf = [0; $maximally_small]; LittleEndian::$write(&mut buf, $zero); } #[test] #[should_panic] fn write_native_endian() { let mut buf = [0; $maximally_small]; NativeEndian::$write(&mut buf, $zero); } } }; ($name:ident, $maximally_small:expr, $read:ident) => { mod $name { use crate::{ BigEndian, ByteOrder, LittleEndian, NativeEndian, }; #[test] #[should_panic] fn read_big_endian() { let buf = [0; $maximally_small]; BigEndian::$read(&buf, $maximally_small + 1); } #[test] #[should_panic] fn read_little_endian() { let buf = [0; $maximally_small]; LittleEndian::$read(&buf, $maximally_small + 1); } #[test] #[should_panic] fn read_native_endian() { let buf = [0; $maximally_small]; NativeEndian::$read(&buf, $maximally_small + 1); } } }; } too_small!(small_u16, 1, 0, read_u16, write_u16); too_small!(small_i16, 1, 0, read_i16, write_i16); too_small!(small_u32, 3, 0, read_u32, write_u32); too_small!(small_i32, 3, 0, read_i32, write_i32); too_small!(small_u64, 7, 0, read_u64, write_u64); too_small!(small_i64, 7, 0, read_i64, write_i64); too_small!(small_f32, 3, 0.0, read_f32, write_f32); too_small!(small_f64, 7, 0.0, read_f64, write_f64); too_small!(small_u128, 15, 0, read_u128, write_u128); too_small!(small_i128, 15, 0, read_i128, write_i128); too_small!(small_uint_1, 1, read_uint); too_small!(small_uint_2, 2, read_uint); too_small!(small_uint_3, 3, read_uint); too_small!(small_uint_4, 4, read_uint); too_small!(small_uint_5, 5, read_uint); too_small!(small_uint_6, 6, read_uint); too_small!(small_uint_7, 7, read_uint); too_small!(small_uint128_1, 1, read_uint128); too_small!(small_uint128_2, 2, read_uint128); too_small!(small_uint128_3, 3, read_uint128); too_small!(small_uint128_4, 4, read_uint128); too_small!(small_uint128_5, 5, read_uint128); too_small!(small_uint128_6, 6, read_uint128); too_small!(small_uint128_7, 7, read_uint128); too_small!(small_uint128_8, 8, read_uint128); too_small!(small_uint128_9, 9, read_uint128); too_small!(small_uint128_10, 10, read_uint128); too_small!(small_uint128_11, 11, read_uint128); too_small!(small_uint128_12, 12, read_uint128); too_small!(small_uint128_13, 13, read_uint128); too_small!(small_uint128_14, 14, read_uint128); too_small!(small_uint128_15, 15, read_uint128); too_small!(small_int_1, 1, read_int); too_small!(small_int_2, 2, read_int); too_small!(small_int_3, 3, read_int); too_small!(small_int_4, 4, read_int); too_small!(small_int_5, 5, read_int); too_small!(small_int_6, 6, read_int); too_small!(small_int_7, 7, read_int); too_small!(small_int128_1, 1, read_int128); too_small!(small_int128_2, 2, read_int128); too_small!(small_int128_3, 3, read_int128); too_small!(small_int128_4, 4, read_int128); too_small!(small_int128_5, 5, read_int128); too_small!(small_int128_6, 6, read_int128); too_small!(small_int128_7, 7, read_int128); too_small!(small_int128_8, 8, read_int128); too_small!(small_int128_9, 9, read_int128); too_small!(small_int128_10, 10, read_int128); too_small!(small_int128_11, 11, read_int128); too_small!(small_int128_12, 12, read_int128); too_small!(small_int128_13, 13, read_int128); too_small!(small_int128_14, 14, read_int128); too_small!(small_int128_15, 15, read_int128); // Test that reading/writing slices enforces the correct lengths. macro_rules! slice_lengths { ($name:ident, $read:ident, $write:ident, $num_bytes:expr, $numbers:expr) => { mod $name { use crate::{ BigEndian, ByteOrder, LittleEndian, NativeEndian, }; #[test] #[should_panic] fn read_big_endian() { let bytes = [0; $num_bytes]; let mut numbers = $numbers; BigEndian::$read(&bytes, &mut numbers); } #[test] #[should_panic] fn read_little_endian() { let bytes = [0; $num_bytes]; let mut numbers = $numbers; LittleEndian::$read(&bytes, &mut numbers); } #[test] #[should_panic] fn read_native_endian() { let bytes = [0; $num_bytes]; let mut numbers = $numbers; NativeEndian::$read(&bytes, &mut numbers); } #[test] #[should_panic] fn write_big_endian() { let mut bytes = [0; $num_bytes]; let numbers = $numbers; BigEndian::$write(&numbers, &mut bytes); } #[test] #[should_panic] fn write_little_endian() { let mut bytes = [0; $num_bytes]; let numbers = $numbers; LittleEndian::$write(&numbers, &mut bytes); } #[test] #[should_panic] fn write_native_endian() { let mut bytes = [0; $num_bytes]; let numbers = $numbers; NativeEndian::$write(&numbers, &mut bytes); } } }; } slice_lengths!( slice_len_too_small_u16, read_u16_into, write_u16_into, 3, [0, 0] ); slice_lengths!( slice_len_too_big_u16, read_u16_into, write_u16_into, 5, [0, 0] ); slice_lengths!( slice_len_too_small_i16, read_i16_into, write_i16_into, 3, [0, 0] ); slice_lengths!( slice_len_too_big_i16, read_i16_into, write_i16_into, 5, [0, 0] ); slice_lengths!( slice_len_too_small_u32, read_u32_into, write_u32_into, 7, [0, 0] ); slice_lengths!( slice_len_too_big_u32, read_u32_into, write_u32_into, 9, [0, 0] ); slice_lengths!( slice_len_too_small_i32, read_i32_into, write_i32_into, 7, [0, 0] ); slice_lengths!( slice_len_too_big_i32, read_i32_into, write_i32_into, 9, [0, 0] ); slice_lengths!( slice_len_too_small_u64, read_u64_into, write_u64_into, 15, [0, 0] ); slice_lengths!( slice_len_too_big_u64, read_u64_into, write_u64_into, 17, [0, 0] ); slice_lengths!( slice_len_too_small_i64, read_i64_into, write_i64_into, 15, [0, 0] ); slice_lengths!( slice_len_too_big_i64, read_i64_into, write_i64_into, 17, [0, 0] ); slice_lengths!( slice_len_too_small_u128, read_u128_into, write_u128_into, 31, [0, 0] ); slice_lengths!( slice_len_too_big_u128, read_u128_into, write_u128_into, 33, [0, 0] ); slice_lengths!( slice_len_too_small_i128, read_i128_into, write_i128_into, 31, [0, 0] ); slice_lengths!( slice_len_too_big_i128, read_i128_into, write_i128_into, 33, [0, 0] ); #[test] fn uint_bigger_buffer() { use crate::{ByteOrder, LittleEndian}; let n = LittleEndian::read_uint(&[1, 2, 3, 4, 5, 6, 7, 8], 5); assert_eq!(n, 0x05_0403_0201); } #[test] fn regression173_array_impl() { use crate::{BigEndian, ByteOrder, LittleEndian}; let xs = [0; 100]; let x = BigEndian::read_u16(&xs); assert_eq!(x, 0); let x = BigEndian::read_u32(&xs); assert_eq!(x, 0); let x = BigEndian::read_u64(&xs); assert_eq!(x, 0); let x = BigEndian::read_u128(&xs); assert_eq!(x, 0); let x = BigEndian::read_i16(&xs); assert_eq!(x, 0); let x = BigEndian::read_i32(&xs); assert_eq!(x, 0); let x = BigEndian::read_i64(&xs); assert_eq!(x, 0); let x = BigEndian::read_i128(&xs); assert_eq!(x, 0); let x = LittleEndian::read_u16(&xs); assert_eq!(x, 0); let x = LittleEndian::read_u32(&xs); assert_eq!(x, 0); let x = LittleEndian::read_u64(&xs); assert_eq!(x, 0); let x = LittleEndian::read_u128(&xs); assert_eq!(x, 0); let x = LittleEndian::read_i16(&xs); assert_eq!(x, 0); let x = LittleEndian::read_i32(&xs); assert_eq!(x, 0); let x = LittleEndian::read_i64(&xs); assert_eq!(x, 0); let x = LittleEndian::read_i128(&xs); assert_eq!(x, 0); } } #[cfg(test)] #[cfg(feature = "std")] mod stdtests { extern crate quickcheck; extern crate rand; use self::quickcheck::{QuickCheck, StdGen, Testable}; use self::rand::thread_rng; fn qc_unsized(f: A) { QuickCheck::new() .gen(StdGen::new(thread_rng(), 16)) .tests(1_00) .max_tests(10_000) .quickcheck(f); } macro_rules! calc_max { ($max:expr, $bytes:expr) => { ($max - 1) >> (8 * (8 - $bytes)) }; } macro_rules! qc_bytes_ext { ($name:ident, $ty_int:ty, $max:expr, $bytes:expr, $read:ident, $write:ident) => { #[cfg(not(miri))] mod $name { #[allow(unused_imports)] use crate::test::{qc_sized, Wi128}; use crate::{ BigEndian, LittleEndian, NativeEndian, ReadBytesExt, WriteBytesExt, }; use std::io::Cursor; #[test] fn big_endian() { fn prop(n: $ty_int) -> bool { let mut wtr = vec![]; wtr.$write::(n.clone()).unwrap(); let offset = wtr.len() - $bytes; let mut rdr = Cursor::new(&mut wtr[offset..]); n == rdr.$read::($bytes).unwrap() } qc_sized(prop as fn($ty_int) -> bool, $max); } #[test] fn little_endian() { fn prop(n: $ty_int) -> bool { let mut wtr = vec![]; wtr.$write::(n.clone()).unwrap(); let mut rdr = Cursor::new(wtr); n == rdr.$read::($bytes).unwrap() } qc_sized(prop as fn($ty_int) -> bool, $max); } #[test] fn native_endian() { fn prop(n: $ty_int) -> bool { let mut wtr = vec![]; wtr.$write::(n.clone()).unwrap(); let offset = if cfg!(target_endian = "big") { wtr.len() - $bytes } else { 0 }; let mut rdr = Cursor::new(&mut wtr[offset..]); n == rdr.$read::($bytes).unwrap() } qc_sized(prop as fn($ty_int) -> bool, $max); } } }; ($name:ident, $ty_int:ty, $max:expr, $read:ident, $write:ident) => { #[cfg(not(miri))] mod $name { #[allow(unused_imports)] use crate::test::{qc_sized, Wi128}; use crate::{ BigEndian, LittleEndian, NativeEndian, ReadBytesExt, WriteBytesExt, }; use std::io::Cursor; #[test] fn big_endian() { fn prop(n: $ty_int) -> bool { let mut wtr = vec![]; wtr.$write::(n.clone()).unwrap(); let mut rdr = Cursor::new(wtr); n == rdr.$read::().unwrap() } qc_sized(prop as fn($ty_int) -> bool, $max - 1); } #[test] fn little_endian() { fn prop(n: $ty_int) -> bool { let mut wtr = vec![]; wtr.$write::(n.clone()).unwrap(); let mut rdr = Cursor::new(wtr); n == rdr.$read::().unwrap() } qc_sized(prop as fn($ty_int) -> bool, $max - 1); } #[test] fn native_endian() { fn prop(n: $ty_int) -> bool { let mut wtr = vec![]; wtr.$write::(n.clone()).unwrap(); let mut rdr = Cursor::new(wtr); n == rdr.$read::().unwrap() } qc_sized(prop as fn($ty_int) -> bool, $max - 1); } } }; } qc_bytes_ext!( prop_ext_u16, u16, ::std::u16::MAX as u64, read_u16, write_u16 ); qc_bytes_ext!( prop_ext_i16, i16, ::std::i16::MAX as u64, read_i16, write_i16 ); qc_bytes_ext!( prop_ext_u32, u32, ::std::u32::MAX as u64, read_u32, write_u32 ); qc_bytes_ext!( prop_ext_i32, i32, ::std::i32::MAX as u64, read_i32, write_i32 ); qc_bytes_ext!( prop_ext_u64, u64, ::std::u64::MAX as u64, read_u64, write_u64 ); qc_bytes_ext!( prop_ext_i64, i64, ::std::i64::MAX as u64, read_i64, write_i64 ); qc_bytes_ext!( prop_ext_f32, f32, ::std::u64::MAX as u64, read_f32, write_f32 ); qc_bytes_ext!( prop_ext_f64, f64, ::std::i64::MAX as u64, read_f64, write_f64 ); qc_bytes_ext!(prop_ext_u128, Wi128, 16 + 1, read_u128, write_u128); qc_bytes_ext!(prop_ext_i128, Wi128, 16 + 1, read_i128, write_i128); qc_bytes_ext!( prop_ext_uint_1, u64, calc_max!(crate::test::U64_MAX, 1), 1, read_uint, write_u64 ); qc_bytes_ext!( prop_ext_uint_2, u64, calc_max!(crate::test::U64_MAX, 2), 2, read_uint, write_u64 ); qc_bytes_ext!( prop_ext_uint_3, u64, calc_max!(crate::test::U64_MAX, 3), 3, read_uint, write_u64 ); qc_bytes_ext!( prop_ext_uint_4, u64, calc_max!(crate::test::U64_MAX, 4), 4, read_uint, write_u64 ); qc_bytes_ext!( prop_ext_uint_5, u64, calc_max!(crate::test::U64_MAX, 5), 5, read_uint, write_u64 ); qc_bytes_ext!( prop_ext_uint_6, u64, calc_max!(crate::test::U64_MAX, 6), 6, read_uint, write_u64 ); qc_bytes_ext!( prop_ext_uint_7, u64, calc_max!(crate::test::U64_MAX, 7), 7, read_uint, write_u64 ); qc_bytes_ext!( prop_ext_uint_8, u64, calc_max!(crate::test::U64_MAX, 8), 8, read_uint, write_u64 ); qc_bytes_ext!( prop_ext_uint128_1, Wi128, 1, 1, read_uint128, write_u128 ); qc_bytes_ext!( prop_ext_uint128_2, Wi128, 2, 2, read_uint128, write_u128 ); qc_bytes_ext!( prop_ext_uint128_3, Wi128, 3, 3, read_uint128, write_u128 ); qc_bytes_ext!( prop_ext_uint128_4, Wi128, 4, 4, read_uint128, write_u128 ); qc_bytes_ext!( prop_ext_uint128_5, Wi128, 5, 5, read_uint128, write_u128 ); qc_bytes_ext!( prop_ext_uint128_6, Wi128, 6, 6, read_uint128, write_u128 ); qc_bytes_ext!( prop_ext_uint128_7, Wi128, 7, 7, read_uint128, write_u128 ); qc_bytes_ext!( prop_ext_uint128_8, Wi128, 8, 8, read_uint128, write_u128 ); qc_bytes_ext!( prop_ext_uint128_9, Wi128, 9, 9, read_uint128, write_u128 ); qc_bytes_ext!( prop_ext_uint128_10, Wi128, 10, 10, read_uint128, write_u128 ); qc_bytes_ext!( prop_ext_uint128_11, Wi128, 11, 11, read_uint128, write_u128 ); qc_bytes_ext!( prop_ext_uint128_12, Wi128, 12, 12, read_uint128, write_u128 ); qc_bytes_ext!( prop_ext_uint128_13, Wi128, 13, 13, read_uint128, write_u128 ); qc_bytes_ext!( prop_ext_uint128_14, Wi128, 14, 14, read_uint128, write_u128 ); qc_bytes_ext!( prop_ext_uint128_15, Wi128, 15, 15, read_uint128, write_u128 ); qc_bytes_ext!( prop_ext_uint128_16, Wi128, 16, 16, read_uint128, write_u128 ); qc_bytes_ext!( prop_ext_int_1, i64, calc_max!(crate::test::I64_MAX, 1), 1, read_int, write_i64 ); qc_bytes_ext!( prop_ext_int_2, i64, calc_max!(crate::test::I64_MAX, 2), 2, read_int, write_i64 ); qc_bytes_ext!( prop_ext_int_3, i64, calc_max!(crate::test::I64_MAX, 3), 3, read_int, write_i64 ); qc_bytes_ext!( prop_ext_int_4, i64, calc_max!(crate::test::I64_MAX, 4), 4, read_int, write_i64 ); qc_bytes_ext!( prop_ext_int_5, i64, calc_max!(crate::test::I64_MAX, 5), 5, read_int, write_i64 ); qc_bytes_ext!( prop_ext_int_6, i64, calc_max!(crate::test::I64_MAX, 6), 6, read_int, write_i64 ); qc_bytes_ext!( prop_ext_int_7, i64, calc_max!(crate::test::I64_MAX, 1), 7, read_int, write_i64 ); qc_bytes_ext!( prop_ext_int_8, i64, calc_max!(crate::test::I64_MAX, 8), 8, read_int, write_i64 ); qc_bytes_ext!( prop_ext_int128_1, Wi128, 1, 1, read_int128, write_i128 ); qc_bytes_ext!( prop_ext_int128_2, Wi128, 2, 2, read_int128, write_i128 ); qc_bytes_ext!( prop_ext_int128_3, Wi128, 3, 3, read_int128, write_i128 ); qc_bytes_ext!( prop_ext_int128_4, Wi128, 4, 4, read_int128, write_i128 ); qc_bytes_ext!( prop_ext_int128_5, Wi128, 5, 5, read_int128, write_i128 ); qc_bytes_ext!( prop_ext_int128_6, Wi128, 6, 6, read_int128, write_i128 ); qc_bytes_ext!( prop_ext_int128_7, Wi128, 7, 7, read_int128, write_i128 ); qc_bytes_ext!( prop_ext_int128_8, Wi128, 8, 8, read_int128, write_i128 ); qc_bytes_ext!( prop_ext_int128_9, Wi128, 9, 9, read_int128, write_i128 ); qc_bytes_ext!( prop_ext_int128_10, Wi128, 10, 10, read_int128, write_i128 ); qc_bytes_ext!( prop_ext_int128_11, Wi128, 11, 11, read_int128, write_i128 ); qc_bytes_ext!( prop_ext_int128_12, Wi128, 12, 12, read_int128, write_i128 ); qc_bytes_ext!( prop_ext_int128_13, Wi128, 13, 13, read_int128, write_i128 ); qc_bytes_ext!( prop_ext_int128_14, Wi128, 14, 14, read_int128, write_i128 ); qc_bytes_ext!( prop_ext_int128_15, Wi128, 15, 15, read_int128, write_i128 ); qc_bytes_ext!( prop_ext_int128_16, Wi128, 16, 16, read_int128, write_i128 ); // Test slice serialization/deserialization. macro_rules! qc_slice { ($name:ident, $ty_int:ty, $read:ident, $write:ident, $zero:expr) => { #[cfg(not(miri))] mod $name { use super::qc_unsized; #[allow(unused_imports)] use crate::test::Wi128; use crate::{ BigEndian, ByteOrder, LittleEndian, NativeEndian, }; use core::mem::size_of; #[test] fn big_endian() { #[allow(unused_unsafe)] fn prop(numbers: Vec<$ty_int>) -> bool { let numbers: Vec<_> = numbers.into_iter().map(|x| x.clone()).collect(); let num_bytes = size_of::<$ty_int>() * numbers.len(); let mut bytes = vec![0; num_bytes]; BigEndian::$write(&numbers, &mut bytes); let mut got = vec![$zero; numbers.len()]; unsafe { BigEndian::$read(&bytes, &mut got); } numbers == got } qc_unsized(prop as fn(_) -> bool); } #[test] fn little_endian() { #[allow(unused_unsafe)] fn prop(numbers: Vec<$ty_int>) -> bool { let numbers: Vec<_> = numbers.into_iter().map(|x| x.clone()).collect(); let num_bytes = size_of::<$ty_int>() * numbers.len(); let mut bytes = vec![0; num_bytes]; LittleEndian::$write(&numbers, &mut bytes); let mut got = vec![$zero; numbers.len()]; unsafe { LittleEndian::$read(&bytes, &mut got); } numbers == got } qc_unsized(prop as fn(_) -> bool); } #[test] fn native_endian() { #[allow(unused_unsafe)] fn prop(numbers: Vec<$ty_int>) -> bool { let numbers: Vec<_> = numbers.into_iter().map(|x| x.clone()).collect(); let num_bytes = size_of::<$ty_int>() * numbers.len(); let mut bytes = vec![0; num_bytes]; NativeEndian::$write(&numbers, &mut bytes); let mut got = vec![$zero; numbers.len()]; unsafe { NativeEndian::$read(&bytes, &mut got); } numbers == got } qc_unsized(prop as fn(_) -> bool); } } }; } qc_slice!(prop_slice_u16, u16, read_u16_into, write_u16_into, 0); qc_slice!(prop_slice_i16, i16, read_i16_into, write_i16_into, 0); qc_slice!(prop_slice_u32, u32, read_u32_into, write_u32_into, 0); qc_slice!(prop_slice_i32, i32, read_i32_into, write_i32_into, 0); qc_slice!(prop_slice_u64, u64, read_u64_into, write_u64_into, 0); qc_slice!(prop_slice_i64, i64, read_i64_into, write_i64_into, 0); qc_slice!( prop_slice_u128, Wi128, read_u128_into, write_u128_into, 0 ); qc_slice!( prop_slice_i128, Wi128, read_i128_into, write_i128_into, 0 ); qc_slice!(prop_slice_f32, f32, read_f32_into, write_f32_into, 0.0); qc_slice!(prop_slice_f64, f64, read_f64_into, write_f64_into, 0.0); }