summaryrefslogtreecommitdiffstats
path: root/third_party/rust/scroll
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/scroll')
-rw-r--r--third_party/rust/scroll/.cargo-checksum.json2
-rw-r--r--third_party/rust/scroll/CHANGELOG.md17
-rw-r--r--third_party/rust/scroll/Cargo.lock205
-rw-r--r--third_party/rust/scroll/Cargo.toml33
-rw-r--r--third_party/rust/scroll/README.md13
-rw-r--r--third_party/rust/scroll/benches/bench.rs157
-rw-r--r--third_party/rust/scroll/examples/data_ctx.rs24
-rw-r--r--third_party/rust/scroll/src/ctx.rs107
-rw-r--r--third_party/rust/scroll/src/endian.rs5
-rw-r--r--third_party/rust/scroll/src/error.rs26
-rw-r--r--third_party/rust/scroll/src/leb128.rs18
-rw-r--r--third_party/rust/scroll/src/lesser.rs7
-rw-r--r--third_party/rust/scroll/src/lib.rs67
-rw-r--r--third_party/rust/scroll/src/pread.rs7
-rw-r--r--third_party/rust/scroll/src/pwrite.rs9
-rw-r--r--third_party/rust/scroll/tests/api.rs292
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);
-}