diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-07-07 05:05:18 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-07-07 05:05:18 +0000 |
commit | 9f6d6ab18021c7f107eeda2ddd4d0d546e132727 (patch) | |
tree | ce2b37828d20a47e3596a5c787f37fa94f262b4d | |
parent | 45fbe72b9f3af251c0e7c914b18ebfc91d45949f (diff) | |
parent | c70033002276d6d635577e67664e6b5b4d295acb (diff) | |
download | flate2-9f6d6ab18021c7f107eeda2ddd4d0d546e132727.tar.gz |
Snap for 10453563 from c70033002276d6d635577e67664e6b5b4d295acb to mainline-os-statsd-releaseaml_sta_341710000aml_sta_341615000aml_sta_341511040aml_sta_341410000aml_sta_341311010aml_sta_341114000aml_sta_341111000aml_sta_341010020aml_sta_340912000aml_sta_340911000aml_net_341111030android14-mainline-os-statsd-release
Change-Id: Ie7a8149bb627b3cc183f2e813b0fe81d760bbccb
37 files changed, 576 insertions, 782 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index 551b999..bfa7c9d 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json @@ -1,5 +1,6 @@ { "git": { - "sha1": "63ecb8c0407c619c7a20529699b89369061ece88" - } -} + "sha1": "8431d9e0c0fdaea16c4643c723631223802b2c86" + }, + "path_in_vcs": "" +}
\ No newline at end of file diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 485df8d..9cdaa50 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -23,10 +23,10 @@ jobs: os: macos-latest rust: stable - build: windows - os: windows-latest + os: windows-2019 rust: stable - build: mingw - os: windows-latest + os: windows-2019 rust: stable-x86_64-gnu steps: - uses: actions/checkout@master @@ -37,13 +37,13 @@ jobs: - run: rustdoc --test README.md -L target/debug/deps --extern flate2=target/debug/libflate2.rlib --edition=2018 - run: cargo test - run: cargo test --features zlib - - run: cargo test --features miniz-sys - run: cargo test --features zlib --no-default-features - run: cargo test --features zlib-ng-compat --no-default-features + if: matrix.build != 'mingw' + - run: cargo test --features zlib-ng --no-default-features + if: matrix.build != 'mingw' - run: cargo test --features cloudflare_zlib --no-default-features if: matrix.build != 'mingw' - - run: cargo test --features miniz-sys --no-default-features - - run: cargo test --features tokio rustfmt: name: Rustfmt @@ -54,15 +54,6 @@ jobs: run: rustup update stable && rustup default stable && rustup component add rustfmt - run: cargo fmt -- --check - systest: - name: Systest - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@master - - name: Install Rust - run: rustup update stable && rustup default stable - - run: cargo run --manifest-path systest/Cargo.toml - wasm: name: WebAssembly runs-on: ubuntu-latest @@ -74,21 +65,3 @@ jobs: - name: Install Rust run: rustup update stable && rustup default stable && rustup target add ${{ matrix.target }} - run: cargo build --target ${{ matrix.target }} - - publish_docs: - name: Publish Documentation - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@master - - name: Install Rust - run: rustup update stable && rustup default stable - - name: Build documentation - run: cargo doc --no-deps --all-features - - name: Publish documentation - run: | - cd target/doc - git init - git add . - git -c user.name='ci' -c user.email='ci' commit -m init - git push -f -q https://git:${{ secrets.github_token }}@github.com/${{ github.repository }} HEAD:gh-pages - if: github.event_name == 'push' && github.event.ref == 'refs/heads/master' @@ -1,2 +1,4 @@ target Cargo.lock +examples/*.gz +.idea @@ -37,12 +37,102 @@ license { ], } +rust_test { + name: "flate2_test_src_lib", + crate_name: "flate2", + cargo_env_compat: true, + cargo_pkg_version: "1.0.25", + srcs: ["src/lib.rs"], + test_suites: ["general-tests"], + auto_gen_config: true, + test_options: { + unit_test: true, + }, + edition: "2018", + features: [ + "any_zlib", + "libz-sys", + "zlib", + ], + rustlibs: [ + "libcrc32fast", + "liblibz_sys", + "libquickcheck", + "librand", + ], +} + +rust_defaults { + name: "flate2_test_defaults", + crate_name: "flate2", + cargo_env_compat: true, + cargo_pkg_version: "1.0.25", + test_suites: ["general-tests"], + auto_gen_config: true, + edition: "2018", + features: [ + "any_zlib", + "libz-sys", + "zlib", + ], + rustlibs: [ + "libcrc32fast", + "libflate2", + "liblibz_sys", + "libquickcheck", + "librand", + ], +} + +rust_test { + name: "flate2_test_tests_early-flush", + defaults: ["flate2_test_defaults"], + srcs: ["tests/early-flush.rs"], + test_options: { + unit_test: true, + }, +} + +rust_test { + name: "flate2_test_tests_empty-read", + defaults: ["flate2_test_defaults"], + srcs: ["tests/empty-read.rs"], + test_options: { + unit_test: true, + }, +} + +rust_test { + name: "flate2_test_tests_gunzip", + defaults: ["flate2_test_defaults"], + srcs: ["tests/gunzip.rs"], + test_options: { + unit_test: true, + }, + data: [ + "tests/corrupt-gz-file.bin", + "tests/good-file.gz", + "tests/good-file.txt", + "tests/multi.gz", + "tests/multi.txt", + ], +} + +rust_test { + name: "flate2_test_tests_zero-write", + defaults: ["flate2_test_defaults"], + srcs: ["tests/zero-write.rs"], + test_options: { + unit_test: true, + }, +} + rust_library { name: "libflate2", host_supported: true, crate_name: "flate2", cargo_env_compat: true, - cargo_pkg_version: "1.0.22", + cargo_pkg_version: "1.0.25", srcs: ["src/lib.rs"], edition: "2018", features: [ @@ -51,13 +141,13 @@ rust_library { "zlib", ], rustlibs: [ - "libcfg_if", "libcrc32fast", - "liblibc", "liblibz_sys", ], apex_available: [ "//apex_available:platform", "com.android.virt", ], + product_available: true, + vendor_available: true, } diff --git a/Cargo.lock.saved b/Cargo.lock.saved new file mode 100644 index 0000000..5389eec --- /dev/null +++ b/Cargo.lock.saved @@ -0,0 +1,173 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "cc" +version = "1.0.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cloudflare-zlib-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2040b6d1edfee6d75f172d81e2d2a7807534f3f294ce18184c70e7bb0105cd6f" +dependencies = [ + "cc", +] + +[[package]] +name = "cmake" +version = "0.1.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db34956e100b30725f2eb215f90d4871051239535632f84fea3bc92722c66b7c" +dependencies = [ + "cc", +] + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "flate2" +version = "1.0.25" +dependencies = [ + "cloudflare-zlib-sys", + "crc32fast", + "libz-ng-sys", + "libz-sys", + "miniz_oxide", + "quickcheck", + "rand", +] + +[[package]] +name = "getrandom" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "libc" +version = "0.2.137" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" + +[[package]] +name = "libz-ng-sys" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4399ae96a9966bf581e726de86969f803a81b7ce795fcd5480e640589457e0f2" +dependencies = [ + "cmake", + "libc", +] + +[[package]] +name = "libz-sys" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9702761c3935f8cc2f101793272e202c72b99da8f4224a19ddcf1279a6450bbf" +dependencies = [ + "cc", + "cmake", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "miniz_oxide" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +dependencies = [ + "adler", +] + +[[package]] +name = "pkg-config" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "quickcheck" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "588f6378e4dd99458b60ec275b4477add41ce4fa9f64dcba6f15adccb19b50d6" +dependencies = [ + "rand", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" @@ -12,18 +12,32 @@ [package] edition = "2018" name = "flate2" -version = "1.0.22" -authors = ["Alex Crichton <alex@alexcrichton.com>", "Josh Triplett <josh@joshtriplett.org>"] -description = "DEFLATE compression and decompression exposed as Read/BufRead/Write streams.\nSupports miniz_oxide, miniz.c, and multiple zlib implementations. Supports\nzlib, gzip, and raw deflate streams.\n" +version = "1.0.25" +authors = [ + "Alex Crichton <alex@alexcrichton.com>", + "Josh Triplett <josh@joshtriplett.org>", +] +description = """ +DEFLATE compression and decompression exposed as Read/BufRead/Write streams. +Supports miniz_oxide and multiple zlib implementations. Supports zlib, gzip, +and raw deflate streams. +""" homepage = "https://github.com/rust-lang/flate2-rs" documentation = "https://docs.rs/flate2" readme = "README.md" -keywords = ["gzip", "deflate", "zlib", "zlib-ng", "encoding"] -categories = ["compression", "api-bindings"] -license = "MIT/Apache-2.0" +keywords = [ + "gzip", + "deflate", + "zlib", + "zlib-ng", + "encoding", +] +categories = [ + "compression", + "api-bindings", +] +license = "MIT OR Apache-2.0" repository = "https://github.com/rust-lang/flate2-rs" -[dependencies.cfg-if] -version = "1.0.0" [dependencies.cloudflare-zlib-sys] version = "0.3.0" @@ -32,57 +46,51 @@ optional = true [dependencies.crc32fast] version = "1.2.0" -[dependencies.futures] -version = "0.1.25" +[dependencies.libz-ng-sys] +version = "1.1.8" optional = true -[dependencies.libc] -version = "0.2.65" - [dependencies.libz-sys] -version = "1.1.0" +version = "1.1.8" optional = true default-features = false -[dependencies.miniz-sys] -version = "0.1.11" -optional = true - [dependencies.miniz_oxide] -version = "0.4.0" +version = "0.6.0" +features = ["with-alloc"] optional = true default-features = false -[dependencies.tokio-io] -version = "0.1.11" -optional = true -[dev-dependencies.futures] -version = "0.1" - [dev-dependencies.quickcheck] -version = "0.9" +version = "1.0" default-features = false [dev-dependencies.rand] -version = "0.7" - -[dev-dependencies.tokio-io] -version = "0.1.11" - -[dev-dependencies.tokio-tcp] -version = "0.1.3" - -[dev-dependencies.tokio-threadpool] -version = "0.1.10" +version = "0.8" [features] any_zlib = [] -cloudflare_zlib = ["any_zlib", "cloudflare-zlib-sys"] +cloudflare_zlib = [ + "any_zlib", + "cloudflare-zlib-sys", +] default = ["rust_backend"] +miniz-sys = ["rust_backend"] rust_backend = ["miniz_oxide"] -tokio = ["tokio-io", "futures"] -zlib = ["any_zlib", "libz-sys"] -zlib-ng-compat = ["zlib", "libz-sys/zlib-ng"] +zlib = [ + "any_zlib", + "libz-sys", +] +zlib-ng = [ + "any_zlib", + "libz-ng-sys", +] +zlib-ng-compat = [ + "zlib", + "libz-sys/zlib-ng", +] + [target."cfg(all(target_arch = \"wasm32\", not(target_os = \"emscripten\")))".dependencies.miniz_oxide] -version = "0.4.0" +version = "0.6.0" +features = ["with-alloc"] default-features = false diff --git a/Cargo.toml.orig b/Cargo.toml.orig index 08ee25b..aa9a4fc 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -1,9 +1,9 @@ [package] name = "flate2" authors = ["Alex Crichton <alex@alexcrichton.com>", "Josh Triplett <josh@joshtriplett.org>"] -version = "1.0.22" +version = "1.0.25" edition = "2018" -license = "MIT/Apache-2.0" +license = "MIT OR Apache-2.0" readme = "README.md" keywords = ["gzip", "deflate", "zlib", "zlib-ng", "encoding"] categories = ["compression", "api-bindings"] @@ -12,40 +12,30 @@ homepage = "https://github.com/rust-lang/flate2-rs" documentation = "https://docs.rs/flate2" description = """ DEFLATE compression and decompression exposed as Read/BufRead/Write streams. -Supports miniz_oxide, miniz.c, and multiple zlib implementations. Supports -zlib, gzip, and raw deflate streams. +Supports miniz_oxide and multiple zlib implementations. Supports zlib, gzip, +and raw deflate streams. """ -[workspace] -members = ['systest'] - [dependencies] -libc = "0.2.65" -cfg-if = "1.0.0" -miniz-sys = { path = "miniz-sys", version = "0.1.11", optional = true } -libz-sys = { version = "1.1.0", optional = true, default-features = false } +libz-sys = { version = "1.1.8", optional = true, default-features = false } +libz-ng-sys = { version = "1.1.8", optional = true } cloudflare-zlib-sys = { version = "0.3.0", optional = true } -tokio-io = { version = "0.1.11", optional = true } -futures = { version = "0.1.25", optional = true } -miniz_oxide = { version = "0.4.0", optional = true, default-features = false } +miniz_oxide = { version = "0.6.0", optional = true, default-features = false, features = ["with-alloc"] } crc32fast = "1.2.0" [target.'cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))'.dependencies] -miniz_oxide = { version = "0.4.0", default-features = false } +miniz_oxide = { version = "0.6.0", default-features = false, features = ["with-alloc"] } [dev-dependencies] -rand = "0.7" -quickcheck = { version = "0.9", default-features = false } -tokio-io = "0.1.11" -tokio-tcp = "0.1.3" -tokio-threadpool = "0.1.10" -futures = "0.1" +rand = "0.8" +quickcheck = { version = "1.0", default-features = false } [features] default = ["rust_backend"] any_zlib = [] # note: this is not a real user-facing feature zlib = ["any_zlib", "libz-sys"] zlib-ng-compat = ["zlib", "libz-sys/zlib-ng"] +zlib-ng = ["any_zlib", "libz-ng-sys"] cloudflare_zlib = ["any_zlib", "cloudflare-zlib-sys"] rust_backend = ["miniz_oxide"] -tokio = ["tokio-io", "futures"] +miniz-sys = ["rust_backend"] # For backwards compatibility @@ -1,3 +1,7 @@ +# This project was upgraded with external_updater. +# Usage: tools/external_updater/updater.sh update rust/crates/flate2 +# For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md + name: "flate2" description: "DEFLATE compression and decompression exposed as Read/BufRead/Write streams. Supports miniz_oxide, miniz.c, and multiple zlib implementations. Supports zlib, gzip, and raw deflate streams." third_party { @@ -7,13 +11,13 @@ third_party { } url { type: ARCHIVE - value: "https://static.crates.io/crates/flate2/flate2-1.0.22.crate" + value: "https://static.crates.io/crates/flate2/flate2-1.0.25.crate" } - version: "1.0.22" + version: "1.0.25" license_type: NOTICE last_upgrade_date { - year: 2021 - month: 9 - day: 22 + year: 2022 + month: 12 + day: 9 } } @@ -52,8 +52,19 @@ fn main() { ## Backends -The default `miniz_oxide` backend has the advantage of being pure Rust, but if -you're already using zlib with another C library, for example, you can use that +The default `miniz_oxide` backend has the advantage of being pure Rust. If you +want maximum performance, you can use the zlib-ng C library: + +```toml +[dependencies] +flate2 = { version = "1.0.17", features = ["zlib-ng"], default-features = false } +``` + +Note that the `"zlib-ng"` feature works even if some other part of your crate +graph depends on zlib. + +However, if you're already using another C or Rust library that depends on +zlib, and you want to avoid including both zlib and zlib-ng, you can use that for Rust code as well: ```toml @@ -61,40 +72,38 @@ for Rust code as well: flate2 = { version = "1.0.17", features = ["zlib"], default-features = false } ``` -This supports either the high-performance zlib-ng backend (in zlib-compat mode) -or the use of a shared system zlib library. To explicitly opt into the fast -zlib-ng backend, use: +Or, if you have C or Rust code that depends on zlib and you want to use zlib-ng +via libz-sys in zlib-compat mode, use: ```toml [dependencies] flate2 = { version = "1.0.17", features = ["zlib-ng-compat"], default-features = false } ``` -Note that if any crate in your dependency graph explicitly requests stock zlib, -or uses libz-sys directly without `default-features = false`, you'll get stock -zlib rather than zlib-ng. See [the libz-sys +Note that when using the `"zlib-ng-compat"` feature, if any crate in your +dependency graph explicitly requests stock zlib, or uses libz-sys directly +without `default-features = false`, you'll get stock zlib rather than zlib-ng. +See [the libz-sys README](https://github.com/rust-lang/libz-sys/blob/main/README.md) for details. +To avoid that, use the `"zlib-ng"` feature instead. -For compatibility with previous versions of `flate2`, the cloudflare optimized +For compatibility with previous versions of `flate2`, the Cloudflare optimized version of zlib is available, via the `cloudflare_zlib` feature. It's not as -fast as zlib-ng, but it's faster than stock zlib. It requires a x86-64 CPU with +fast as zlib-ng, but it's faster than stock zlib. It requires an x86-64 CPU with SSE 4.2 or ARM64 with NEON & CRC. It does not support 32-bit CPUs at all and is incompatible with mingw. For more information check the [crate documentation](https://crates.io/crates/cloudflare-zlib-sys). Note that `cloudflare_zlib` will cause breakage if any other crate in your crate graph uses another version of zlib/libz. -For compatibility with previous versions of `flate2`, the C version of `miniz.c` -is still available, using the feature `miniz-sys`. - # License This project is licensed under either of * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or - http://www.apache.org/licenses/LICENSE-2.0) + https://www.apache.org/licenses/LICENSE-2.0) * MIT license ([LICENSE-MIT](LICENSE-MIT) or - http://opensource.org/licenses/MIT) + https://opensource.org/licenses/MIT) at your option. diff --git a/TEST_MAPPING b/TEST_MAPPING index 7325ef4..7608707 100644 --- a/TEST_MAPPING +++ b/TEST_MAPPING @@ -1,37 +1,63 @@ // Generated by update_crate_tests.py for tests that depend on this crate. { + "imports": [ + { + "path": "packages/modules/Virtualization/apkdmverity" + }, + { + "path": "packages/modules/Virtualization/avmd" + }, + { + "path": "packages/modules/Virtualization/libs/apexutil" + }, + { + "path": "packages/modules/Virtualization/libs/apkverify" + }, + { + "path": "packages/modules/Virtualization/microdroid_manager" + }, + { + "path": "packages/modules/Virtualization/virtualizationmanager" + }, + { + "path": "packages/modules/Virtualization/vm" + }, + { + "path": "packages/modules/Virtualization/zipfuse" + } + ], "presubmit": [ { - "name": "ZipFuseTest" + "name": "flate2_test_src_lib" }, { - "name": "libapkverify.integration_test" + "name": "flate2_test_tests_early-flush" }, { - "name": "libapkverify.test" + "name": "flate2_test_tests_empty-read" }, { - "name": "microdroid_manager_test" + "name": "flate2_test_tests_gunzip" }, { - "name": "virtualizationservice_device_test" + "name": "flate2_test_tests_zero-write" } ], "presubmit-rust": [ { - "name": "ZipFuseTest" + "name": "flate2_test_src_lib" }, { - "name": "libapkverify.integration_test" + "name": "flate2_test_tests_early-flush" }, { - "name": "libapkverify.test" + "name": "flate2_test_tests_empty-read" }, { - "name": "microdroid_manager_test" + "name": "flate2_test_tests_gunzip" }, { - "name": "virtualizationservice_device_test" + "name": "flate2_test_tests_zero-write" } ] } diff --git a/cargo2android.json b/cargo2android.json index 85a6aa6..11879eb 100644 --- a/cargo2android.json +++ b/cargo2android.json @@ -5,5 +5,14 @@ ], "device": true, "features": "zlib", - "run": true -}
\ No newline at end of file + "run": true, + "patch": "patches/Android.bp.patch", + "tests": true, + "test-data": [ + "tests/gunzip.rs=tests/corrupt-gz-file.bin", + "tests/gunzip.rs=tests/good-file.gz", + "tests/gunzip.rs=tests/good-file.txt", + "tests/gunzip.rs=tests/multi.gz", + "tests/gunzip.rs=tests/multi.txt" + ] +} diff --git a/examples/deflateencoder-read.rs b/examples/deflateencoder-read.rs index 47e4784..ffb628e 100644 --- a/examples/deflateencoder-read.rs +++ b/examples/deflateencoder-read.rs @@ -10,7 +10,7 @@ fn main() { println!("{:?}", deflateencoder_read_hello_world().unwrap()); } -// Return a vector containing the Defalte compressed version of hello world +// Return a vector containing the Deflate compressed version of hello world fn deflateencoder_read_hello_world() -> io::Result<Vec<u8>> { let mut result = Vec::new(); let c = b"hello world"; diff --git a/examples/gzbuilder.rs b/examples/gzbuilder.rs index 031683d..d6ec2f4 100644 --- a/examples/gzbuilder.rs +++ b/examples/gzbuilder.rs @@ -6,14 +6,14 @@ use std::fs::File; use std::io; use std::io::prelude::*; -// Open file and debug print the contents compressed with gzip +// Compresses content of a text file into a gzip file fn main() { sample_builder().unwrap(); } // GzBuilder opens a file and writes a sample string using Builder pattern fn sample_builder() -> Result<(), io::Error> { - let f = File::create("examples/hello_world.gz")?; + let f = File::create("examples/hello_world.txt.gz")?; let mut gz = GzBuilder::new() .filename("hello_world.txt") .comment("test file, please delete") diff --git a/examples/gzdecoder-bufread.rs b/examples/gzdecoder-bufread.rs index 0702c17..8551197 100644 --- a/examples/gzdecoder-bufread.rs +++ b/examples/gzdecoder-bufread.rs @@ -1,8 +1,7 @@ extern crate flate2; -use flate2::bufread::GzDecoder; use flate2::write::GzEncoder; -use flate2::Compression; +use flate2::{bufread, Compression}; use std::io; use std::io::prelude::*; @@ -17,7 +16,7 @@ fn main() { // Uncompresses a Gz Encoded vector of bytes and returns a string or error // Here &[u8] implements BufRead fn decode_reader(bytes: Vec<u8>) -> io::Result<String> { - let mut gz = GzDecoder::new(&bytes[..]); + let mut gz = bufread::GzDecoder::new(&bytes[..]); let mut s = String::new(); gz.read_to_string(&mut s)?; Ok(s) diff --git a/examples/gzdecoder-read.rs b/examples/gzdecoder-read.rs index d8dcba3..705d28c 100644 --- a/examples/gzdecoder-read.rs +++ b/examples/gzdecoder-read.rs @@ -1,8 +1,7 @@ extern crate flate2; -use flate2::read::GzDecoder; use flate2::write::GzEncoder; -use flate2::Compression; +use flate2::{read, Compression}; use std::io; use std::io::prelude::*; @@ -17,7 +16,7 @@ fn main() { // Uncompresses a Gz Encoded vector of bytes and returns a string or error // Here &[u8] implements Read fn decode_reader(bytes: Vec<u8>) -> io::Result<String> { - let mut gz = GzDecoder::new(&bytes[..]); + let mut gz = read::GzDecoder::new(&bytes[..]); let mut s = String::new(); gz.read_to_string(&mut s)?; Ok(s) diff --git a/patches/Android.bp.patch b/patches/Android.bp.patch new file mode 100644 index 0000000..903ecfe --- /dev/null +++ b/patches/Android.bp.patch @@ -0,0 +1,44 @@ +diff --git a/Android.bp b/Android.bp +index 0d89ca8..d52dddd 100644 +--- a/Android.bp ++++ b/Android.bp +@@ -39,7 +39,6 @@ license { + + rust_test { + name: "flate2_test_src_lib", +- host_supported: true, + crate_name: "flate2", + cargo_env_compat: true, + cargo_pkg_version: "1.0.24", +@@ -88,7 +87,6 @@ rust_defaults { + rust_test { + name: "flate2_test_tests_early-flush", + defaults: ["flate2_test_defaults"], +- host_supported: true, + srcs: ["tests/early-flush.rs"], + test_options: { + unit_test: true, +@@ -98,7 +96,6 @@ rust_test { + rust_test { + name: "flate2_test_tests_empty-read", + defaults: ["flate2_test_defaults"], +- host_supported: true, + srcs: ["tests/empty-read.rs"], + test_options: { + unit_test: true, +@@ -108,7 +105,6 @@ rust_test { + rust_test { + name: "flate2_test_tests_gunzip", + defaults: ["flate2_test_defaults"], +- host_supported: true, + srcs: ["tests/gunzip.rs"], + test_options: { + unit_test: true, +@@ -125,7 +121,6 @@ rust_test { + rust_test { + name: "flate2_test_tests_zero-write", + defaults: ["flate2_test_defaults"], +- host_supported: true, + srcs: ["tests/zero-write.rs"], + test_options: { + unit_test: true, diff --git a/src/bufreader.rs b/src/bufreader.rs index 9aa6a3a..7e6f89d 100644 --- a/src/bufreader.rs +++ b/src/bufreader.rs @@ -1,10 +1,10 @@ // Copyright 2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. +// <https://github.com/rust-lang/rust/blob/HEAD/COPYRIGHT>. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. @@ -42,7 +42,7 @@ impl<R: Read> BufReader<R> { pub fn with_buf(buf: Vec<u8>, inner: R) -> BufReader<R> { BufReader { - inner: inner, + inner, buf: buf.into_boxed_slice(), pos: 0, cap: 0, @@ -23,6 +23,12 @@ pub struct CrcReader<R> { crc: Crc, } +impl Default for Crc { + fn default() -> Self { + Self::new() + } +} + impl Crc { /// Create a new CRC. pub fn new() -> Crc { diff --git a/src/deflate/bufread.rs b/src/deflate/bufread.rs index 98aee70..f0b29e0 100644 --- a/src/deflate/bufread.rs +++ b/src/deflate/bufread.rs @@ -2,11 +2,6 @@ use std::io; use std::io::prelude::*; use std::mem; -#[cfg(feature = "tokio")] -use futures::Poll; -#[cfg(feature = "tokio")] -use tokio_io::{AsyncRead, AsyncWrite}; - use crate::zio; use crate::{Compress, Decompress}; @@ -116,9 +111,6 @@ impl<R: BufRead> Read for DeflateEncoder<R> { } } -#[cfg(feature = "tokio")] -impl<R: AsyncRead + BufRead> AsyncRead for DeflateEncoder<R> {} - impl<W: BufRead + Write> Write for DeflateEncoder<W> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.get_mut().write(buf) @@ -129,13 +121,6 @@ impl<W: BufRead + Write> Write for DeflateEncoder<W> { } } -#[cfg(feature = "tokio")] -impl<R: AsyncWrite + BufRead> AsyncWrite for DeflateEncoder<R> { - fn shutdown(&mut self) -> Poll<(), io::Error> { - self.get_mut().shutdown() - } -} - /// A DEFLATE decoder, or decompressor. /// /// This structure consumes a [`BufRead`] interface, reading compressed data @@ -247,9 +232,6 @@ impl<R: BufRead> Read for DeflateDecoder<R> { } } -#[cfg(feature = "tokio")] -impl<R: AsyncRead + BufRead> AsyncRead for DeflateDecoder<R> {} - impl<W: BufRead + Write> Write for DeflateDecoder<W> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.get_mut().write(buf) @@ -259,10 +241,3 @@ impl<W: BufRead + Write> Write for DeflateDecoder<W> { self.get_mut().flush() } } - -#[cfg(feature = "tokio")] -impl<R: AsyncWrite + BufRead> AsyncWrite for DeflateDecoder<R> { - fn shutdown(&mut self) -> Poll<(), io::Error> { - self.get_mut().shutdown() - } -} diff --git a/src/deflate/mod.rs b/src/deflate/mod.rs index 90a4241..51758b3 100644 --- a/src/deflate/mod.rs +++ b/src/deflate/mod.rs @@ -17,7 +17,7 @@ mod tests { let mut w = write::DeflateEncoder::new(Vec::new(), Compression::default()); let v = crate::random_bytes().take(1024).collect::<Vec<_>>(); for _ in 0..200 { - let to_write = &v[..thread_rng().gen_range(0, v.len())]; + let to_write = &v[..thread_rng().gen_range(0..v.len())]; real.extend(to_write.iter().map(|x| *x)); w.write_all(to_write).unwrap(); } @@ -46,7 +46,7 @@ mod tests { let mut w = write::DeflateEncoder::new(Vec::new(), Compression::default()); let v = crate::random_bytes().take(1024).collect::<Vec<_>>(); for _ in 0..200 { - let to_write = &v[..thread_rng().gen_range(0, v.len())]; + let to_write = &v[..thread_rng().gen_range(0..v.len())]; real.extend(to_write.iter().map(|x| *x)); w.write_all(to_write).unwrap(); } diff --git a/src/deflate/read.rs b/src/deflate/read.rs index 21748e7..fd17a89 100644 --- a/src/deflate/read.rs +++ b/src/deflate/read.rs @@ -1,11 +1,6 @@ use std::io; use std::io::prelude::*; -#[cfg(feature = "tokio")] -use futures::Poll; -#[cfg(feature = "tokio")] -use tokio_io::{AsyncRead, AsyncWrite}; - use super::bufread; use crate::bufreader::BufReader; @@ -113,9 +108,6 @@ impl<R: Read> Read for DeflateEncoder<R> { } } -#[cfg(feature = "tokio")] -impl<R: AsyncRead> AsyncRead for DeflateEncoder<R> {} - impl<W: Read + Write> Write for DeflateEncoder<W> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.get_mut().write(buf) @@ -126,13 +118,6 @@ impl<W: Read + Write> Write for DeflateEncoder<W> { } } -#[cfg(feature = "tokio")] -impl<R: AsyncRead + AsyncWrite> AsyncWrite for DeflateEncoder<R> { - fn shutdown(&mut self) -> Poll<(), io::Error> { - self.get_mut().shutdown() - } -} - /// A DEFLATE decoder, or decompressor. /// /// This structure implements a [`Read`] interface and takes a stream of @@ -245,9 +230,6 @@ impl<R: Read> Read for DeflateDecoder<R> { } } -#[cfg(feature = "tokio")] -impl<R: AsyncRead> AsyncRead for DeflateDecoder<R> {} - impl<W: Read + Write> Write for DeflateDecoder<W> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.get_mut().write(buf) @@ -257,10 +239,3 @@ impl<W: Read + Write> Write for DeflateDecoder<W> { self.get_mut().flush() } } - -#[cfg(feature = "tokio")] -impl<R: AsyncWrite + AsyncRead> AsyncWrite for DeflateDecoder<R> { - fn shutdown(&mut self) -> Poll<(), io::Error> { - self.get_mut().shutdown() - } -} diff --git a/src/deflate/write.rs b/src/deflate/write.rs index a9aadb9..2c44556 100644 --- a/src/deflate/write.rs +++ b/src/deflate/write.rs @@ -1,11 +1,6 @@ use std::io; use std::io::prelude::*; -#[cfg(feature = "tokio")] -use futures::Poll; -#[cfg(feature = "tokio")] -use tokio_io::{AsyncRead, AsyncWrite}; - use crate::zio; use crate::{Compress, Decompress}; @@ -139,7 +134,7 @@ impl<W: Write> DeflateEncoder<W> { Ok(self.inner.take_inner()) } - /// Returns the number of bytes that have been written to this compresor. + /// Returns the number of bytes that have been written to this compressor. /// /// Note that not all bytes written to this object may be accounted for, /// there may still be some active buffering. @@ -166,23 +161,12 @@ impl<W: Write> Write for DeflateEncoder<W> { } } -#[cfg(feature = "tokio")] -impl<W: AsyncWrite> AsyncWrite for DeflateEncoder<W> { - fn shutdown(&mut self) -> Poll<(), io::Error> { - self.inner.finish()?; - self.inner.get_mut().shutdown() - } -} - impl<W: Read + Write> Read for DeflateEncoder<W> { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.inner.get_mut().read(buf) } } -#[cfg(feature = "tokio")] -impl<W: AsyncRead + AsyncWrite> AsyncRead for DeflateEncoder<W> {} - /// A DEFLATE decoder, or decompressor. /// /// This structure implements a [`Write`] and will emit a stream of decompressed @@ -331,19 +315,8 @@ impl<W: Write> Write for DeflateDecoder<W> { } } -#[cfg(feature = "tokio")] -impl<W: AsyncWrite> AsyncWrite for DeflateDecoder<W> { - fn shutdown(&mut self) -> Poll<(), io::Error> { - self.inner.finish()?; - self.inner.get_mut().shutdown() - } -} - impl<W: Read + Write> Read for DeflateDecoder<W> { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.inner.get_mut().read(buf) } } - -#[cfg(feature = "tokio")] -impl<W: AsyncRead + AsyncWrite> AsyncRead for DeflateDecoder<W> {} diff --git a/src/ffi/c.rs b/src/ffi/c.rs index 1ab6cab..59e2011 100644 --- a/src/ffi/c.rs +++ b/src/ffi/c.rs @@ -5,27 +5,18 @@ use std::convert::TryFrom; use std::fmt; use std::marker; use std::ops::{Deref, DerefMut}; +use std::os::raw::{c_int, c_uint, c_void}; use std::ptr; -pub use libc::{c_int, c_uint, c_void, size_t}; - use super::*; use crate::mem::{self, FlushDecompress, Status}; -// miniz doesn't provide any error messages, so only enable the field when we use a real zlib #[derive(Default)] -pub struct ErrorMessage(#[cfg(feature = "any_zlib")] Option<&'static str>); +pub struct ErrorMessage(Option<&'static str>); impl ErrorMessage { pub fn get(&self) -> Option<&str> { - #[cfg(feature = "any_zlib")] - { - self.0 - } - #[cfg(not(feature = "any_zlib"))] - { - None - } + self.0 } } @@ -109,7 +100,7 @@ extern "C" fn zalloc(_ptr: *mut c_void, items: AllocSize, item_size: AllocSize) extern "C" fn zfree(_ptr: *mut c_void, address: *mut c_void) { unsafe { - // Move our address being free'd back one pointer, read the size we + // Move our address being freed back one pointer, read the size we // stored in `zalloc`, and then free it using the standard Rust // allocator. let ptr = (address as *mut usize).offset(-1); @@ -157,20 +148,13 @@ pub struct Stream<D: Direction> { impl<D: Direction> Stream<D> { pub fn msg(&self) -> ErrorMessage { - #[cfg(feature = "any_zlib")] - { - let msg = self.stream_wrapper.msg; - ErrorMessage(if msg.is_null() { - None - } else { - let s = unsafe { std::ffi::CStr::from_ptr(msg) }; - std::str::from_utf8(s.to_bytes()).ok() - }) - } - #[cfg(not(feature = "any_zlib"))] - { - ErrorMessage() - } + let msg = self.stream_wrapper.msg; + ErrorMessage(if msg.is_null() { + None + } else { + let s = unsafe { std::ffi::CStr::from_ptr(msg) }; + std::str::from_utf8(s.to_bytes()).ok() + }) } } @@ -252,7 +236,6 @@ impl InflateBackend for Inflate { } } - #[cfg(feature = "any_zlib")] fn reset(&mut self, zlib_header: bool) { let bits = if zlib_header { MZ_DEFAULT_WINDOW_BITS @@ -265,11 +248,6 @@ impl InflateBackend for Inflate { self.inner.total_out = 0; self.inner.total_in = 0; } - - #[cfg(not(feature = "any_zlib"))] - fn reset(&mut self, zlib_header: bool) { - *self = Self::make(zlib_header, MZ_DEFAULT_WINDOW_BITS as u8); - } } impl Backend for Inflate { @@ -367,23 +345,19 @@ impl Backend for Deflate { pub use self::c_backend::*; -/// Miniz specific -#[cfg(not(feature = "any_zlib"))] -mod c_backend { - pub use miniz_sys::*; - pub type AllocSize = libc::size_t; -} - -/// Zlib specific - make zlib mimic miniz' API -#[cfg(feature = "any_zlib")] +/// For backwards compatibility, we provide symbols as `mz_` to mimic the miniz API #[allow(bad_style)] mod c_backend { - use libc::{c_char, c_int}; use std::mem; + use std::os::raw::{c_char, c_int}; - #[cfg(feature = "cloudflare_zlib")] + #[cfg(feature = "zlib-ng")] + use libz_ng_sys as libz; + + #[cfg(all(not(feature = "zlib-ng"), feature = "cloudflare_zlib"))] use cloudflare_zlib_sys as libz; - #[cfg(not(feature = "cloudflare_zlib"))] + + #[cfg(all(not(feature = "cloudflare_zlib"), not(feature = "zlib-ng")))] use libz_sys as libz; pub use libz::deflate as mz_deflate; @@ -412,6 +386,9 @@ mod c_backend { pub const MZ_DEFAULT_WINDOW_BITS: c_int = 15; + #[cfg(feature = "zlib-ng")] + const ZLIB_VERSION: &'static str = "2.1.0.devel\0"; + #[cfg(not(feature = "zlib-ng"))] const ZLIB_VERSION: &'static str = "1.2.8\0"; pub unsafe extern "C" fn mz_deflateInit2( diff --git a/src/ffi/mod.rs b/src/ffi/mod.rs index 83e632d..8bac6e4 100644 --- a/src/ffi/mod.rs +++ b/src/ffi/mod.rs @@ -35,15 +35,15 @@ pub trait DeflateBackend: Backend { } // Default to Rust implementation unless explicitly opted in to a different backend. -cfg_if::cfg_if! { - if #[cfg(any(feature = "miniz-sys", feature = "any_zlib"))] { - mod c; - pub use self::c::*; - } else { - mod rust; - pub use self::rust::*; - } -} +#[cfg(feature = "any_zlib")] +mod c; +#[cfg(feature = "any_zlib")] +pub use self::c::*; + +#[cfg(not(feature = "any_zlib"))] +mod rust; +#[cfg(not(feature = "any_zlib"))] +pub use self::rust::*; impl std::fmt::Debug for ErrorMessage { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { diff --git a/src/gz/bufread.rs b/src/gz/bufread.rs index eb0b332..6be144d 100644 --- a/src/gz/bufread.rs +++ b/src/gz/bufread.rs @@ -3,11 +3,6 @@ use std::io; use std::io::prelude::*; use std::mem; -#[cfg(feature = "tokio")] -use futures::Poll; -#[cfg(feature = "tokio")] -use tokio_io::{AsyncRead, AsyncWrite}; - use super::{GzBuilder, GzHeader}; use super::{FCOMMENT, FEXTRA, FHCRC, FNAME}; use crate::crc::{Crc, CrcReader}; @@ -20,7 +15,7 @@ fn copy(into: &mut [u8], from: &[u8], pos: &mut usize) -> usize { *slot = *val; } *pos += min; - return min; + min } pub(crate) fn corrupt() -> io::Error { @@ -126,15 +121,7 @@ pub(crate) fn read_gz_header<R: Read>(r: &mut R) -> io::Result<GzHeader> { let mut reader = Buffer::new(&mut part, r); read_gz_header_part(&mut reader) }; - - match result { - Ok(()) => { - return Ok(part.take_header()); - } - Err(err) => { - return Err(err); - } - }; + result.map(|()| part.take_header()) } /// A gzip streaming encoder @@ -179,7 +166,7 @@ pub fn gz_encoder<R: BufRead>(header: Vec<u8>, r: R, lvl: Compression) -> GzEnco let crc = CrcReader::new(r); GzEncoder { inner: deflate::bufread::DeflateEncoder::new(crc, lvl), - header: header, + header, pos: 0, eof: false, } @@ -363,7 +350,7 @@ impl GzHeaderPartial { } pub fn take_header(self) -> GzHeader { - return self.header; + self.header } } @@ -443,7 +430,7 @@ where self.part.buf.truncate(0); self.buf_cur = 0; self.buf_max = 0; - return Ok(rlen); + Ok(rlen) } } @@ -523,7 +510,7 @@ impl<R: BufRead> Read for GzDecoder<R> { let mut reader = Buffer::new(&mut part, reader.get_mut().get_mut()); read_gz_header_part(&mut reader) }; - let state = match result { + match result { Ok(()) => { *header = Some(part.take_header()); GzState::Body @@ -533,8 +520,7 @@ impl<R: BufRead> Read for GzDecoder<R> { return Err(err); } Err(err) => return Err(err), - }; - state + } } GzState::Body => { if into.is_empty() { @@ -619,9 +605,6 @@ impl<R: BufRead> Read for GzDecoder<R> { } } -#[cfg(feature = "tokio")] -impl<R: AsyncRead + BufRead> AsyncRead for GzDecoder<R> {} - impl<R: BufRead + Write> Write for GzDecoder<R> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.get_mut().write(buf) @@ -632,13 +615,6 @@ impl<R: BufRead + Write> Write for GzDecoder<R> { } } -#[cfg(feature = "tokio")] -impl<R: AsyncWrite + BufRead> AsyncWrite for GzDecoder<R> { - fn shutdown(&mut self) -> Poll<(), io::Error> { - self.get_mut().shutdown() - } -} - /// A gzip streaming decoder that decodes all members of a multistream /// /// A gzip member consists of a header, compressed data and a trailer. The [gzip @@ -722,26 +698,6 @@ impl<R: BufRead> Read for MultiGzDecoder<R> { } } -#[cfg(feature = "tokio")] -impl<R: AsyncRead + BufRead> AsyncRead for MultiGzDecoder<R> {} - -impl<R: BufRead + Write> Write for MultiGzDecoder<R> { - fn write(&mut self, buf: &[u8]) -> io::Result<usize> { - self.get_mut().write(buf) - } - - fn flush(&mut self) -> io::Result<()> { - self.get_mut().flush() - } -} - -#[cfg(feature = "tokio")] -impl<R: AsyncWrite + BufRead> AsyncWrite for MultiGzDecoder<R> { - fn shutdown(&mut self) -> Poll<(), io::Error> { - self.get_mut().shutdown() - } -} - #[cfg(test)] pub mod tests { use crate::gz::bufread::*; @@ -870,7 +826,7 @@ pub mod tests { } r.set_position(pos2); - // Fourth read : now succesful for 7 bytes + // Fourth read : now successful for 7 bytes let mut reader3 = Buffer::new(&mut part, &mut r); match reader3.read_and_forget(&mut out) { Ok(7) => { @@ -882,7 +838,7 @@ pub mod tests { } } - // Fifth read : succesful for one more byte + // Fifth read : successful for one more byte out.resize(1, 0); match reader3.read_and_forget(&mut out) { Ok(1) => { diff --git a/src/gz/mod.rs b/src/gz/mod.rs index 3c894c9..505450e 100644 --- a/src/gz/mod.rs +++ b/src/gz/mod.rs @@ -117,6 +117,12 @@ pub struct GzBuilder { mtime: u32, } +impl Default for GzBuilder { + fn default() -> Self { + Self::new() + } +} + impl GzBuilder { /// Create a new blank builder with no header by default. pub fn new() -> GzBuilder { @@ -204,28 +210,19 @@ impl GzBuilder { } = self; let mut flg = 0; let mut header = vec![0u8; 10]; - match extra { - Some(v) => { - flg |= FEXTRA; - header.push((v.len() >> 0) as u8); - header.push((v.len() >> 8) as u8); - header.extend(v); - } - None => {} + if let Some(v) = extra { + flg |= FEXTRA; + header.push((v.len() >> 0) as u8); + header.push((v.len() >> 8) as u8); + header.extend(v); } - match filename { - Some(filename) => { - flg |= FNAME; - header.extend(filename.as_bytes_with_nul().iter().map(|x| *x)); - } - None => {} + if let Some(filename) = filename { + flg |= FNAME; + header.extend(filename.as_bytes_with_nul().iter().map(|x| *x)); } - match comment { - Some(comment) => { - flg |= FCOMMENT; - header.extend(comment.as_bytes_with_nul().iter().map(|x| *x)); - } - None => {} + if let Some(comment) = comment { + flg |= FCOMMENT; + header.extend(comment.as_bytes_with_nul().iter().map(|x| *x)); } header[0] = 0x1f; header[1] = 0x8b; @@ -248,7 +245,7 @@ impl GzBuilder { // default this value to 255. I'm not sure that if we "correctly" set // this it'd do anything anyway... header[9] = operating_system.unwrap_or(255); - return header; + header } } @@ -287,7 +284,7 @@ mod tests { let mut w = write::GzEncoder::new(Vec::new(), Compression::default()); let v = crate::random_bytes().take(1024).collect::<Vec<_>>(); for _ in 0..200 { - let to_write = &v[..thread_rng().gen_range(0, v.len())]; + let to_write = &v[..thread_rng().gen_range(0..v.len())]; real.extend(to_write.iter().map(|x| *x)); w.write_all(to_write).unwrap(); } diff --git a/src/gz/read.rs b/src/gz/read.rs index 25f2741..dbbe632 100644 --- a/src/gz/read.rs +++ b/src/gz/read.rs @@ -1,11 +1,6 @@ use std::io; use std::io::prelude::*; -#[cfg(feature = "tokio")] -use futures::Poll; -#[cfg(feature = "tokio")] -use tokio_io::{AsyncRead, AsyncWrite}; - use super::bufread; use super::{GzBuilder, GzHeader}; use crate::bufreader::BufReader; @@ -43,7 +38,7 @@ pub struct GzEncoder<R> { } pub fn gz_encoder<R: Read>(inner: bufread::GzEncoder<BufReader<R>>) -> GzEncoder<R> { - GzEncoder { inner: inner } + GzEncoder { inner } } impl<R: Read> GzEncoder<R> { @@ -175,9 +170,6 @@ impl<R: Read> Read for GzDecoder<R> { } } -#[cfg(feature = "tokio")] -impl<R: AsyncRead> AsyncRead for GzDecoder<R> {} - impl<R: Read + Write> Write for GzDecoder<R> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.get_mut().write(buf) @@ -188,13 +180,6 @@ impl<R: Read + Write> Write for GzDecoder<R> { } } -#[cfg(feature = "tokio")] -impl<R: AsyncWrite + AsyncRead> AsyncWrite for GzDecoder<R> { - fn shutdown(&mut self) -> Poll<(), io::Error> { - self.get_mut().shutdown() - } -} - /// A gzip streaming decoder that decodes all members of a multistream /// /// A gzip member consists of a header, compressed data and a trailer. The [gzip @@ -282,9 +267,6 @@ impl<R: Read> Read for MultiGzDecoder<R> { } } -#[cfg(feature = "tokio")] -impl<R: AsyncRead> AsyncRead for MultiGzDecoder<R> {} - impl<R: Read + Write> Write for MultiGzDecoder<R> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.get_mut().write(buf) @@ -294,10 +276,3 @@ impl<R: Read + Write> Write for MultiGzDecoder<R> { self.get_mut().flush() } } - -#[cfg(feature = "tokio")] -impl<R: AsyncWrite + AsyncRead> AsyncWrite for MultiGzDecoder<R> { - fn shutdown(&mut self) -> Poll<(), io::Error> { - self.get_mut().shutdown() - } -} diff --git a/src/gz/write.rs b/src/gz/write.rs index 4e27593..7cf1a7c 100644 --- a/src/gz/write.rs +++ b/src/gz/write.rs @@ -2,11 +2,6 @@ use std::cmp; use std::io; use std::io::prelude::*; -#[cfg(feature = "tokio")] -use futures::Poll; -#[cfg(feature = "tokio")] -use tokio_io::{AsyncRead, AsyncWrite}; - use super::bufread::{corrupt, read_gz_header}; use super::{GzBuilder, GzHeader}; use crate::crc::{Crc, CrcWriter}; @@ -47,7 +42,7 @@ pub fn gz_encoder<W: Write>(header: Vec<u8>, w: W, lvl: Compression) -> GzEncode GzEncoder { inner: zio::Writer::new(w, Compress::new(lvl, false)), crc: Crc::new(), - header: header, + header, crc_bytes_written: 0, } } @@ -134,7 +129,7 @@ impl<W: Write> GzEncoder<W> { } fn write_header(&mut self) -> io::Result<()> { - while self.header.len() > 0 { + while !self.header.is_empty() { let n = self.inner.get_mut().write(&self.header)?; self.header.drain(..n); } @@ -158,23 +153,12 @@ impl<W: Write> Write for GzEncoder<W> { } } -#[cfg(feature = "tokio")] -impl<W: AsyncWrite> AsyncWrite for GzEncoder<W> { - fn shutdown(&mut self) -> Poll<(), io::Error> { - self.try_finish()?; - self.get_mut().shutdown() - } -} - impl<R: Read + Write> Read for GzEncoder<R> { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.get_mut().read(buf) } } -#[cfg(feature = "tokio")] -impl<R: AsyncRead + AsyncWrite> AsyncRead for GzEncoder<R> {} - impl<W: Write> Drop for GzEncoder<W> { fn drop(&mut self) { if self.inner.is_present() { @@ -368,13 +352,11 @@ impl<W: Write> Write for GzDecoder<W> { } else { let (n, status) = self.inner.write_with_status(buf)?; - if status == Status::StreamEnd { - if n < buf.len() && self.crc_bytes.len() < 8 { - let remaining = buf.len() - n; - let crc_bytes = cmp::min(remaining, CRC_BYTES_LEN - self.crc_bytes.len()); - self.crc_bytes.extend(&buf[n..n + crc_bytes]); - return Ok(n + crc_bytes); - } + if status == Status::StreamEnd && n < buf.len() && self.crc_bytes.len() < 8 { + let remaining = buf.len() - n; + let crc_bytes = cmp::min(remaining, CRC_BYTES_LEN - self.crc_bytes.len()); + self.crc_bytes.extend(&buf[n..n + crc_bytes]); + return Ok(n + crc_bytes); } Ok(n) } @@ -385,23 +367,12 @@ impl<W: Write> Write for GzDecoder<W> { } } -#[cfg(feature = "tokio")] -impl<W: AsyncWrite> AsyncWrite for GzDecoder<W> { - fn shutdown(&mut self) -> Poll<(), io::Error> { - self.try_finish()?; - self.inner.get_mut().get_mut().shutdown() - } -} - impl<W: Read + Write> Read for GzDecoder<W> { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.inner.get_mut().get_mut().read(buf) } } -#[cfg(feature = "tokio")] -impl<W: AsyncRead + AsyncWrite> AsyncRead for GzDecoder<W> {} - #[cfg(test)] mod tests { use super::*; @@ -13,30 +13,24 @@ //! //! # Implementation //! -//! In addition to supporting three formats, this crate supports three different +//! In addition to supporting three formats, this crate supports several different //! backends, controlled through this crate's features: //! //! * `default`, or `rust_backend` - this implementation uses the `miniz_oxide` //! crate which is a port of `miniz.c` (below) to Rust. This feature does not //! require a C compiler and only requires Rust code. //! -//! * `miniz-sys` - when enabled this feature will enable this crate to instead -//! use `miniz.c`, distributed with `miniz-sys`, to implement -//! compression/decompression. +//! * `zlib` - this feature will enable linking against the `libz` library, typically found on most +//! Linux systems by default. If the library isn't found to already be on the system it will be +//! compiled from source (this is a C library). //! -//! * `zlib` - finally, this feature will enable linking against the `libz` -//! library, typically found on most Linux systems by default. If the library -//! isn't found to already be on the system it will be compiled from source -//! (this is a C library). -//! -//! There's various tradeoffs associated with each implementation, but in -//! general you probably won't have to tweak the defaults. The default choice is -//! selected to avoid the need for a C compiler at build time. The `miniz-sys` -//! feature is largely a historical artifact at this point and is unlikely to be -//! needed, and `zlib` is often useful if you're already using `zlib` for other -//! C dependencies. The compression ratios and performance of each of these -//! feature should be roughly comparable, but you'll likely want to run your own -//! tests if you're curious about the performance. +//! There's various tradeoffs associated with each implementation, but in general you probably +//! won't have to tweak the defaults. The default choice is selected to avoid the need for a C +//! compiler at build time. `zlib-ng-compat` is useful if you're using zlib for compatibility but +//! want performance via zlib-ng's zlib-compat mode. `zlib` is useful if something else in your +//! dependencies links the original zlib so you cannot use zlib-ng-compat. The compression ratios +//! and performance of each of these feature should be roughly comparable, but you'll likely want +//! to run your own tests if you're curious about the performance. //! //! # Organization //! @@ -77,30 +71,6 @@ //! [read]: https://doc.rust-lang.org/std/io/trait.Read.html //! [write]: https://doc.rust-lang.org/std/io/trait.Write.html //! [bufread]: https://doc.rust-lang.org/std/io/trait.BufRead.html -//! -//! # Async I/O -//! -//! This crate optionally can support async I/O streams with the [Tokio stack] via -//! the `tokio` feature of this crate: -//! -//! [Tokio stack]: https://tokio.rs/ -//! -//! ```toml -//! flate2 = { version = "0.2", features = ["tokio"] } -//! ``` -//! -//! All methods are internally capable of working with streams that may return -//! [`ErrorKind::WouldBlock`] when they're not ready to perform the particular -//! operation. -//! -//! [`ErrorKind::WouldBlock`]: https://doc.rust-lang.org/std/io/enum.ErrorKind.html -//! -//! Note that care needs to be taken when using these objects, however. The -//! Tokio runtime, in particular, requires that data is fully flushed before -//! dropping streams. For compatibility with blocking streams all streams are -//! flushed/written when they are dropped, and this is not always a suitable -//! time to perform I/O. If I/O streams are flushed before drop, however, then -//! these operations will be a noop. #![doc(html_root_url = "https://docs.rs/flate2/0.2")] #![deny(missing_docs)] #![deny(missing_debug_implementations)] @@ -64,7 +64,7 @@ pub enum FlushCompress { /// All of the input data so far will be available to the decompressor (as /// with `Flush::Sync`. This completes the current deflate block and follows /// it with an empty fixed codes block that is 10 bites long, and it assures - /// that enough bytes are output in order for the decompessor to finish the + /// that enough bytes are output in order for the decompressor to finish the /// block before the empty fixed code block. Partial = ffi::MZ_PARTIAL_FLUSH as isize, @@ -283,7 +283,7 @@ impl Compress { let stream = &mut *self.inner.inner.stream_wrapper; stream.msg = std::ptr::null_mut(); let rc = unsafe { - assert!(dictionary.len() < ffi::uInt::max_value() as usize); + assert!(dictionary.len() < ffi::uInt::MAX as usize); ffi::deflateSetDictionary(stream, dictionary.as_ptr(), dictionary.len() as ffi::uInt) }; @@ -313,7 +313,7 @@ impl Compress { /// ensures that the function will succeed on the first call. #[cfg(feature = "any_zlib")] pub fn set_level(&mut self, level: Compression) -> Result<(), CompressError> { - use libc::c_int; + use std::os::raw::c_int; let stream = &mut *self.inner.inner.stream_wrapper; stream.msg = std::ptr::null_mut(); @@ -367,7 +367,7 @@ impl Compress { self.compress(input, out, flush) }; output.set_len((self.total_out() - before) as usize + len); - return ret; + ret } } } @@ -411,7 +411,7 @@ impl Decompress { /// Creates a new object ready for decompressing data that it's given. /// - /// The Deompress object produced by this constructor expects gzip headers + /// The Decompress object produced by this constructor expects gzip headers /// for the compressed data. /// /// # Panics @@ -508,7 +508,7 @@ impl Decompress { self.decompress(input, out, flush) }; output.set_len((self.total_out() - before) as usize + len); - return ret; + ret } } @@ -518,7 +518,7 @@ impl Decompress { let stream = &mut *self.inner.inner.stream_wrapper; stream.msg = std::ptr::null_mut(); let rc = unsafe { - assert!(dictionary.len() < ffi::uInt::max_value() as usize); + assert!(dictionary.len() < ffi::uInt::MAX as usize); ffi::inflateSetDictionary(stream, dictionary.as_ptr(), dictionary.len() as ffi::uInt) }; @@ -143,7 +143,9 @@ where // then we need to keep asking for more data because if we // return that 0 bytes of data have been read then it will // be interpreted as EOF. - Ok(Status::Ok) | Ok(Status::BufError) if read == 0 && !eof && dst.len() > 0 => continue, + Ok(Status::Ok) | Ok(Status::BufError) if read == 0 && !eof && !dst.is_empty() => { + continue + } Ok(Status::Ok) | Ok(Status::BufError) | Ok(Status::StreamEnd) => return Ok(read), Err(..) => { @@ -216,13 +218,9 @@ impl<W: Write, D: Ops> Writer<W, D> { let before_in = self.data.total_in(); let ret = self.data.run_vec(buf, &mut self.buf, D::Flush::none()); let written = (self.data.total_in() - before_in) as usize; + let is_stream_end = matches!(ret, Ok(Status::StreamEnd)); - let is_stream_end = match ret { - Ok(Status::StreamEnd) => true, - _ => false, - }; - - if buf.len() > 0 && written == 0 && ret.is_ok() && !is_stream_end { + if !buf.is_empty() && written == 0 && ret.is_ok() && !is_stream_end { continue; } return match ret { @@ -240,7 +238,7 @@ impl<W: Write, D: Ops> Writer<W, D> { fn dump(&mut self) -> io::Result<()> { // TODO: should manage this buffer not with `drain` but probably more of // a deque-like strategy. - while self.buf.len() > 0 { + while !self.buf.is_empty() { let n = self.obj.as_mut().unwrap().write(&self.buf)?; if n == 0 { return Err(io::ErrorKind::WriteZero.into()); diff --git a/src/zlib/bufread.rs b/src/zlib/bufread.rs index 182f064..f1d3231 100644 --- a/src/zlib/bufread.rs +++ b/src/zlib/bufread.rs @@ -2,11 +2,6 @@ use std::io; use std::io::prelude::*; use std::mem; -#[cfg(feature = "tokio")] -use futures::Poll; -#[cfg(feature = "tokio")] -use tokio_io::{AsyncRead, AsyncWrite}; - use crate::zio; use crate::{Compress, Decompress}; @@ -112,9 +107,6 @@ impl<R: BufRead> Read for ZlibEncoder<R> { } } -#[cfg(feature = "tokio")] -impl<R: AsyncRead + BufRead> AsyncRead for ZlibEncoder<R> {} - impl<R: BufRead + Write> Write for ZlibEncoder<R> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.get_mut().write(buf) @@ -125,13 +117,6 @@ impl<R: BufRead + Write> Write for ZlibEncoder<R> { } } -#[cfg(feature = "tokio")] -impl<R: AsyncWrite + BufRead> AsyncWrite for ZlibEncoder<R> { - fn shutdown(&mut self) -> Poll<(), io::Error> { - self.get_mut().shutdown() - } -} - /// A ZLIB decoder, or decompressor. /// /// This structure consumes a [`BufRead`] interface, reading compressed data @@ -237,9 +222,6 @@ impl<R: BufRead> Read for ZlibDecoder<R> { } } -#[cfg(feature = "tokio")] -impl<R: AsyncRead + BufRead> AsyncRead for ZlibDecoder<R> {} - impl<R: BufRead + Write> Write for ZlibDecoder<R> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.get_mut().write(buf) @@ -249,10 +231,3 @@ impl<R: BufRead + Write> Write for ZlibDecoder<R> { self.get_mut().flush() } } - -#[cfg(feature = "tokio")] -impl<R: AsyncWrite + BufRead> AsyncWrite for ZlibDecoder<R> { - fn shutdown(&mut self) -> Poll<(), io::Error> { - self.get_mut().shutdown() - } -} diff --git a/src/zlib/mod.rs b/src/zlib/mod.rs index 1813a4e..9d3de95 100644 --- a/src/zlib/mod.rs +++ b/src/zlib/mod.rs @@ -18,7 +18,7 @@ mod tests { let mut w = write::ZlibEncoder::new(Vec::new(), Compression::default()); let v = crate::random_bytes().take(1024).collect::<Vec<_>>(); for _ in 0..200 { - let to_write = &v[..thread_rng().gen_range(0, v.len())]; + let to_write = &v[..thread_rng().gen_range(0..v.len())]; real.extend(to_write.iter().map(|x| *x)); w.write_all(to_write).unwrap(); } @@ -47,7 +47,7 @@ mod tests { let mut w = write::ZlibEncoder::new(Vec::new(), Compression::default()); let v = crate::random_bytes().take(1024).collect::<Vec<_>>(); for _ in 0..200 { - let to_write = &v[..thread_rng().gen_range(0, v.len())]; + let to_write = &v[..thread_rng().gen_range(0..v.len())]; real.extend(to_write.iter().map(|x| *x)); w.write_all(to_write).unwrap(); } diff --git a/src/zlib/read.rs b/src/zlib/read.rs index 43f3502..5094931 100644 --- a/src/zlib/read.rs +++ b/src/zlib/read.rs @@ -1,11 +1,6 @@ use std::io; use std::io::prelude::*; -#[cfg(feature = "tokio")] -use futures::Poll; -#[cfg(feature = "tokio")] -use tokio_io::{AsyncRead, AsyncWrite}; - use super::bufread; use crate::bufreader::BufReader; @@ -110,9 +105,6 @@ impl<R: Read> Read for ZlibEncoder<R> { } } -#[cfg(feature = "tokio")] -impl<R: AsyncRead> AsyncRead for ZlibEncoder<R> {} - impl<W: Read + Write> Write for ZlibEncoder<W> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.get_mut().write(buf) @@ -123,13 +115,6 @@ impl<W: Read + Write> Write for ZlibEncoder<W> { } } -#[cfg(feature = "tokio")] -impl<R: AsyncRead + AsyncWrite> AsyncWrite for ZlibEncoder<R> { - fn shutdown(&mut self) -> Poll<(), io::Error> { - self.get_mut().shutdown() - } -} - /// A ZLIB decoder, or decompressor. /// /// This structure implements a [`Read`] interface and takes a stream of @@ -244,9 +229,6 @@ impl<R: Read> Read for ZlibDecoder<R> { } } -#[cfg(feature = "tokio")] -impl<R: AsyncRead> AsyncRead for ZlibDecoder<R> {} - impl<R: Read + Write> Write for ZlibDecoder<R> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.get_mut().write(buf) @@ -256,10 +238,3 @@ impl<R: Read + Write> Write for ZlibDecoder<R> { self.get_mut().flush() } } - -#[cfg(feature = "tokio")] -impl<R: AsyncWrite + AsyncRead> AsyncWrite for ZlibDecoder<R> { - fn shutdown(&mut self) -> Poll<(), io::Error> { - self.get_mut().shutdown() - } -} diff --git a/src/zlib/write.rs b/src/zlib/write.rs index 7135c34..c671814 100644 --- a/src/zlib/write.rs +++ b/src/zlib/write.rs @@ -1,11 +1,6 @@ use std::io; use std::io::prelude::*; -#[cfg(feature = "tokio")] -use futures::Poll; -#[cfg(feature = "tokio")] -use tokio_io::{AsyncRead, AsyncWrite}; - use crate::zio; use crate::{Compress, Decompress}; @@ -139,7 +134,7 @@ impl<W: Write> ZlibEncoder<W> { Ok(self.inner.take_inner()) } - /// Returns the number of bytes that have been written to this compresor. + /// Returns the number of bytes that have been written to this compressor. /// /// Note that not all bytes written to this object may be accounted for, /// there may still be some active buffering. @@ -166,23 +161,12 @@ impl<W: Write> Write for ZlibEncoder<W> { } } -#[cfg(feature = "tokio")] -impl<W: AsyncWrite> AsyncWrite for ZlibEncoder<W> { - fn shutdown(&mut self) -> Poll<(), io::Error> { - self.try_finish()?; - self.get_mut().shutdown() - } -} - impl<W: Read + Write> Read for ZlibEncoder<W> { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.get_mut().read(buf) } } -#[cfg(feature = "tokio")] -impl<W: AsyncRead + AsyncWrite> AsyncRead for ZlibEncoder<W> {} - /// A ZLIB decoder, or decompressor. /// /// This structure implements a [`Write`] and will emit a stream of decompressed @@ -330,19 +314,8 @@ impl<W: Write> Write for ZlibDecoder<W> { } } -#[cfg(feature = "tokio")] -impl<W: AsyncWrite> AsyncWrite for ZlibDecoder<W> { - fn shutdown(&mut self) -> Poll<(), io::Error> { - self.inner.finish()?; - self.inner.get_mut().shutdown() - } -} - impl<W: Read + Write> Read for ZlibDecoder<W> { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.inner.get_mut().read(buf) } } - -#[cfg(feature = "tokio")] -impl<W: AsyncRead + AsyncWrite> AsyncRead for ZlibDecoder<W> {} diff --git a/tests/async-reader.rs b/tests/async-reader.rs deleted file mode 100644 index 16dae65..0000000 --- a/tests/async-reader.rs +++ /dev/null @@ -1,96 +0,0 @@ -extern crate flate2; -extern crate futures; -extern crate tokio_io; - -use flate2::read::{GzDecoder, MultiGzDecoder}; -use futures::prelude::*; -use futures::task; -use std::cmp; -use std::fs::File; -use std::io::{self, Read}; -use tokio_io::io::read_to_end; -use tokio_io::AsyncRead; - -struct BadReader<T> { - reader: T, - x: bool, -} - -impl<T> BadReader<T> { - fn new(reader: T) -> BadReader<T> { - BadReader { reader, x: true } - } -} - -impl<T: Read> Read for BadReader<T> { - fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { - if self.x { - self.x = false; - let len = cmp::min(buf.len(), 1); - self.reader.read(&mut buf[..len]) - } else { - self.x = true; - Err(io::ErrorKind::WouldBlock.into()) - } - } -} - -struct AssertAsync<T>(T); - -impl<T: Read> Read for AssertAsync<T> { - fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { - self.0.read(buf) - } -} - -impl<T: Read> AsyncRead for AssertAsync<T> {} - -struct AlwaysNotify<T>(T); - -impl<T: Future> Future for AlwaysNotify<T> { - type Item = T::Item; - type Error = T::Error; - - fn poll(&mut self) -> Poll<Self::Item, Self::Error> { - let ret = self.0.poll(); - if let Ok(Async::NotReady) = &ret { - task::current().notify(); - } - ret - } -} - -#[test] -fn test_gz_asyncread() { - let f = File::open("tests/good-file.gz").unwrap(); - - let fut = read_to_end(AssertAsync(GzDecoder::new(BadReader::new(f))), Vec::new()); - let (_, content) = AlwaysNotify(fut).wait().unwrap(); - - let mut expected = Vec::new(); - File::open("tests/good-file.txt") - .unwrap() - .read_to_end(&mut expected) - .unwrap(); - - assert_eq!(content, expected); -} - -#[test] -fn test_multi_gz_asyncread() { - let f = File::open("tests/multi.gz").unwrap(); - - let fut = read_to_end( - AssertAsync(MultiGzDecoder::new(BadReader::new(f))), - Vec::new(), - ); - let (_, content) = AlwaysNotify(fut).wait().unwrap(); - - let mut expected = Vec::new(); - File::open("tests/multi.txt") - .unwrap() - .read_to_end(&mut expected) - .unwrap(); - - assert_eq!(content, expected); -} diff --git a/tests/tokio.rs b/tests/tokio.rs deleted file mode 100644 index 0f73646..0000000 --- a/tests/tokio.rs +++ /dev/null @@ -1,133 +0,0 @@ -#![cfg(feature = "tokio")] - -extern crate flate2; -extern crate futures; -extern crate rand; -extern crate tokio_io; -extern crate tokio_tcp; -extern crate tokio_threadpool; - -use std::io::{Read, Write}; -use std::iter; -use std::net::{Shutdown, TcpListener}; -use std::thread; - -use flate2::read; -use flate2::write; -use flate2::Compression; -use futures::Future; -use rand::{thread_rng, Rng}; -use tokio_io::io::{copy, shutdown}; -use tokio_io::AsyncRead; -use tokio_tcp::TcpStream; - -#[test] -fn tcp_stream_echo_pattern() { - const N: u8 = 16; - const M: usize = 16 * 1024; - - let listener = TcpListener::bind("127.0.0.1:0").unwrap(); - let addr = listener.local_addr().unwrap(); - let t = thread::spawn(move || { - let a = listener.accept().unwrap().0; - let b = a.try_clone().unwrap(); - - let t = thread::spawn(move || { - let mut b = read::DeflateDecoder::new(b); - let mut buf = [0; M]; - for i in 0..N { - b.read_exact(&mut buf).unwrap(); - for byte in buf.iter() { - assert_eq!(*byte, i); - } - } - - assert_eq!(b.read(&mut buf).unwrap(), 0); - }); - - let mut a = write::ZlibEncoder::new(a, Compression::default()); - for i in 0..N { - let buf = [i; M]; - a.write_all(&buf).unwrap(); - } - a.finish().unwrap().shutdown(Shutdown::Write).unwrap(); - - t.join().unwrap(); - }); - - let stream = TcpStream::connect(&addr); - let copy = stream - .and_then(|s| { - let (a, b) = s.split(); - let a = read::ZlibDecoder::new(a); - let b = write::DeflateEncoder::new(b, Compression::default()); - copy(a, b) - }) - .then(|result| { - let (amt, _a, b) = result.unwrap(); - assert_eq!(amt, (N as u64) * (M as u64)); - shutdown(b).map(|_| ()) - }) - .map_err(|err| panic!("{}", err)); - - let threadpool = tokio_threadpool::Builder::new().build(); - threadpool.spawn(copy); - threadpool.shutdown().wait().unwrap(); - t.join().unwrap(); -} - -#[test] -fn echo_random() { - let v = iter::repeat(()) - .take(1024 * 1024) - .map(|()| thread_rng().gen::<u8>()) - .collect::<Vec<_>>(); - let listener = TcpListener::bind("127.0.0.1:0").unwrap(); - let addr = listener.local_addr().unwrap(); - let v2 = v.clone(); - let t = thread::spawn(move || { - let a = listener.accept().unwrap().0; - let b = a.try_clone().unwrap(); - - let mut v3 = v2.clone(); - let t = thread::spawn(move || { - let mut b = read::DeflateDecoder::new(b); - let mut buf = [0; 1024]; - while v3.len() > 0 { - let n = b.read(&mut buf).unwrap(); - for (actual, expected) in buf[..n].iter().zip(&v3) { - assert_eq!(*actual, *expected); - } - v3.drain(..n); - } - - assert_eq!(b.read(&mut buf).unwrap(), 0); - }); - - let mut a = write::ZlibEncoder::new(a, Compression::default()); - a.write_all(&v2).unwrap(); - a.finish().unwrap().shutdown(Shutdown::Write).unwrap(); - - t.join().unwrap(); - }); - - let stream = TcpStream::connect(&addr); - let copy = stream - .and_then(|s| { - let (a, b) = s.split(); - let a = read::ZlibDecoder::new(a); - let b = write::DeflateEncoder::new(b, Compression::default()); - copy(a, b) - }) - .then(move |result| { - let (amt, _a, b) = result.unwrap(); - assert_eq!(amt, v.len() as u64); - shutdown(b).map(|_| ()) - }) - .map_err(|err| panic!("{}", err)); - - let threadpool = tokio_threadpool::Builder::new().build(); - threadpool.spawn(copy); - threadpool.shutdown().wait().unwrap(); - t.join().unwrap(); -} |