diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-15 03:35:49 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-15 03:35:49 +0000 |
commit | d8bbc7858622b6d9c278469aab701ca0b609cddf (patch) | |
tree | eff41dc61d9f714852212739e6b3738b82a2af87 /third_party/rust/scroll | |
parent | Releasing progress-linux version 125.0.3-1~progress7.99u1. (diff) | |
download | firefox-d8bbc7858622b6d9c278469aab701ca0b609cddf.tar.xz firefox-d8bbc7858622b6d9c278469aab701ca0b609cddf.zip |
Merging upstream version 126.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/scroll')
-rw-r--r-- | third_party/rust/scroll/.cargo-checksum.json | 2 | ||||
-rw-r--r-- | third_party/rust/scroll/CHANGELOG.md | 17 | ||||
-rw-r--r-- | third_party/rust/scroll/Cargo.lock | 205 | ||||
-rw-r--r-- | third_party/rust/scroll/Cargo.toml | 33 | ||||
-rw-r--r-- | third_party/rust/scroll/README.md | 13 | ||||
-rw-r--r-- | third_party/rust/scroll/benches/bench.rs | 157 | ||||
-rw-r--r-- | third_party/rust/scroll/examples/data_ctx.rs | 24 | ||||
-rw-r--r-- | third_party/rust/scroll/src/ctx.rs | 107 | ||||
-rw-r--r-- | third_party/rust/scroll/src/endian.rs | 5 | ||||
-rw-r--r-- | third_party/rust/scroll/src/error.rs | 26 | ||||
-rw-r--r-- | third_party/rust/scroll/src/leb128.rs | 18 | ||||
-rw-r--r-- | third_party/rust/scroll/src/lesser.rs | 7 | ||||
-rw-r--r-- | third_party/rust/scroll/src/lib.rs | 67 | ||||
-rw-r--r-- | third_party/rust/scroll/src/pread.rs | 7 | ||||
-rw-r--r-- | third_party/rust/scroll/src/pwrite.rs | 9 | ||||
-rw-r--r-- | third_party/rust/scroll/tests/api.rs | 292 |
16 files changed, 190 insertions, 799 deletions
diff --git a/third_party/rust/scroll/.cargo-checksum.json b/third_party/rust/scroll/.cargo-checksum.json index 406f97faa2..4cdf2841c7 100644 --- a/third_party/rust/scroll/.cargo-checksum.json +++ b/third_party/rust/scroll/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"CHANGELOG.md":"de2bbf4669561405d402322f4cc2604218d4986b73b75b41708b9505aebcb02c","Cargo.lock":"d6a215b7466d37e08551c56949e77be4ee488f989bdef3e507713c729bbda0e6","Cargo.toml":"c240c5768d23ea9611ef57308f08b8ee4372ede6c04f0783dc9fd1710e664c19","LICENSE":"6e24b7455f0b9afefdf4f3efd59a56ce76a3020c2dc4371937e281fc5e587fd7","README.md":"e4fe9aabcd87d85a5ec93241eeefc0d69aa0d98fbd67da2fe1849e4cbddac3ce","benches/bench.rs":"12ae02c383c91f1b0e11e9201eb8a9d44dadfb2b5987e7e71b0ef7c6589af1ca","examples/data_ctx.rs":"79684fc44d499d0b13a173184793837fbaba70d2f74f075e796eb37a1803ce3d","src/ctx.rs":"8f58672c5f3bc09b8f09c76f1d423431cbff786af75f5b39a0cef23b820d48c6","src/endian.rs":"5b717eb5ed0dc2b536779316b020df4e6489c05b13b4fd9b5f5e683aca1b2c28","src/error.rs":"a6a0ec9a6237d23febd608637c0e3926d147511e7983195366bc5a11f12d9093","src/greater.rs":"29d9736f9d35a0f92ca054c7a36878ade0a77b4e8ee27441c34cd81c6bdb68e6","src/leb128.rs":"e343f4e104ca6d8660a3dded30934b83bad4c04d8888ce2cbebfa562f5ac115d","src/lesser.rs":"d3028781977e60d67003512e45666935deab9a03c76a3ba9316a5dbdddf432eb","src/lib.rs":"49d02fa761bb2a771d1857ffd150aa4b6f55b4f03aee1a7a23d8181c76a55fd6","src/pread.rs":"64afdcf2c2785f1f23d065ec5e565d78569086dfd9ece0a3d2553b05aee5df9b","src/pwrite.rs":"05e3129ec666790a61f5b5f894ad863103e213eb798243cfe5f2cbb54d042ba1","tests/api.rs":"1bef345e020a6a4e590350ea4f6069c5836941656379e252bfbdaee6edbbc0de"},"package":"04c565b551bafbef4157586fa379538366e4385d42082f255bfd96e4fe8519da"}
\ No newline at end of file +{"files":{"Cargo.toml":"c9242ab52e0b3ba02d9557c3ef2070bc173dfbef05870c3c4831937233de38c0","LICENSE":"6e24b7455f0b9afefdf4f3efd59a56ce76a3020c2dc4371937e281fc5e587fd7","README.md":"7a7f6695853fbc174e3b016d72a8ef0113e313c897269779c7c368f102ed0c23","src/ctx.rs":"9bd92f1038962a8034450b64818cc7b5eaebacde2a229eec5b9cda3ec99c5ae4","src/endian.rs":"e3e0fcb99d0f71f739b6f0ea466a5d3479ed9c90f29269adb1aa2d725ac12af4","src/error.rs":"d91d332a87bde35738cc5915279fc0fde65301fe86ef98ec36126e1de9fd0474","src/greater.rs":"29d9736f9d35a0f92ca054c7a36878ade0a77b4e8ee27441c34cd81c6bdb68e6","src/leb128.rs":"eb71761d708f78c785e6dbe8d385fd90317d08369d1c3ac57d142ca7c0e09e9e","src/lesser.rs":"16fa2c3a737c126b7ac40117c960bc025fb418abc99559c244e8a5ae4348c730","src/lib.rs":"e9a1b9b0ee06ba39de6925f4bc23cb847c8ec3831ca37280c3660dc6d1b28826","src/pread.rs":"80eb931ad7340bba7e1a03a7cbef62c93537bdf4703e467210957d07b82f6489","src/pwrite.rs":"5384d97a57a245e057bca70bd3a386c2942c89f6f7555bcad498b348ee555543"},"package":"6ab8598aa408498679922eff7fa985c25d58a90771bd6be794434c5277eab1a6"}
\ No newline at end of file diff --git a/third_party/rust/scroll/CHANGELOG.md b/third_party/rust/scroll/CHANGELOG.md deleted file mode 100644 index bae87ee590..0000000000 --- a/third_party/rust/scroll/CHANGELOG.md +++ /dev/null @@ -1,17 +0,0 @@ -# Changelog -All notable changes to this project will be documented in this file. - -Before 1.0, this project does not adhere to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). - -## [0.10.0] - unreleased -### Added - - scroll is now 2018 compliant, thanks @lzutao: https://github.com/m4b/scroll/pull/49 - - scroll_derive now lives in scroll repo itself -### Removed - - BREAKING: removed units/size generics in SizeWith, thanks @willglynn: https://github.com/m4b/scroll/pull/45 - -## [0.9.1] - 2018-9-22 -### Added - - pread primitive references: https://github.com/m4b/scroll/pull/35 - - u128/i128 support: https://github.com/m4b/scroll/pull/32 - - CStr support: https://github.com/m4b/scroll/pull/30 diff --git a/third_party/rust/scroll/Cargo.lock b/third_party/rust/scroll/Cargo.lock deleted file mode 100644 index baf29fe049..0000000000 --- a/third_party/rust/scroll/Cargo.lock +++ /dev/null @@ -1,205 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "autocfg" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" - -[[package]] -name = "byteorder" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "const_fn" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b9d6de7f49e22cf97ad17fc4036ece69300032f45f78f30b4a4482cdc3f4a6" - -[[package]] -name = "crossbeam-channel" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1aaa739f95311c2c7887a76863f500026092fb1dce0161dab577e559ef3569d" -dependencies = [ - "cfg-if", - "const_fn", - "crossbeam-utils", - "lazy_static", - "memoffset", - "scopeguard", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d" -dependencies = [ - "autocfg", - "cfg-if", - "lazy_static", -] - -[[package]] -name = "either" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" - -[[package]] -name = "hermit-abi" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" -dependencies = [ - "libc", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89203f3fba0a3795506acaad8ebce3c80c0af93f994d5a1d7a0b1eeb23271929" - -[[package]] -name = "memoffset" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "proc-macro2" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" -dependencies = [ - "unicode-xid", -] - -[[package]] -name = "quote" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rayon" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674" -dependencies = [ - "autocfg", - "crossbeam-deque", - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "lazy_static", - "num_cpus", -] - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "scroll" -version = "0.11.0" -dependencies = [ - "byteorder", - "rayon", - "scroll_derive", -] - -[[package]] -name = "scroll_derive" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdbda6ac5cd1321e724fa9cee216f3a61885889b896f073b8f82322789c5250e" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "syn" -version = "1.0.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "unicode-xid" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" diff --git a/third_party/rust/scroll/Cargo.toml b/third_party/rust/scroll/Cargo.toml index 548be72db9..70e9e8d1c3 100644 --- a/third_party/rust/scroll/Cargo.toml +++ b/third_party/rust/scroll/Cargo.toml @@ -11,26 +11,37 @@ [package] edition = "2021" +rust-version = "1.63" name = "scroll" -version = "0.11.0" -authors = ["m4b <m4b.github.io@gmail.com>", "Ted Mielczarek <ted@mielczarek.org>"] +version = "0.12.0" +authors = [ + "m4b <m4b.github.io@gmail.com>", + "Ted Mielczarek <ted@mielczarek.org>", +] +include = [ + "src/**/*", + "Cargo.toml", + "LICENSE", + "README.md", +] description = "A suite of powerful, extensible, generic, endian-aware Read/Write traits for byte buffers" documentation = "https://docs.rs/scroll" readme = "README.md" -keywords = ["bytes", "endian", "immutable", "pread", "pwrite"] +keywords = [ + "bytes", + "endian", + "immutable", + "pread", + "pwrite", +] license = "MIT" repository = "https://github.com/m4b/scroll" -resolver = "2" + [dependencies.scroll_derive] -version = "0.11" +version = "0.12" optional = true -[dev-dependencies.byteorder] -version = "1" - -[dev-dependencies.rayon] -version = "1" [features] default = ["std"] -derive = ["scroll_derive"] +derive = ["dep:scroll_derive"] std = [] diff --git a/third_party/rust/scroll/README.md b/third_party/rust/scroll/README.md index 717fe6a234..50dde54d7e 100644 --- a/third_party/rust/scroll/README.md +++ b/third_party/rust/scroll/README.md @@ -1,4 +1,13 @@ - [![Build Status](https://travis-ci.org/m4b/scroll.svg?branch=master)](https://travis-ci.org/m4b/scroll) +[![Actions][actions-badge]][actions-url] +[![crates.io version][crates-scroll-badge]][crates-scroll] + +<!-- Badges' links --> + +[actions-badge]: https://github.com/m4b/scroll/workflows/CI/badge.svg?branch=master +[actions-url]: https://github.com/m4b/scroll/actions +[crates-scroll-badge]: https://img.shields.io/crates/v/scroll.svg +[crates-scroll]: https://crates.io/crates/scroll + ## Scroll - cast some magic ```text @@ -23,7 +32,7 @@ Add to your `Cargo.toml` ```toml, no_test [dependencies] -scroll = "0.10" +scroll = "0.11" ``` ### Overview diff --git a/third_party/rust/scroll/benches/bench.rs b/third_party/rust/scroll/benches/bench.rs deleted file mode 100644 index 0787dbe14b..0000000000 --- a/third_party/rust/scroll/benches/bench.rs +++ /dev/null @@ -1,157 +0,0 @@ -#![feature(test)] -extern crate test; - -use scroll::{Cread, Pread, LE}; -use test::black_box; - -#[bench] -fn bench_parallel_cread_with(b: &mut test::Bencher) { - use rayon::prelude::*; - let vec = vec![0u8; 1_000_000]; - let nums = vec![0usize; 500_000]; - b.iter(|| { - let data = black_box(&vec[..]); - nums.par_iter().for_each(|offset| { - let _: u16 = black_box(data.cread_with(*offset, LE)); - }); - }); - b.bytes = vec.len() as u64; -} - -#[bench] -fn bench_cread_vec(b: &mut test::Bencher) { - let vec = vec![0u8; 1_000_000]; - b.iter(|| { - let data = black_box(&vec[..]); - for val in data.chunks(2) { - let _: u16 = black_box(val.cread_with(0, LE)); - } - }); - b.bytes = vec.len() as u64; -} - -#[bench] -fn bench_cread(b: &mut test::Bencher) { - const NITER: i32 = 100_000; - b.iter(|| { - for _ in 1..NITER { - let data = black_box([1, 2]); - let _: u16 = black_box(data.cread(0)); - } - }); - b.bytes = 2 * NITER as u64; -} - -#[bench] -fn bench_pread_ctx_vec(b: &mut test::Bencher) { - let vec = vec![0u8; 1_000_000]; - b.iter(|| { - let data = black_box(&vec[..]); - for val in data.chunks(2) { - let _: Result<u16, _> = black_box(val.pread(0)); - } - }); - b.bytes = vec.len() as u64; -} - -#[bench] -fn bench_pread_with_unwrap(b: &mut test::Bencher) { - const NITER: i32 = 100_000; - b.iter(|| { - for _ in 1..NITER { - let data: &[u8] = &black_box([1, 2]); - let _: u16 = black_box(data.pread_with(0, LE).unwrap()); - } - }); - b.bytes = 2 * NITER as u64; -} - -#[bench] -fn bench_pread_vec(b: &mut test::Bencher) { - let vec = vec![0u8; 1_000_000]; - b.iter(|| { - let data = black_box(&vec[..]); - for val in data.chunks(2) { - let _: Result<u16, _> = black_box(val.pread_with(0, LE)); - } - }); - b.bytes = vec.len() as u64; -} - -#[bench] -fn bench_pread_unwrap(b: &mut test::Bencher) { - const NITER: i32 = 100_000; - b.iter(|| { - for _ in 1..NITER { - let data = black_box([1, 2]); - let _: u16 = black_box(data.pread(0)).unwrap(); - } - }); - b.bytes = 2 * NITER as u64; -} - -#[bench] -fn bench_gread_vec(b: &mut test::Bencher) { - let vec = vec![0u8; 1_000_000]; - b.iter(|| { - let data = black_box(&vec[..]); - for val in data.chunks(2) { - let mut offset = 0; - let _: Result<u16, _> = black_box(val.gread(&mut offset)); - } - }); - b.bytes = vec.len() as u64; -} - -#[bench] -fn bench_gread_unwrap(b: &mut test::Bencher) { - const NITER: i32 = 100_000; - b.iter(|| { - for _ in 1..NITER { - let data = black_box([1, 2]); - let mut offset = 0; - let _: u16 = black_box(data.gread_with(&mut offset, LE).unwrap()); - } - }); - b.bytes = 2 * NITER as u64; -} - -#[bench] -fn bench_parallel_pread_with(b: &mut test::Bencher) { - use rayon::prelude::*; - let vec = vec![0u8; 1_000_000]; - let nums = vec![0usize; 500_000]; - b.iter(|| { - let data = black_box(&vec[..]); - nums.par_iter().for_each(|offset| { - let _: Result<u16, _> = black_box(data.pread_with(*offset, LE)); - }); - }); - b.bytes = vec.len() as u64; -} - -#[bench] -fn bench_byteorder_vec(b: &mut test::Bencher) { - use byteorder::ReadBytesExt; - let vec = vec![0u8; 1_000_000]; - b.iter(|| { - let data = black_box(&vec[..]); - for mut val in data.chunks(2) { - let _: Result<u16, _> = black_box(val.read_u16::<byteorder::LittleEndian>()); - } - }); - b.bytes = vec.len() as u64; -} - -#[bench] -fn bench_byteorder(b: &mut test::Bencher) { - use byteorder::ByteOrder; - const NITER: i32 = 100_000; - b.iter(|| { - for _ in 1..NITER { - let data = black_box([1, 2]); - let _: u16 = black_box(byteorder::LittleEndian::read_u16(&data)); - } - }); - b.bytes = 2 * NITER as u64; -} diff --git a/third_party/rust/scroll/examples/data_ctx.rs b/third_party/rust/scroll/examples/data_ctx.rs deleted file mode 100644 index 667f4b18f0..0000000000 --- a/third_party/rust/scroll/examples/data_ctx.rs +++ /dev/null @@ -1,24 +0,0 @@ -use scroll::{ctx, Endian, Pread, BE}; - -#[derive(Debug)] -struct Data<'a> { - name: &'a str, - id: u32, -} - -impl<'a> ctx::TryFromCtx<'a, Endian> for Data<'a> { - type Error = scroll::Error; - fn try_from_ctx(src: &'a [u8], endian: Endian) -> Result<(Self, usize), Self::Error> { - let name = src.pread::<&'a str>(0)?; - let id = src.pread_with(name.len() + 1, endian)?; - Ok((Data { name: name, id: id }, name.len() + 4)) - } -} - -fn main() { - let bytes = b"UserName\x00\x01\x02\x03\x04"; - let data = bytes.pread_with::<Data>(0, BE).unwrap(); - assert_eq!(data.id, 0x01020304); - assert_eq!(data.name.to_string(), "UserName".to_string()); - println!("Data: {:?}", &data); -} diff --git a/third_party/rust/scroll/src/ctx.rs b/third_party/rust/scroll/src/ctx.rs index 1f982b82fa..e24d2dc506 100644 --- a/third_party/rust/scroll/src/ctx.rs +++ b/third_party/rust/scroll/src/ctx.rs @@ -180,17 +180,14 @@ //! } //! ``` -use core::mem::size_of; -use core::mem::transmute; +use core::mem::{size_of, MaybeUninit}; use core::ptr::copy_nonoverlapping; -use core::result; -use core::str; - +use core::{result, str}; #[cfg(feature = "std")] use std::ffi::{CStr, CString}; use crate::endian::Endian; -use crate::error; +use crate::{error, Pread, Pwrite}; /// A trait for measuring how large something is; for a byte sequence, it will be its length. pub trait MeasureWith<Ctx> { @@ -240,18 +237,14 @@ impl Default for StrCtx { impl StrCtx { pub fn len(&self) -> usize { - match *self { + match self { StrCtx::Delimiter(_) | StrCtx::DelimiterUntil(_, _) => 1, StrCtx::Length(_) => 0, } } pub fn is_empty(&self) -> bool { - if let StrCtx::Length(_) = *self { - true - } else { - false - } + matches!(self, StrCtx::Length(_)) } } @@ -267,6 +260,7 @@ pub trait FromCtx<Ctx: Copy = (), This: ?Sized = [u8]> { /// `[u8]`), then you need to implement this trait /// /// ```rust +/// ##[cfg(feature = "std")] { /// use scroll::{self, ctx, Pread}; /// #[derive(Debug, PartialEq, Eq)] /// pub struct Foo(u16); @@ -286,6 +280,7 @@ pub trait FromCtx<Ctx: Copy = (), This: ?Sized = [u8]> { /// /// let foo2 = bytes.pread_with::<Foo>(0, scroll::BE).unwrap(); /// assert_eq!(Foo(0xdeadu16), foo2); +/// # } /// ``` /// /// # Advanced: Using Your Own Error in `TryFromCtx` @@ -350,6 +345,7 @@ pub trait IntoCtx<Ctx: Copy = (), This: ?Sized = [u8]>: Sized { /// To implement writing into an arbitrary byte buffer, implement `TryIntoCtx` /// # Example /// ```rust +/// ##[cfg(feature = "std")] { /// use scroll::{self, ctx, LE, Endian, Pwrite}; /// #[derive(Debug, PartialEq, Eq)] /// pub struct Foo(u16); @@ -369,6 +365,7 @@ pub trait IntoCtx<Ctx: Copy = (), This: ?Sized = [u8]>: Sized { /// /// let mut bytes: [u8; 4] = [0, 0, 0, 0]; /// bytes.pwrite_with(Foo(0x7f), 1, LE).unwrap(); +/// # } /// ``` pub trait TryIntoCtx<Ctx: Copy = (), This: ?Sized = [u8]>: Sized { type Error; @@ -403,13 +400,14 @@ macro_rules! signed_to_unsigned { macro_rules! write_into { ($typ:ty, $size:expr, $n:expr, $dst:expr, $endian:expr) => {{ + assert!($dst.len() >= $size); + let bytes = if $endian.is_little() { + $n.to_le() + } else { + $n.to_be() + } + .to_ne_bytes(); unsafe { - assert!($dst.len() >= $size); - let bytes = transmute::<$typ, [u8; $size]>(if $endian.is_little() { - $n.to_le() - } else { - $n.to_be() - }); copy_nonoverlapping((&bytes).as_ptr(), $dst.as_mut_ptr(), $size); } }}; @@ -570,12 +568,12 @@ macro_rules! from_ctx_float_impl { &mut data as *mut signed_to_unsigned!($typ) as *mut u8, $size, ); - transmute(if le.is_little() { - data.to_le() - } else { - data.to_be() - }) } + $typ::from_bits(if le.is_little() { + data.to_le() + } else { + data.to_be() + }) } } impl<'a> TryFromCtx<'a, Endian> for $typ @@ -621,13 +619,7 @@ macro_rules! into_ctx_float_impl { #[inline] fn into_ctx(self, dst: &mut [u8], le: Endian) { assert!(dst.len() >= $size); - write_into!( - signed_to_unsigned!($typ), - $size, - transmute::<$typ, signed_to_unsigned!($typ)>(self), - dst, - le - ); + write_into!(signed_to_unsigned!($typ), $size, self.to_bits(), dst, le); } } impl<'a> IntoCtx<Endian> for &'a $typ { @@ -725,7 +717,7 @@ impl<'a> TryIntoCtx for &'a [u8] { let src_len = self.len() as isize; let dst_len = dst.len() as isize; // if src_len < 0 || dst_len < 0 || offset < 0 { - // return Err(error::Error::BadOffset(format!("requested operation has negative casts: src len: {} dst len: {} offset: {}", src_len, dst_len, offset)).into()) + // return Err(error::Error::BadOffset(format!("requested operation has negative casts: src len: {src_len} dst len: {dst_len} offset: {offset}")).into()) // } if src_len > dst_len { Err(error::Error::TooBig { @@ -789,6 +781,56 @@ impl<'a> TryFromCtx<'a, usize> for &'a [u8] { } } +impl<'a, Ctx: Copy, T: TryFromCtx<'a, Ctx, Error = error::Error>, const N: usize> + TryFromCtx<'a, Ctx> for [T; N] +{ + type Error = error::Error; + fn try_from_ctx(src: &'a [u8], ctx: Ctx) -> Result<(Self, usize), Self::Error> { + let mut offset = 0; + + let mut buf: [MaybeUninit<T>; N] = core::array::from_fn(|_| MaybeUninit::uninit()); + + let mut error_ctx = None; + for (idx, element) in buf.iter_mut().enumerate() { + match src.gread_with::<T>(&mut offset, ctx) { + Ok(val) => { + *element = MaybeUninit::new(val); + } + Err(e) => { + error_ctx = Some((e, idx)); + break; + } + } + } + if let Some((e, idx)) = error_ctx { + for element in &mut buf[0..idx].iter_mut() { + // SAFETY: Any element upto idx must have already been initialized, since + // we iterate until we encounter an error. + unsafe { + element.assume_init_drop(); + } + } + Err(e) + } else { + // SAFETY: we initialized each element above by preading them out, correctness + // of the initialized element is guaranted by pread itself + Ok((buf.map(|element| unsafe { element.assume_init() }), offset)) + } + } +} +impl<Ctx: Copy, T: TryIntoCtx<Ctx, Error = error::Error>, const N: usize> TryIntoCtx<Ctx> + for [T; N] +{ + type Error = error::Error; + fn try_into_ctx(self, buf: &mut [u8], ctx: Ctx) -> Result<usize, Self::Error> { + let mut offset = 0; + for element in self { + buf.gwrite_with(element, &mut offset, ctx)?; + } + Ok(offset) + } +} + #[cfg(feature = "std")] impl<'a> TryFromCtx<'a> for &'a CStr { type Error = error::Error; @@ -863,11 +905,11 @@ impl TryIntoCtx for CString { // } #[cfg(test)] +#[cfg(feature = "std")] mod tests { use super::*; #[test] - #[cfg(feature = "std")] fn parse_a_cstr() { let src = CString::new("Hello World").unwrap(); let as_bytes = src.as_bytes_with_nul(); @@ -879,7 +921,6 @@ mod tests { } #[test] - #[cfg(feature = "std")] fn round_trip_a_c_str() { let src = CString::new("Hello World").unwrap(); let src = src.as_c_str(); diff --git a/third_party/rust/scroll/src/endian.rs b/third_party/rust/scroll/src/endian.rs index 06d7a1dc1c..7b83c348d5 100644 --- a/third_party/rust/scroll/src/endian.rs +++ b/third_party/rust/scroll/src/endian.rs @@ -43,9 +43,6 @@ impl Endian { } #[inline] pub fn is_little(&self) -> bool { - match *self { - LE => true, - _ => false, - } + *self == LE } } diff --git a/third_party/rust/scroll/src/error.rs b/third_party/rust/scroll/src/error.rs index 7740254774..1b68c2e4c7 100644 --- a/third_party/rust/scroll/src/error.rs +++ b/third_party/rust/scroll/src/error.rs @@ -1,10 +1,7 @@ use core::fmt::{self, Display}; use core::result; - -#[cfg(feature = "std")] -use std::error; #[cfg(feature = "std")] -use std::io; +use std::{error, io}; #[derive(Debug)] /// A custom Scroll error @@ -20,18 +17,19 @@ pub enum Error { size: usize, msg: &'static str, }, + /// A custom Scroll error for reporting messages to clients. + /// For no-std, use [`Error::BadInput`] with a static string. #[cfg(feature = "std")] - /// A custom Scroll error for reporting messages to clients Custom(String), - #[cfg(feature = "std")] /// Returned when IO based errors are encountered + #[cfg(feature = "std")] IO(io::Error), } #[cfg(feature = "std")] impl error::Error for Error { fn description(&self) -> &str { - match *self { + match self { Error::TooBig { .. } => "TooBig", Error::BadOffset(_) => "BadOffset", Error::BadInput { .. } => "BadInput", @@ -40,7 +38,7 @@ impl error::Error for Error { } } fn cause(&self) -> Option<&dyn error::Error> { - match *self { + match self { Error::TooBig { .. } => None, Error::BadOffset(_) => None, Error::BadInput { .. } => None, @@ -59,23 +57,23 @@ impl From<io::Error> for Error { impl Display for Error { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - match *self { + match self { Error::TooBig { ref size, ref len } => { - write!(fmt, "type is too big ({}) for {}", size, len) + write!(fmt, "type is too big ({size}) for {len}") } Error::BadOffset(ref offset) => { - write!(fmt, "bad offset {}", offset) + write!(fmt, "bad offset {offset}") } Error::BadInput { ref msg, ref size } => { - write!(fmt, "bad input {} ({})", msg, size) + write!(fmt, "bad input {msg} ({size})") } #[cfg(feature = "std")] Error::Custom(ref msg) => { - write!(fmt, "{}", msg) + write!(fmt, "{msg}") } #[cfg(feature = "std")] Error::IO(ref err) => { - write!(fmt, "{}", err) + write!(fmt, "{err}") } } } diff --git a/third_party/rust/scroll/src/leb128.rs b/third_party/rust/scroll/src/leb128.rs index 43f50b95f1..eceec6d166 100644 --- a/third_party/rust/scroll/src/leb128.rs +++ b/third_party/rust/scroll/src/leb128.rs @@ -1,9 +1,8 @@ -use crate::ctx::TryFromCtx; -use crate::error; -use crate::Pread; use core::convert::{AsRef, From}; -use core::result; -use core::u8; +use core::{result, u8}; + +use crate::ctx::TryFromCtx; +use crate::{error, Pread}; #[derive(Debug, PartialEq, Copy, Clone)] /// An unsigned leb128 integer @@ -184,21 +183,24 @@ mod tests { let buf = [2u8 | CONTINUATION_BIT, 1]; let bytes = &buf[..]; let num = bytes.pread::<Uleb128>(0).unwrap(); - println!("num: {:?}", &num); + #[cfg(feature = "std")] + println!("num: {num:?}"); assert_eq!(130u64, num.into()); assert_eq!(num.size(), 2); let buf = [0x00, 0x01]; let bytes = &buf[..]; let num = bytes.pread::<Uleb128>(0).unwrap(); - println!("num: {:?}", &num); + #[cfg(feature = "std")] + println!("num: {num:?}"); assert_eq!(0u64, num.into()); assert_eq!(num.size(), 1); let buf = [0x21]; let bytes = &buf[..]; let num = bytes.pread::<Uleb128>(0).unwrap(); - println!("num: {:?}", &num); + #[cfg(feature = "std")] + println!("num: {num:?}"); assert_eq!(0x21u64, num.into()); assert_eq!(num.size(), 1); } diff --git a/third_party/rust/scroll/src/lesser.rs b/third_party/rust/scroll/src/lesser.rs index 46ef4c5b11..636bf2553e 100644 --- a/third_party/rust/scroll/src/lesser.rs +++ b/third_party/rust/scroll/src/lesser.rs @@ -1,6 +1,7 @@ -use crate::ctx::{FromCtx, IntoCtx, SizeWith}; use std::io::{Read, Result, Write}; +use crate::ctx::{FromCtx, IntoCtx, SizeWith}; + /// An extension trait to `std::io::Read` streams; mainly targeted at reading primitive types with /// a known size. /// @@ -104,8 +105,8 @@ pub trait IOread<Ctx: Copy>: Read { fn ioread_with<N: FromCtx<Ctx> + SizeWith<Ctx>>(&mut self, ctx: Ctx) -> Result<N> { let mut scratch = [0u8; 256]; let size = N::size_with(&ctx); - let mut buf = &mut scratch[0..size]; - self.read_exact(&mut buf)?; + let buf = &mut scratch[0..size]; + self.read_exact(buf)?; Ok(N::from_ctx(buf, ctx)) } } diff --git a/third_party/rust/scroll/src/lib.rs b/third_party/rust/scroll/src/lib.rs index dcb58e7564..2740648517 100644 --- a/third_party/rust/scroll/src/lib.rs +++ b/third_party/rust/scroll/src/lib.rs @@ -119,6 +119,7 @@ //! [FromCtx](ctx/trait.FromCtx.html) and [SizeWith](ctx/trait.SizeWith.html). //! //! ```rust +//! ##[cfg(feature = "std")] { //! use std::io::Cursor; //! use scroll::{IOread, ctx, Endian}; //! let bytes = [0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0xef,0xbe,0x00,0x00,]; @@ -139,12 +140,14 @@ //! // read/written, e.g. switching between ELF32 or ELF64 at runtime. //! let size = <u64 as ctx::SizeWith<Endian>>::size_with(&Endian::Little) as u64; //! assert_eq!(prev + size, after); +//! # } //! ``` //! //! In the same vein as IOread we can use IOwrite to write a type to anything implementing //! `std::io::Write`: //! //! ```rust +//! ##[cfg(feature = "std")] { //! use std::io::Cursor; //! use scroll::{IOwrite}; //! @@ -155,6 +158,7 @@ //! cursor.iowrite_with(0xdeadbeef as u32, scroll::BE).unwrap(); //! //! assert_eq!(cursor.into_inner(), [0xde, 0xad, 0xbe, 0xef, 0x0]); +//! # } //! ``` //! //! ## Complex use cases @@ -249,8 +253,7 @@ pub use crate::pwrite::*; #[doc(hidden)] pub mod export { - pub use ::core::mem; - pub use ::core::result; + pub use ::core::{mem, result}; } #[allow(unused)] @@ -267,7 +270,6 @@ doc_comment!(include_str!("../README.md")); #[cfg(test)] mod tests { - #[allow(overflowing_literals)] use super::LE; #[test] @@ -355,36 +357,48 @@ mod tests { let bytes: [u8; 2] = [0x2e, 0x0]; let b = &bytes[..]; let s: &str = b.pread(0).unwrap(); - println!("str: {}", s); + #[cfg(feature = "std")] + println!("str: {s}"); assert_eq!(s.len(), bytes[..].len() - 1); let bytes: &[u8] = b"hello, world!\0some_other_things"; let hello_world: &str = bytes.pread_with(0, StrCtx::Delimiter(NULL)).unwrap(); - println!("{:?}", &hello_world); + #[cfg(feature = "std")] + println!("{hello_world:?}"); assert_eq!(hello_world.len(), 13); let hello: &str = bytes.pread_with(0, StrCtx::Delimiter(SPACE)).unwrap(); - println!("{:?}", &hello); + #[cfg(feature = "std")] + println!("{hello:?}"); assert_eq!(hello.len(), 6); // this could result in underflow so we just try it let _error = bytes.pread_with::<&str>(6, StrCtx::Delimiter(SPACE)); let error = bytes.pread_with::<&str>(7, StrCtx::Delimiter(SPACE)); - println!("{:?}", &error); + #[cfg(feature = "std")] + println!("{error:?}"); assert!(error.is_ok()); } + /// In this test, we are testing preading + /// at length boundaries. + /// In the past, this test was supposed to test failures for `hello_world`. + /// Since PR#94, this test is unwrapping as we exploit + /// the fact that if you do &x[x.len()..] you get an empty slice. #[test] fn pread_str_weird() { use super::ctx::*; use super::Pread; let bytes: &[u8] = b""; let hello_world = bytes.pread_with::<&str>(0, StrCtx::Delimiter(NULL)); - println!("1 {:?}", &hello_world); - assert_eq!(hello_world.is_err(), true); + #[cfg(feature = "std")] + println!("1 {hello_world:?}"); + assert!(hello_world.unwrap().is_empty()); let error = bytes.pread_with::<&str>(7, StrCtx::Delimiter(SPACE)); - println!("2 {:?}", &error); + #[cfg(feature = "std")] + println!("2 {error:?}"); assert!(error.is_err()); let bytes: &[u8] = b"\0"; let null = bytes.pread::<&str>(0).unwrap(); - println!("3 {:?}", &null); + #[cfg(feature = "std")] + println!("3 {null:?}"); assert_eq!(null.len(), 0); } @@ -413,8 +427,7 @@ mod tests { assert_eq!(bytes, "bytes"); } - use std::error; - use std::fmt::{self, Display}; + use core::fmt::{self, Display}; #[derive(Debug)] pub struct ExternalError {} @@ -425,11 +438,12 @@ mod tests { } } - impl error::Error for ExternalError { + #[cfg(feature = "std")] + impl std::error::Error for ExternalError { fn description(&self) -> &str { "ExternalError" } - fn cause(&self) -> Option<&dyn error::Error> { + fn cause(&self) -> Option<&dyn std::error::Error> { None } } @@ -451,7 +465,7 @@ mod tests { fn try_into_ctx(self, this: &mut [u8], le: super::Endian) -> Result<usize, Self::Error> { use super::Pwrite; if this.len() < 2 { - return Err((ExternalError {}).into()); + return Err(ExternalError {}); } this.pwrite_with(self.0, 0, le)?; Ok(2) @@ -463,7 +477,7 @@ mod tests { fn try_from_ctx(this: &'a [u8], le: super::Endian) -> Result<(Self, usize), Self::Error> { use super::Pread; if this.len() > 2 { - return Err((ExternalError {}).into()); + return Err(ExternalError {}); } let n = this.pread_with(0, le)?; Ok((Foo(n), 2)) @@ -499,7 +513,7 @@ mod tests { let mut offset = 0; let deadbeef: $typ = bytes.gread_with(&mut offset, LE).unwrap(); assert_eq!(deadbeef, $deadbeef as $typ); - assert_eq!(offset, ::std::mem::size_of::<$typ>()); + assert_eq!(offset, ::core::mem::size_of::<$typ>()); } }; } @@ -518,7 +532,7 @@ mod tests { let mut offset = 0; let deadbeef: $typ = bytes.gread_with(&mut offset, LE).unwrap(); assert_eq!(deadbeef, $deadbeef as $typ); - assert_eq!(offset, ::std::mem::size_of::<$typ>()); + assert_eq!(offset, ::core::mem::size_of::<$typ>()); } }; } @@ -537,8 +551,8 @@ mod tests { let o2 = &mut 0; let val: $typ = buffer.gread_with(o2, LE).unwrap(); assert_eq!(val, $val); - assert_eq!(*offset, ::std::mem::size_of::<$typ>()); - assert_eq!(*o2, ::std::mem::size_of::<$typ>()); + assert_eq!(*offset, ::core::mem::size_of::<$typ>()); + assert_eq!(*o2, ::core::mem::size_of::<$typ>()); assert_eq!(*o2, *offset); buffer.gwrite_with($val.clone(), offset, BE).unwrap(); let val: $typ = buffer.gread_with(o2, BE).unwrap(); @@ -612,16 +626,17 @@ mod tests { let res = b.gread_with::<&str>(offset, StrCtx::Length(3)); assert!(res.is_err()); *offset = 0; - let astring: [u8; 3] = [0x45, 042, 0x44]; + let astring: [u8; 3] = [0x45, 0x42, 0x44]; let string = astring.gread_with::<&str>(offset, StrCtx::Length(2)); match &string { - &Ok(_) => {} - &Err(ref err) => { - println!("{}", &err); + Ok(_) => {} + Err(_err) => { + #[cfg(feature = "std")] + println!("{_err}"); panic!(); } } - assert_eq!(string.unwrap(), "E*"); + assert_eq!(string.unwrap(), "EB"); *offset = 0; let bytes2: &[u8] = b.gread_with(offset, 2).unwrap(); assert_eq!(*offset, 2); diff --git a/third_party/rust/scroll/src/pread.rs b/third_party/rust/scroll/src/pread.rs index 72ba877054..15bf1426be 100644 --- a/third_party/rust/scroll/src/pread.rs +++ b/third_party/rust/scroll/src/pread.rs @@ -20,6 +20,11 @@ use crate::error; /// over chunks of memory or any other indexable type — but scroll does come with a set of powerful /// blanket implementations for data being a continous block of byte-addressable memory. /// +/// Note that in the particular case of the implementation of `Pread` for `[u8]`, +/// reading it at the length boundary of that slice will cause to read from an empty slice. +/// i.e. we make use of the fact that `&bytes[bytes.len()..]` will return an empty slice, rather +/// than returning an error. In the past, scroll returned an offset error. +/// /// Pread provides two main groups of functions: pread and gread. /// /// `pread` is the basic function that simply extracts a given type from a given data store - either @@ -167,7 +172,7 @@ impl<Ctx: Copy, E: From<error::Error>> Pread<Ctx, E> for [u8] { ctx: Ctx, ) -> result::Result<N, E> { let start = *offset; - if start >= self.len() { + if start > self.len() { return Err(error::Error::BadOffset(start).into()); } N::try_from_ctx(&self[start..], ctx).map(|(n, size)| { diff --git a/third_party/rust/scroll/src/pwrite.rs b/third_party/rust/scroll/src/pwrite.rs index ab6d96157d..7a07f2daba 100644 --- a/third_party/rust/scroll/src/pwrite.rs +++ b/third_party/rust/scroll/src/pwrite.rs @@ -19,6 +19,13 @@ use crate::error; /// with 'read' switched for 'write' and 'From' switched with 'Into' so if you haven't yet you /// should read the documentation of `Pread` first. /// +/// As with `Pread`, note that in the particular case of the implementation of `Pwrite` for `[u8]`, +/// writing it at the length boundary of that slice will cause to write in an empty slice. +/// i.e. we make use of the fact that `&bytes[bytes.len()..]` will return an empty slice, rather +/// than returning an error. In the past, scroll returned an offset error. +/// In this case, this is relevant if you are writing an empty slice inside an empty slice and +/// expected this to work. +/// /// Unless you need to implement your own data store — that is either can't convert to `&[u8]` or /// have a data that does not expose a `&mut [u8]` — you will probably want to implement /// [TryIntoCtx](ctx/trait.TryIntoCtx.html) on your Rust types to be written. @@ -87,7 +94,7 @@ impl<Ctx: Copy, E: From<error::Error>> Pwrite<Ctx, E> for [u8] { offset: usize, ctx: Ctx, ) -> result::Result<usize, E> { - if offset >= self.len() { + if offset > self.len() { return Err(error::Error::BadOffset(offset).into()); } let dst = &mut self[offset..]; diff --git a/third_party/rust/scroll/tests/api.rs b/third_party/rust/scroll/tests/api.rs deleted file mode 100644 index e10726f22a..0000000000 --- a/third_party/rust/scroll/tests/api.rs +++ /dev/null @@ -1,292 +0,0 @@ -// this exists primarily to test various API usages of scroll; e.g., must compile - -// guard against potential undefined behaviour when borrowing from -// packed structs. See https://github.com/rust-lang/rust/issues/46043 -#![deny(unaligned_references)] - -// #[macro_use] extern crate scroll_derive; - -use scroll::ctx::SizeWith; -use scroll::{ctx, Cread, Pread, Result}; -use std::ops::{Deref, DerefMut}; - -#[derive(Default)] -pub struct Section<'a> { - pub sectname: [u8; 16], - pub segname: [u8; 16], - pub addr: u64, - pub size: u64, - pub offset: u32, - pub align: u32, - pub reloff: u32, - pub nreloc: u32, - pub flags: u32, - pub data: &'a [u8], -} - -impl<'a> Section<'a> { - pub fn name(&self) -> Result<&str> { - self.sectname.pread::<&str>(0) - } - pub fn segname(&self) -> Result<&str> { - self.segname.pread::<&str>(0) - } -} - -impl<'a> ctx::SizeWith for Section<'a> { - fn size_with(_ctx: &()) -> usize { - 4 - } -} - -#[repr(C)] -// renable when scroll_derive Pread/Pwrite matches -//#[derive(Debug, Clone, Copy, Pread, Pwrite)] -#[derive(Debug, Clone, Copy)] -pub struct Section32 { - pub sectname: [u8; 16], - pub segname: [u8; 16], - pub addr: u32, - pub size: u32, - pub offset: u32, - pub align: u32, - pub reloff: u32, - pub nreloc: u32, - pub flags: u32, - pub reserved1: u32, - pub reserved2: u32, -} - -impl<'a> ctx::TryFromCtx<'a, ()> for Section<'a> { - type Error = scroll::Error; - fn try_from_ctx( - _bytes: &'a [u8], - _ctx: (), - ) -> ::std::result::Result<(Self, usize), Self::Error> { - let section = Section::default(); - Ok((section, ::std::mem::size_of::<Section>())) - } -} - -pub struct Segment<'a> { - pub cmd: u32, - pub cmdsize: u32, - pub segname: [u8; 16], - pub vmaddr: u64, - pub vmsize: u64, - pub fileoff: u64, - pub filesize: u64, - pub maxprot: u32, - pub initprot: u32, - pub nsects: u32, - pub flags: u32, - pub data: &'a [u8], - offset: usize, - raw_data: &'a [u8], -} - -impl<'a> Segment<'a> { - pub fn name(&self) -> Result<&str> { - Ok(self.segname.pread::<&str>(0)?) - } - pub fn sections(&self) -> Result<Vec<Section<'a>>> { - let nsects = self.nsects as usize; - let mut sections = Vec::with_capacity(nsects); - let offset = &mut (self.offset + Self::size_with(&())); - let _size = Section::size_with(&()); - let raw_data: &'a [u8] = self.raw_data; - for _ in 0..nsects { - let section = raw_data.gread_with::<Section<'a>>(offset, ())?; - sections.push(section); - //offset += size; - } - Ok(sections) - } -} - -impl<'a> ctx::SizeWith for Segment<'a> { - fn size_with(_ctx: &()) -> usize { - 4 - } -} - -pub struct Segments<'a> { - pub segments: Vec<Segment<'a>>, -} - -impl<'a> Deref for Segments<'a> { - type Target = Vec<Segment<'a>>; - fn deref(&self) -> &Self::Target { - &self.segments - } -} - -impl<'a> DerefMut for Segments<'a> { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.segments - } -} - -impl<'a> Segments<'a> { - pub fn new() -> Self { - Segments { - segments: Vec::new(), - } - } - pub fn sections(&self) -> Result<Vec<Vec<Section<'a>>>> { - let mut sections = Vec::new(); - for segment in &self.segments { - sections.push(segment.sections()?); - } - Ok(sections) - } -} - -fn lifetime_passthrough_<'a>(segments: &Segments<'a>, section_name: &str) -> Option<&'a [u8]> { - let segment_name = "__TEXT"; - for segment in &segments.segments { - if let Ok(name) = segment.name() { - println!("segment.name: {}", name); - if name == segment_name { - if let Ok(sections) = segment.sections() { - for section in sections { - let sname = section.name().unwrap(); - println!("section.name: {}", sname); - if section_name == sname { - return Some(section.data); - } - } - } - } - } - } - None -} - -#[test] -fn lifetime_passthrough() { - let segments = Segments::new(); - let _res = lifetime_passthrough_(&segments, "__text"); - assert!(true) -} - -#[derive(Default)] -#[repr(packed)] -struct Foo { - foo: i64, - bar: u32, -} - -impl scroll::ctx::FromCtx<scroll::Endian> for Foo { - fn from_ctx(bytes: &[u8], ctx: scroll::Endian) -> Self { - Foo { - foo: bytes.cread_with::<i64>(0, ctx), - bar: bytes.cread_with::<u32>(8, ctx), - } - } -} - -impl scroll::ctx::SizeWith<scroll::Endian> for Foo { - fn size_with(_: &scroll::Endian) -> usize { - ::std::mem::size_of::<Foo>() - } -} - -#[test] -fn ioread_api() { - use scroll::{IOread, LE}; - use std::io::Cursor; - let bytes_ = [ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0xbe, 0x00, 0x00, - ]; - let mut bytes = Cursor::new(bytes_); - let foo = bytes.ioread_with::<i64>(LE).unwrap(); - let bar = bytes.ioread_with::<u32>(LE).unwrap(); - assert_eq!(foo, 1); - assert_eq!(bar, 0xbeef); - let error = bytes.ioread_with::<f64>(LE); - assert!(error.is_err()); - let mut bytes = Cursor::new(bytes_); - let foo_ = bytes.ioread_with::<Foo>(LE).unwrap(); - assert_eq!({ foo_.foo }, foo); - assert_eq!({ foo_.bar }, bar); -} - -#[repr(packed)] -struct Bar { - foo: i32, - bar: u32, -} - -impl scroll::ctx::FromCtx<scroll::Endian> for Bar { - fn from_ctx(bytes: &[u8], ctx: scroll::Endian) -> Self { - Bar { - foo: bytes.cread_with(0, ctx), - bar: bytes.cread_with(4, ctx), - } - } -} - -#[test] -fn cread_api() { - use scroll::{Cread, LE}; - let bytes = [ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0xbe, 0x00, 0x00, - ]; - let foo = bytes.cread_with::<u64>(0, LE); - let bar = bytes.cread_with::<u32>(8, LE); - assert_eq!(foo, 1); - assert_eq!(bar, 0xbeef); -} - -#[test] -fn cread_api_customtype() { - use scroll::{Cread, LE}; - let bytes = [0xff, 0xff, 0xff, 0xff, 0xef, 0xbe, 0xad, 0xde]; - let bar = &bytes[..].cread_with::<Bar>(0, LE); - assert_eq!({ bar.foo }, -1); - assert_eq!({ bar.bar }, 0xdeadbeef); -} - -#[test] -#[should_panic] -fn cread_api_badindex() { - use scroll::Cread; - let bytes = [ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0xbe, 0xad, 0xde, - ]; - let _foo = bytes.cread::<i64>(1_000_000); -} - -#[test] -fn cwrite_api() { - use scroll::Cread; - use scroll::Cwrite; - let mut bytes = [0x0; 16]; - bytes.cwrite::<u64>(42, 0); - bytes.cwrite::<u32>(0xdeadbeef, 8); - assert_eq!(bytes.cread::<u64>(0), 42); - assert_eq!(bytes.cread::<u32>(8), 0xdeadbeef); -} - -impl scroll::ctx::IntoCtx<scroll::Endian> for Bar { - fn into_ctx(self, bytes: &mut [u8], ctx: scroll::Endian) { - use scroll::Cwrite; - bytes.cwrite_with(self.foo, 0, ctx); - bytes.cwrite_with(self.bar, 4, ctx); - } -} - -#[test] -fn cwrite_api_customtype() { - use scroll::{Cread, Cwrite}; - let bar = Bar { - foo: -1, - bar: 0xdeadbeef, - }; - let mut bytes = [0x0; 16]; - let _ = &bytes[..].cwrite::<Bar>(bar, 0); - let bar = bytes.cread::<Bar>(0); - assert_eq!({ bar.foo }, -1); - assert_eq!({ bar.bar }, 0xdeadbeef); -} |