Initial vendor packages

Signed-off-by: Valentin Popov <valentin@popov.link>
This commit is contained in:
2024-01-08 01:21:28 +04:00
parent 5ecd8cf2cb
commit 1b6a04ca55
7309 changed files with 2160054 additions and 0 deletions

1
vendor/flate2/.cargo-checksum.json vendored Normal file

File diff suppressed because one or more lines are too long

173
vendor/flate2/Cargo.lock generated vendored Normal file
View File

@ -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.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
[[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.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130"
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.28"
dependencies = [
"cloudflare-zlib-sys",
"crc32fast",
"libz-ng-sys",
"libz-sys",
"miniz_oxide",
"quickcheck",
"rand",
]
[[package]]
name = "getrandom"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "libc"
version = "0.2.144"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1"
[[package]]
name = "libz-ng-sys"
version = "1.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "425fb6808068335c8c7c69d1cff0a7d1ed8f681e9ac040272f160a89e6f43b8b"
dependencies = [
"cmake",
"libc",
]
[[package]]
name = "libz-sys"
version = "1.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24e6ab01971eb092ffe6a7d42f49f9ff42662f17604681e2843ad65077ba47dc"
dependencies = [
"cc",
"cmake",
"libc",
"pkg-config",
"vcpkg",
]
[[package]]
name = "miniz_oxide"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
dependencies = [
"adler",
]
[[package]]
name = "pkg-config"
version = "0.3.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
[[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"

111
vendor/flate2/Cargo.toml vendored Normal file
View File

@ -0,0 +1,111 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g., crates.io) dependencies.
#
# If you are reading this file be aware that the original Cargo.toml
# will likely look very different (and much more reasonable).
# See Cargo.toml.orig for the original contents.
[package]
edition = "2018"
name = "flate2"
version = "1.0.28"
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 OR Apache-2.0"
repository = "https://github.com/rust-lang/flate2-rs"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = [
"--cfg",
"docsrs",
]
[dependencies.cloudflare-zlib-sys]
version = "0.3.0"
optional = true
[dependencies.crc32fast]
version = "1.2.0"
[dependencies.libz-ng-sys]
version = "1.1.8"
optional = true
[dependencies.libz-sys]
version = "1.1.8"
optional = true
default-features = false
[dependencies.miniz_oxide]
version = "0.7.1"
features = ["with-alloc"]
optional = true
default-features = false
[dev-dependencies.quickcheck]
version = "1.0"
default-features = false
[dev-dependencies.rand]
version = "0.8"
[features]
any_impl = []
any_zlib = ["any_impl"]
cloudflare_zlib = [
"any_zlib",
"cloudflare-zlib-sys",
]
default = ["rust_backend"]
miniz-sys = ["rust_backend"]
rust_backend = [
"miniz_oxide",
"any_impl",
]
zlib = [
"any_zlib",
"libz-sys",
]
zlib-default = [
"any_zlib",
"libz-sys/default",
]
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.7.1"
features = ["with-alloc"]
default-features = false

201
vendor/flate2/LICENSE-APACHE vendored Normal file
View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

25
vendor/flate2/LICENSE-MIT vendored Normal file
View File

@ -0,0 +1,25 @@
Copyright (c) 2014 Alex Crichton
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

21
vendor/flate2/MAINTENANCE.md vendored Normal file
View File

@ -0,0 +1,21 @@
This document explains how to perform the project's maintenance tasks.
### Creating a new release
#### Artifacts
* a tag of the version number
* a new [crate version](https://crates.io/crates/flate2/versions)
#### Process
To generate all the artifacts above, one proceeds as follows:
1. `git checkout -b release-<next-version>` - move to a branch to prepare making changes to the repository. *Changes cannot be made to `main` as it is protected.*
2. Edit `Cargo.toml` to the next package version.
3. `gh pr create` to create a new PR for the current branch and **get it merged**.
4. `cargo publish` to create a new release on `crates.io`.
5. `git tag <next-version>` to remember the commit.
6. `git push --tags` to push the new tag.
7. Go to the newly created release page on GitHub and edit it by pressing the "Generate Release Notes" and the `@` button. Save the release.

120
vendor/flate2/README.md vendored Normal file
View File

@ -0,0 +1,120 @@
# flate2
[![Crates.io](https://img.shields.io/crates/v/flate2.svg?maxAge=2592000)](https://crates.io/crates/flate2)
[![Documentation](https://docs.rs/flate2/badge.svg)](https://docs.rs/flate2)
A streaming compression/decompression library DEFLATE-based streams in Rust.
This crate by default uses the `miniz_oxide` crate, a port of `miniz.c` to pure
Rust. This crate also supports other [backends](#backends), such as the widely
available zlib library or the high-performance zlib-ng library.
Supported formats:
* deflate
* zlib
* gzip
```toml
# Cargo.toml
[dependencies]
flate2 = "1.0"
```
## MSRV (Minimum Supported Rust Version) Policy
This crate supports the current stable and the last stable for the latest version.
For example, if the current stable is 1.64, this crate supports 1.64 and 1.63.
Older stables may work, but we don't guarantee these will continue to work.
## Compression
```rust
use std::io::prelude::*;
use flate2::Compression;
use flate2::write::ZlibEncoder;
fn main() {
let mut e = ZlibEncoder::new(Vec::new(), Compression::default());
e.write_all(b"foo");
e.write_all(b"bar");
let compressed_bytes = e.finish();
}
```
## Decompression
```rust,no_run
use std::io::prelude::*;
use flate2::read::GzDecoder;
fn main() {
let mut d = GzDecoder::new("...".as_bytes());
let mut s = String::new();
d.read_to_string(&mut s).unwrap();
println!("{}", s);
}
```
## Backends
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
[dependencies]
flate2 = { version = "1.0.17", features = ["zlib"], default-features = false }
```
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 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
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 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.
# License
This project is licensed under either of
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
https://www.apache.org/licenses/LICENSE-2.0)
* MIT license ([LICENSE-MIT](LICENSE-MIT) or
https://opensource.org/licenses/MIT)
at your option.
### Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in this project by you, as defined in the Apache-2.0 license,
shall be dual licensed as above, without any additional terms or conditions.

26
vendor/flate2/examples/compress_file.rs vendored Normal file
View File

@ -0,0 +1,26 @@
use flate2::write::GzEncoder;
use flate2::Compression;
use std::env::args;
use std::fs::File;
use std::io::copy;
use std::io::BufReader;
use std::time::Instant;
fn main() {
if args().len() != 3 {
eprintln!("Usage: ./compress_file `source` `target`");
return;
}
let mut input = BufReader::new(File::open(args().nth(1).unwrap()).unwrap());
let output = File::create(args().nth(2).unwrap()).unwrap();
let mut encoder = GzEncoder::new(output, Compression::default());
let start = Instant::now();
copy(&mut input, &mut encoder).unwrap();
let output = encoder.finish().unwrap();
println!(
"Source len: {:?}",
input.get_ref().metadata().unwrap().len()
);
println!("Target len: {:?}", output.metadata().unwrap().len());
println!("Elapsed: {:?}", start.elapsed());
}

View File

@ -0,0 +1,23 @@
use flate2::bufread;
use std::env::args;
use std::fs::File;
use std::io::copy;
use std::io::BufReader;
use std::time::Instant;
fn main() {
// E.g. `cargo run --example decompress_file examples/hello_world.txt.gz hello_world.txt`
if args().len() != 3 {
eprintln!("Usage: ./decompress_file `source` `target`");
return;
}
let input = BufReader::new(File::open(args().nth(1).unwrap()).unwrap());
let mut output = File::create(args().nth(2).unwrap()).unwrap();
let source_len = input.get_ref().metadata().unwrap().len();
let start = Instant::now();
let mut decoder = bufread::GzDecoder::new(input);
copy(&mut decoder, &mut output).unwrap();
println!("Source len: {:?}", source_len);
println!("Target len: {:?}", output.metadata().unwrap().len());
println!("Elapsed: {:?}", start.elapsed());
}

View File

@ -0,0 +1,22 @@
use flate2::bufread::DeflateDecoder;
use flate2::write::DeflateEncoder;
use flate2::Compression;
use std::io;
use std::io::prelude::*;
// Compress a sample string and print it after transformation.
fn main() {
let mut e = DeflateEncoder::new(Vec::new(), Compression::default());
e.write_all(b"Hello World").unwrap();
let bytes = e.finish().unwrap();
println!("{}", decode_reader(bytes).unwrap());
}
// Uncompresses a Deflate 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 deflater = DeflateDecoder::new(&bytes[..]);
let mut s = String::new();
deflater.read_to_string(&mut s)?;
Ok(s)
}

View File

@ -0,0 +1,22 @@
use flate2::read::DeflateDecoder;
use flate2::write::DeflateEncoder;
use flate2::Compression;
use std::io;
use std::io::prelude::*;
// Compress a sample string and print it after transformation.
fn main() {
let mut e = DeflateEncoder::new(Vec::new(), Compression::default());
e.write_all(b"Hello World").unwrap();
let bytes = e.finish().unwrap();
println!("{}", decode_reader(bytes).unwrap());
}
// Uncompresses a Deflate 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 deflater = DeflateDecoder::new(&bytes[..]);
let mut s = String::new();
deflater.read_to_string(&mut s)?;
Ok(s)
}

View File

@ -0,0 +1,24 @@
use flate2::write::DeflateDecoder;
use flate2::write::DeflateEncoder;
use flate2::Compression;
use std::io;
use std::io::prelude::*;
// Compress a sample string and print it after transformation.
fn main() {
let mut e = DeflateEncoder::new(Vec::new(), Compression::default());
e.write_all(b"Hello World").unwrap();
let bytes = e.finish().unwrap();
println!("{}", decode_reader(bytes).unwrap());
}
// Uncompresses a Deflate Encoded vector of bytes and returns a string or error
// Here Vec<u8> implements Write
fn decode_reader(bytes: Vec<u8>) -> io::Result<String> {
let mut writer = Vec::new();
let mut deflater = DeflateDecoder::new(writer);
deflater.write_all(&bytes[..])?;
writer = deflater.finish()?;
let return_string = String::from_utf8(writer).expect("String parsing error");
Ok(return_string)
}

View File

@ -0,0 +1,22 @@
use flate2::bufread::DeflateEncoder;
use flate2::Compression;
use std::fs::File;
use std::io;
use std::io::prelude::*;
use std::io::BufReader;
// Open file and debug print the contents compressed with Deflate
fn main() {
println!("{:?}", open_hello_world().unwrap());
}
// Opens sample file, compresses the contents and returns a Vector or error
// File wrapped in a BufReader implements Bufread
fn open_hello_world() -> io::Result<Vec<u8>> {
let f = File::open("examples/hello_world.txt")?;
let b = BufReader::new(f);
let mut deflater = DeflateEncoder::new(b, Compression::fast());
let mut buffer = Vec::new();
deflater.read_to_end(&mut buffer)?;
Ok(buffer)
}

View File

@ -0,0 +1,18 @@
use flate2::read::DeflateEncoder;
use flate2::Compression;
use std::io;
use std::io::prelude::*;
// Print the Deflate compressed representation of hello world
fn main() {
println!("{:?}", deflateencoder_read_hello_world().unwrap());
}
// 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";
let mut deflater = DeflateEncoder::new(&c[..], Compression::fast());
deflater.read_to_end(&mut result)?;
Ok(result)
}

View File

@ -0,0 +1,10 @@
use flate2::write::DeflateEncoder;
use flate2::Compression;
use std::io::prelude::*;
// Vec<u8> implements Write to print the compressed bytes of sample string
fn main() {
let mut e = DeflateEncoder::new(Vec::new(), Compression::default());
e.write_all(b"Hello World").unwrap();
println!("{:?}", e.finish().unwrap());
}

22
vendor/flate2/examples/gzbuilder.rs vendored Normal file
View File

@ -0,0 +1,22 @@
use flate2::Compression;
use flate2::GzBuilder;
use std::fs::File;
use std::io;
use std::io::prelude::*;
// 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.txt.gz")?;
let mut gz = GzBuilder::new()
.filename("hello_world.txt")
.comment("test file, please delete")
.write(f, Compression::default());
gz.write_all(b"hello world")?;
gz.finish()?;
Ok(())
}

View File

@ -0,0 +1,21 @@
use flate2::write::GzEncoder;
use flate2::{bufread, Compression};
use std::io;
use std::io::prelude::*;
// Compress a sample string and print it after transformation.
fn main() {
let mut e = GzEncoder::new(Vec::new(), Compression::default());
e.write_all(b"Hello World").unwrap();
let bytes = e.finish().unwrap();
println!("{}", decode_reader(bytes).unwrap());
}
// 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 = bufread::GzDecoder::new(&bytes[..]);
let mut s = String::new();
gz.read_to_string(&mut s)?;
Ok(s)
}

View File

@ -0,0 +1,21 @@
use flate2::write::GzEncoder;
use flate2::{read, Compression};
use std::io;
use std::io::prelude::*;
// Compress a sample string and print it after transformation.
fn main() {
let mut e = GzEncoder::new(Vec::new(), Compression::default());
e.write_all(b"Hello World").unwrap();
let bytes = e.finish().unwrap();
println!("{}", decode_reader(bytes).unwrap());
}
// 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 = read::GzDecoder::new(&bytes[..]);
let mut s = String::new();
gz.read_to_string(&mut s)?;
Ok(s)
}

View File

@ -0,0 +1,24 @@
use flate2::write::{GzDecoder, GzEncoder};
use flate2::Compression;
use std::io;
use std::io::prelude::*;
// Compress a sample string and print it after transformation.
fn main() {
let mut e = GzEncoder::new(Vec::new(), Compression::default());
e.write_all(b"Hello World").unwrap();
let bytes = e.finish().unwrap();
println!("{}", decode_writer(bytes).unwrap());
}
// Uncompresses a Gz Encoded vector of bytes and returns a string or error
// Here &[u8] implements Read
fn decode_writer(bytes: Vec<u8>) -> io::Result<String> {
let mut writer = Vec::new();
let mut decoder = GzDecoder::new(writer);
decoder.write_all(&bytes[..])?;
decoder.try_finish()?;
writer = decoder.finish()?;
let return_string = String::from_utf8(writer).expect("String parsing error");
Ok(return_string)
}

View File

@ -0,0 +1,22 @@
use flate2::bufread::GzEncoder;
use flate2::Compression;
use std::fs::File;
use std::io;
use std::io::prelude::*;
use std::io::BufReader;
// Open file and debug print the contents compressed with gzip
fn main() {
println!("{:?}", open_hello_world().unwrap());
}
// Opens sample file, compresses the contents and returns a Vector or error
// File wrapped in a BufReader implements Bufread
fn open_hello_world() -> io::Result<Vec<u8>> {
let f = File::open("examples/hello_world.txt")?;
let b = BufReader::new(f);
let mut gz = GzEncoder::new(b, Compression::fast());
let mut buffer = Vec::new();
gz.read_to_end(&mut buffer)?;
Ok(buffer)
}

View File

@ -0,0 +1,18 @@
use flate2::read::GzEncoder;
use flate2::Compression;
use std::io;
use std::io::prelude::*;
// Print the GZ compressed representation of hello world
fn main() {
println!("{:?}", gzencoder_read_hello_world().unwrap());
}
// Return a vector containing the GZ compressed version of hello world
fn gzencoder_read_hello_world() -> io::Result<Vec<u8>> {
let mut result = Vec::new();
let c = b"hello world";
let mut z = GzEncoder::new(&c[..], Compression::fast());
z.read_to_end(&mut result)?;
Ok(result)
}

View File

@ -0,0 +1,10 @@
use flate2::write::GzEncoder;
use flate2::Compression;
use std::io::prelude::*;
// Vec<u8> implements Write to print the compressed bytes of sample string
fn main() {
let mut e = GzEncoder::new(Vec::new(), Compression::default());
e.write_all(b"Hello World").unwrap();
println!("{:?}", e.finish().unwrap());
}

View File

@ -0,0 +1,22 @@
use flate2::bufread::MultiGzDecoder;
use flate2::write::GzEncoder;
use flate2::Compression;
use std::io;
use std::io::prelude::*;
// Compress a sample string and print it after transformation.
fn main() {
let mut e = GzEncoder::new(Vec::new(), Compression::default());
e.write_all(b"Hello World").unwrap();
let bytes = e.finish().unwrap();
println!("{}", decode_reader(bytes).unwrap());
}
// 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 = MultiGzDecoder::new(&bytes[..]);
let mut s = String::new();
gz.read_to_string(&mut s)?;
Ok(s)
}

View File

@ -0,0 +1,22 @@
use flate2::read::MultiGzDecoder;
use flate2::write::GzEncoder;
use flate2::Compression;
use std::io;
use std::io::prelude::*;
// Compress a sample string and print it after transformation.
fn main() {
let mut e = GzEncoder::new(Vec::new(), Compression::default());
e.write_all(b"Hello World").unwrap();
let bytes = e.finish().unwrap();
println!("{}", decode_reader(bytes).unwrap());
}
// 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 = MultiGzDecoder::new(&bytes[..]);
let mut s = String::new();
gz.read_to_string(&mut s)?;
Ok(s)
}

View File

@ -0,0 +1 @@
Hello World

Binary file not shown.

View File

@ -0,0 +1,22 @@
use flate2::bufread::ZlibDecoder;
use flate2::write::ZlibEncoder;
use flate2::Compression;
use std::io;
use std::io::prelude::*;
// Compress a sample string and print it after transformation.
fn main() {
let mut e = ZlibEncoder::new(Vec::new(), Compression::default());
e.write_all(b"Hello World").unwrap();
let bytes = e.finish().unwrap();
println!("{}", decode_bufreader(bytes).unwrap());
}
// Uncompresses a Zlib Encoded vector of bytes and returns a string or error
// Here &[u8] implements BufRead
fn decode_bufreader(bytes: Vec<u8>) -> io::Result<String> {
let mut z = ZlibDecoder::new(&bytes[..]);
let mut s = String::new();
z.read_to_string(&mut s)?;
Ok(s)
}

View File

@ -0,0 +1,22 @@
use flate2::read::ZlibDecoder;
use flate2::write::ZlibEncoder;
use flate2::Compression;
use std::io;
use std::io::prelude::*;
// Compress a sample string and print it after transformation.
fn main() {
let mut e = ZlibEncoder::new(Vec::new(), Compression::default());
e.write_all(b"Hello World").unwrap();
let bytes = e.finish().unwrap();
println!("{}", decode_reader(bytes).unwrap());
}
// Uncompresses a Zlib 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 z = ZlibDecoder::new(&bytes[..]);
let mut s = String::new();
z.read_to_string(&mut s)?;
Ok(s)
}

View File

@ -0,0 +1,24 @@
use flate2::write::ZlibDecoder;
use flate2::write::ZlibEncoder;
use flate2::Compression;
use std::io;
use std::io::prelude::*;
// Compress a sample string and print it after transformation.
fn main() {
let mut e = ZlibEncoder::new(Vec::new(), Compression::default());
e.write_all(b"Hello World").unwrap();
let bytes = e.finish().unwrap();
println!("{}", decode_reader(bytes).unwrap());
}
// Uncompresses a Zlib Encoded vector of bytes and returns a string or error
// Here Vec<u8> implements Write
fn decode_reader(bytes: Vec<u8>) -> io::Result<String> {
let mut writer = Vec::new();
let mut z = ZlibDecoder::new(writer);
z.write_all(&bytes[..])?;
writer = z.finish()?;
let return_string = String::from_utf8(writer).expect("String parsing error");
Ok(return_string)
}

View File

@ -0,0 +1,22 @@
use flate2::bufread::ZlibEncoder;
use flate2::Compression;
use std::fs::File;
use std::io;
use std::io::prelude::*;
use std::io::BufReader;
// Open file and debug print the contents compressed with zlib
fn main() {
println!("{:?}", open_hello_world().unwrap());
}
// Opens sample file, compresses the contents and returns a Vector or error
// File wrapped in a BufReader implements Bufread
fn open_hello_world() -> io::Result<Vec<u8>> {
let f = File::open("examples/hello_world.txt")?;
let b = BufReader::new(f);
let mut z = ZlibEncoder::new(b, Compression::fast());
let mut buffer = Vec::new();
z.read_to_end(&mut buffer)?;
Ok(buffer)
}

View File

@ -0,0 +1,19 @@
use flate2::read::ZlibEncoder;
use flate2::Compression;
use std::fs::File;
use std::io::prelude::*;
// Open file and debug print the compressed contents
fn main() {
println!("{:?}", open_hello_world().unwrap());
}
// Opens sample file, compresses the contents and returns a Vector or error
// File implements Read
fn open_hello_world() -> std::io::Result<Vec<u8>> {
let f = File::open("examples/hello_world.txt")?;
let mut z = ZlibEncoder::new(f, Compression::fast());
let mut result = Vec::new();
z.read_to_end(&mut result)?;
Ok(result)
}

View File

@ -0,0 +1,10 @@
use flate2::write::ZlibEncoder;
use flate2::Compression;
use std::io::prelude::*;
// Vec<u8> implements Write to print the compressed bytes of sample string
fn main() {
let mut e = ZlibEncoder::new(Vec::new(), Compression::default());
e.write_all(b"Hello World").unwrap();
println!("{:?}", e.finish().unwrap());
}

104
vendor/flate2/src/bufreader.rs vendored Normal file
View File

@ -0,0 +1,104 @@
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// <https://github.com/rust-lang/rust/blob/HEAD/COPYRIGHT>.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// 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.
use std::cmp;
use std::io;
use std::io::prelude::*;
use std::mem;
pub struct BufReader<R> {
inner: R,
buf: Box<[u8]>,
pos: usize,
cap: usize,
}
impl<R> ::std::fmt::Debug for BufReader<R>
where
R: ::std::fmt::Debug,
{
fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
fmt.debug_struct("BufReader")
.field("reader", &self.inner)
.field(
"buffer",
&format_args!("{}/{}", self.cap - self.pos, self.buf.len()),
)
.finish()
}
}
impl<R: Read> BufReader<R> {
pub fn new(inner: R) -> BufReader<R> {
BufReader::with_buf(vec![0; 32 * 1024], inner)
}
pub fn with_buf(buf: Vec<u8>, inner: R) -> BufReader<R> {
BufReader {
inner,
buf: buf.into_boxed_slice(),
pos: 0,
cap: 0,
}
}
}
impl<R> BufReader<R> {
pub fn get_ref(&self) -> &R {
&self.inner
}
pub fn get_mut(&mut self) -> &mut R {
&mut self.inner
}
pub fn into_inner(self) -> R {
self.inner
}
pub fn reset(&mut self, inner: R) -> R {
self.pos = 0;
self.cap = 0;
mem::replace(&mut self.inner, inner)
}
}
impl<R: Read> Read for BufReader<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
// If we don't have any buffered data and we're doing a massive read
// (larger than our internal buffer), bypass our internal buffer
// entirely.
if self.pos == self.cap && buf.len() >= self.buf.len() {
return self.inner.read(buf);
}
let nread = {
let mut rem = self.fill_buf()?;
rem.read(buf)?
};
self.consume(nread);
Ok(nread)
}
}
impl<R: Read> BufRead for BufReader<R> {
fn fill_buf(&mut self) -> io::Result<&[u8]> {
// If we've reached the end of our internal buffer then we need to fetch
// some more data from the underlying reader.
if self.pos == self.cap {
self.cap = self.inner.read(&mut self.buf)?;
self.pos = 0;
}
Ok(&self.buf[self.pos..self.cap])
}
fn consume(&mut self, amt: usize) {
self.pos = cmp::min(self.pos + amt, self.cap);
}
}

184
vendor/flate2/src/crc.rs vendored Normal file
View File

@ -0,0 +1,184 @@
//! Simple CRC bindings backed by miniz.c
use std::io;
use std::io::prelude::*;
use crc32fast::Hasher;
/// The CRC calculated by a [`CrcReader`].
///
/// [`CrcReader`]: struct.CrcReader.html
#[derive(Debug)]
pub struct Crc {
amt: u32,
hasher: Hasher,
}
/// A wrapper around a [`Read`] that calculates the CRC.
///
/// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
#[derive(Debug)]
pub struct CrcReader<R> {
inner: R,
crc: Crc,
}
impl Default for Crc {
fn default() -> Self {
Self::new()
}
}
impl Crc {
/// Create a new CRC.
pub fn new() -> Crc {
Crc {
amt: 0,
hasher: Hasher::new(),
}
}
/// Returns the current crc32 checksum.
pub fn sum(&self) -> u32 {
self.hasher.clone().finalize()
}
/// The number of bytes that have been used to calculate the CRC.
/// This value is only accurate if the amount is lower than 2<sup>32</sup>.
pub fn amount(&self) -> u32 {
self.amt
}
/// Update the CRC with the bytes in `data`.
pub fn update(&mut self, data: &[u8]) {
self.amt = self.amt.wrapping_add(data.len() as u32);
self.hasher.update(data);
}
/// Reset the CRC.
pub fn reset(&mut self) {
self.amt = 0;
self.hasher.reset();
}
/// Combine the CRC with the CRC for the subsequent block of bytes.
pub fn combine(&mut self, additional_crc: &Crc) {
self.amt = self.amt.wrapping_add(additional_crc.amt);
self.hasher.combine(&additional_crc.hasher);
}
}
impl<R: Read> CrcReader<R> {
/// Create a new `CrcReader`.
pub fn new(r: R) -> CrcReader<R> {
CrcReader {
inner: r,
crc: Crc::new(),
}
}
}
impl<R> CrcReader<R> {
/// Get the Crc for this `CrcReader`.
pub fn crc(&self) -> &Crc {
&self.crc
}
/// Get the reader that is wrapped by this `CrcReader`.
pub fn into_inner(self) -> R {
self.inner
}
/// Get the reader that is wrapped by this `CrcReader` by reference.
pub fn get_ref(&self) -> &R {
&self.inner
}
/// Get a mutable reference to the reader that is wrapped by this `CrcReader`.
pub fn get_mut(&mut self) -> &mut R {
&mut self.inner
}
/// Reset the Crc in this `CrcReader`.
pub fn reset(&mut self) {
self.crc.reset();
}
}
impl<R: Read> Read for CrcReader<R> {
fn read(&mut self, into: &mut [u8]) -> io::Result<usize> {
let amt = self.inner.read(into)?;
self.crc.update(&into[..amt]);
Ok(amt)
}
}
impl<R: BufRead> BufRead for CrcReader<R> {
fn fill_buf(&mut self) -> io::Result<&[u8]> {
self.inner.fill_buf()
}
fn consume(&mut self, amt: usize) {
if let Ok(data) = self.inner.fill_buf() {
self.crc.update(&data[..amt]);
}
self.inner.consume(amt);
}
}
/// A wrapper around a [`Write`] that calculates the CRC.
///
/// [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
#[derive(Debug)]
pub struct CrcWriter<W> {
inner: W,
crc: Crc,
}
impl<W> CrcWriter<W> {
/// Get the Crc for this `CrcWriter`.
pub fn crc(&self) -> &Crc {
&self.crc
}
/// Get the writer that is wrapped by this `CrcWriter`.
pub fn into_inner(self) -> W {
self.inner
}
/// Get the writer that is wrapped by this `CrcWriter` by reference.
pub fn get_ref(&self) -> &W {
&self.inner
}
/// Get a mutable reference to the writer that is wrapped by this `CrcWriter`.
pub fn get_mut(&mut self) -> &mut W {
&mut self.inner
}
/// Reset the Crc in this `CrcWriter`.
pub fn reset(&mut self) {
self.crc.reset();
}
}
impl<W: Write> CrcWriter<W> {
/// Create a new `CrcWriter`.
pub fn new(w: W) -> CrcWriter<W> {
CrcWriter {
inner: w,
crc: Crc::new(),
}
}
}
impl<W: Write> Write for CrcWriter<W> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
let amt = self.inner.write(buf)?;
self.crc.update(&buf[..amt]);
Ok(amt)
}
fn flush(&mut self) -> io::Result<()> {
self.inner.flush()
}
}

245
vendor/flate2/src/deflate/bufread.rs vendored Normal file
View File

@ -0,0 +1,245 @@
use std::io;
use std::io::prelude::*;
use std::mem;
use crate::zio;
use crate::{Compress, Decompress};
/// A DEFLATE encoder, or compressor.
///
/// This structure implements a [`Read`] interface. When read from, it reads
/// uncompressed data from the underlying [`BufRead`] and provides the compressed data.
///
/// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
/// [`BufRead`]: https://doc.rust-lang.org/std/io/trait.BufRead.html
///
/// # Examples
///
/// ```
/// use std::io::prelude::*;
/// use std::io;
/// use flate2::Compression;
/// use flate2::bufread::DeflateEncoder;
/// use std::fs::File;
/// use std::io::BufReader;
///
/// # fn main() {
/// # println!("{:?}", open_hello_world().unwrap());
/// # }
/// #
/// // Opens sample file, compresses the contents and returns a Vector
/// fn open_hello_world() -> io::Result<Vec<u8>> {
/// let f = File::open("examples/hello_world.txt")?;
/// let b = BufReader::new(f);
/// let mut deflater = DeflateEncoder::new(b, Compression::fast());
/// let mut buffer = Vec::new();
/// deflater.read_to_end(&mut buffer)?;
/// Ok(buffer)
/// }
/// ```
#[derive(Debug)]
pub struct DeflateEncoder<R> {
obj: R,
data: Compress,
}
impl<R: BufRead> DeflateEncoder<R> {
/// Creates a new encoder which will read uncompressed data from the given
/// stream and emit the compressed stream.
pub fn new(r: R, level: crate::Compression) -> DeflateEncoder<R> {
DeflateEncoder {
obj: r,
data: Compress::new(level, false),
}
}
}
pub fn reset_encoder_data<R>(zlib: &mut DeflateEncoder<R>) {
zlib.data.reset();
}
impl<R> DeflateEncoder<R> {
/// Resets the state of this encoder entirely, swapping out the input
/// stream for another.
///
/// This function will reset the internal state of this encoder and replace
/// the input stream with the one provided, returning the previous input
/// stream. Future data read from this encoder will be the compressed
/// version of `r`'s data.
pub fn reset(&mut self, r: R) -> R {
reset_encoder_data(self);
mem::replace(&mut self.obj, r)
}
/// Acquires a reference to the underlying reader
pub fn get_ref(&self) -> &R {
&self.obj
}
/// Acquires a mutable reference to the underlying stream
///
/// Note that mutation of the stream may result in surprising results if
/// this encoder is continued to be used.
pub fn get_mut(&mut self) -> &mut R {
&mut self.obj
}
/// Consumes this encoder, returning the underlying reader.
pub fn into_inner(self) -> R {
self.obj
}
/// Returns the number of bytes that have been read into this compressor.
///
/// Note that not all bytes read from the underlying object may be accounted
/// for, there may still be some active buffering.
pub fn total_in(&self) -> u64 {
self.data.total_in()
}
/// Returns the number of bytes that the compressor has produced.
///
/// Note that not all bytes may have been read yet, some may still be
/// buffered.
pub fn total_out(&self) -> u64 {
self.data.total_out()
}
}
impl<R: BufRead> Read for DeflateEncoder<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
zio::read(&mut self.obj, &mut self.data, buf)
}
}
impl<W: BufRead + Write> Write for DeflateEncoder<W> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.get_mut().write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.get_mut().flush()
}
}
/// A DEFLATE decoder, or decompressor.
///
/// This structure implements a [`Read`] interface. When read from, it reads
/// compressed data from the underlying [`BufRead`] and provides the uncompressed data.
///
/// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
/// [`BufRead`]: https://doc.rust-lang.org/std/io/trait.BufRead.html
///
/// # Examples
///
/// ```
/// use std::io::prelude::*;
/// use std::io;
/// # use flate2::Compression;
/// # use flate2::write::DeflateEncoder;
/// use flate2::bufread::DeflateDecoder;
///
/// # fn main() {
/// # let mut e = DeflateEncoder::new(Vec::new(), Compression::default());
/// # e.write_all(b"Hello World").unwrap();
/// # let bytes = e.finish().unwrap();
/// # println!("{}", decode_reader(bytes).unwrap());
/// # }
/// // Uncompresses a Deflate 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 deflater = DeflateDecoder::new(&bytes[..]);
/// let mut s = String::new();
/// deflater.read_to_string(&mut s)?;
/// Ok(s)
/// }
/// ```
#[derive(Debug)]
pub struct DeflateDecoder<R> {
obj: R,
data: Decompress,
}
pub fn reset_decoder_data<R>(zlib: &mut DeflateDecoder<R>) {
zlib.data = Decompress::new(false);
}
impl<R: BufRead> DeflateDecoder<R> {
/// Creates a new decoder which will decompress data read from the given
/// stream.
pub fn new(r: R) -> DeflateDecoder<R> {
DeflateDecoder {
obj: r,
data: Decompress::new(false),
}
}
}
impl<R> DeflateDecoder<R> {
/// Resets the state of this decoder entirely, swapping out the input
/// stream for another.
///
/// This will reset the internal state of this decoder and replace the
/// input stream with the one provided, returning the previous input
/// stream. Future data read from this decoder will be the decompressed
/// version of `r`'s data.
pub fn reset(&mut self, r: R) -> R {
reset_decoder_data(self);
mem::replace(&mut self.obj, r)
}
/// Resets the state of this decoder's data
///
/// This will reset the internal state of this decoder. It will continue
/// reading from the same stream.
pub fn reset_data(&mut self) {
reset_decoder_data(self);
}
/// Acquires a reference to the underlying stream
pub fn get_ref(&self) -> &R {
&self.obj
}
/// Acquires a mutable reference to the underlying stream
///
/// Note that mutation of the stream may result in surprising results if
/// this decoder is continued to be used.
pub fn get_mut(&mut self) -> &mut R {
&mut self.obj
}
/// Consumes this decoder, returning the underlying reader.
pub fn into_inner(self) -> R {
self.obj
}
/// Returns the number of bytes that the decompressor has consumed.
///
/// Note that this will likely be smaller than what the decompressor
/// actually read from the underlying stream due to buffering.
pub fn total_in(&self) -> u64 {
self.data.total_in()
}
/// Returns the number of bytes that the decompressor has produced.
pub fn total_out(&self) -> u64 {
self.data.total_out()
}
}
impl<R: BufRead> Read for DeflateDecoder<R> {
fn read(&mut self, into: &mut [u8]) -> io::Result<usize> {
zio::read(&mut self.obj, &mut self.data, into)
}
}
impl<W: BufRead + Write> Write for DeflateDecoder<W> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.get_mut().write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.get_mut().flush()
}
}

193
vendor/flate2/src/deflate/mod.rs vendored Normal file
View File

@ -0,0 +1,193 @@
pub mod bufread;
pub mod read;
pub mod write;
#[cfg(test)]
mod tests {
use std::io::prelude::*;
use rand::{thread_rng, Rng};
use super::{read, write};
use crate::Compression;
#[test]
fn roundtrip() {
let mut real = Vec::new();
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())];
real.extend(to_write.iter().copied());
w.write_all(to_write).unwrap();
}
let result = w.finish().unwrap();
let mut r = read::DeflateDecoder::new(&result[..]);
let mut ret = Vec::new();
r.read_to_end(&mut ret).unwrap();
assert_eq!(ret, real);
}
#[test]
fn drop_writes() {
let mut data = Vec::new();
write::DeflateEncoder::new(&mut data, Compression::default())
.write_all(b"foo")
.unwrap();
let mut r = read::DeflateDecoder::new(&data[..]);
let mut ret = Vec::new();
r.read_to_end(&mut ret).unwrap();
assert_eq!(ret, b"foo");
}
#[test]
fn total_in() {
let mut real = Vec::new();
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())];
real.extend(to_write.iter().copied());
w.write_all(to_write).unwrap();
}
let mut result = w.finish().unwrap();
let result_len = result.len();
for _ in 0..200 {
result.extend(v.iter().copied());
}
let mut r = read::DeflateDecoder::new(&result[..]);
let mut ret = Vec::new();
r.read_to_end(&mut ret).unwrap();
assert_eq!(ret, real);
assert_eq!(r.total_in(), result_len as u64);
}
#[test]
fn roundtrip2() {
let v = crate::random_bytes().take(1024 * 1024).collect::<Vec<_>>();
let mut r =
read::DeflateDecoder::new(read::DeflateEncoder::new(&v[..], Compression::default()));
let mut ret = Vec::new();
r.read_to_end(&mut ret).unwrap();
assert_eq!(ret, v);
}
#[test]
fn roundtrip3() {
let v = crate::random_bytes().take(1024 * 1024).collect::<Vec<_>>();
let mut w = write::DeflateEncoder::new(
write::DeflateDecoder::new(Vec::new()),
Compression::default(),
);
w.write_all(&v).unwrap();
let w = w.finish().unwrap().finish().unwrap();
assert_eq!(w, v);
}
#[test]
fn reset_writer() {
let v = crate::random_bytes().take(1024 * 1024).collect::<Vec<_>>();
let mut w = write::DeflateEncoder::new(Vec::new(), Compression::default());
w.write_all(&v).unwrap();
let a = w.reset(Vec::new()).unwrap();
w.write_all(&v).unwrap();
let b = w.finish().unwrap();
let mut w = write::DeflateEncoder::new(Vec::new(), Compression::default());
w.write_all(&v).unwrap();
let c = w.finish().unwrap();
assert!(a == b && b == c);
}
#[test]
fn reset_reader() {
let v = crate::random_bytes().take(1024 * 1024).collect::<Vec<_>>();
let (mut a, mut b, mut c) = (Vec::new(), Vec::new(), Vec::new());
let mut r = read::DeflateEncoder::new(&v[..], Compression::default());
r.read_to_end(&mut a).unwrap();
r.reset(&v[..]);
r.read_to_end(&mut b).unwrap();
let mut r = read::DeflateEncoder::new(&v[..], Compression::default());
r.read_to_end(&mut c).unwrap();
assert!(a == b && b == c);
}
#[test]
fn reset_decoder() {
let v = crate::random_bytes().take(1024 * 1024).collect::<Vec<_>>();
let mut w = write::DeflateEncoder::new(Vec::new(), Compression::default());
w.write_all(&v).unwrap();
let data = w.finish().unwrap();
{
let (mut a, mut b, mut c) = (Vec::new(), Vec::new(), Vec::new());
let mut r = read::DeflateDecoder::new(&data[..]);
r.read_to_end(&mut a).unwrap();
r.reset(&data);
r.read_to_end(&mut b).unwrap();
let mut r = read::DeflateDecoder::new(&data[..]);
r.read_to_end(&mut c).unwrap();
assert!(a == b && b == c && c == v);
}
{
let mut w = write::DeflateDecoder::new(Vec::new());
w.write_all(&data).unwrap();
let a = w.reset(Vec::new()).unwrap();
w.write_all(&data).unwrap();
let b = w.finish().unwrap();
let mut w = write::DeflateDecoder::new(Vec::new());
w.write_all(&data).unwrap();
let c = w.finish().unwrap();
assert!(a == b && b == c && c == v);
}
}
#[test]
fn zero_length_read_with_data() {
let m = vec![3u8; 128 * 1024 + 1];
let mut c = read::DeflateEncoder::new(&m[..], Compression::default());
let mut result = Vec::new();
c.read_to_end(&mut result).unwrap();
let mut d = read::DeflateDecoder::new(&result[..]);
let mut data = Vec::new();
assert_eq!(d.read(&mut data).unwrap(), 0);
}
#[test]
fn qc_reader() {
::quickcheck::quickcheck(test as fn(_) -> _);
fn test(v: Vec<u8>) -> bool {
let mut r = read::DeflateDecoder::new(read::DeflateEncoder::new(
&v[..],
Compression::default(),
));
let mut v2 = Vec::new();
r.read_to_end(&mut v2).unwrap();
v == v2
}
}
#[test]
fn qc_writer() {
::quickcheck::quickcheck(test as fn(_) -> _);
fn test(v: Vec<u8>) -> bool {
let mut w = write::DeflateEncoder::new(
write::DeflateDecoder::new(Vec::new()),
Compression::default(),
);
w.write_all(&v).unwrap();
v == w.finish().unwrap().finish().unwrap()
}
}
}

241
vendor/flate2/src/deflate/read.rs vendored Normal file
View File

@ -0,0 +1,241 @@
use std::io;
use std::io::prelude::*;
use super::bufread;
use crate::bufreader::BufReader;
/// A DEFLATE encoder, or compressor.
///
/// This structure implements a [`Read`] interface. When read from, it reads
/// uncompressed data from the underlying [`Read`] and provides the compressed data.
///
/// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
///
/// # Examples
///
/// ```
/// use std::io::prelude::*;
/// use std::io;
/// use flate2::Compression;
/// use flate2::read::DeflateEncoder;
///
/// # fn main() {
/// # println!("{:?}", deflateencoder_read_hello_world().unwrap());
/// # }
/// #
/// // Return a vector containing the Deflate compressed version of hello world
/// fn deflateencoder_read_hello_world() -> io::Result<Vec<u8>> {
/// let mut ret_vec = Vec::new();
/// let c = b"hello world";
/// let mut deflater = DeflateEncoder::new(&c[..], Compression::fast());
/// deflater.read_to_end(&mut ret_vec)?;
/// Ok(ret_vec)
/// }
/// ```
#[derive(Debug)]
pub struct DeflateEncoder<R> {
inner: bufread::DeflateEncoder<BufReader<R>>,
}
impl<R: Read> DeflateEncoder<R> {
/// Creates a new encoder which will read uncompressed data from the given
/// stream and emit the compressed stream.
pub fn new(r: R, level: crate::Compression) -> DeflateEncoder<R> {
DeflateEncoder {
inner: bufread::DeflateEncoder::new(BufReader::new(r), level),
}
}
}
impl<R> DeflateEncoder<R> {
/// Resets the state of this encoder entirely, swapping out the input
/// stream for another.
///
/// This function will reset the internal state of this encoder and replace
/// the input stream with the one provided, returning the previous input
/// stream. Future data read from this encoder will be the compressed
/// version of `r`'s data.
///
/// Note that there may be currently buffered data when this function is
/// called, and in that case the buffered data is discarded.
pub fn reset(&mut self, r: R) -> R {
super::bufread::reset_encoder_data(&mut self.inner);
self.inner.get_mut().reset(r)
}
/// Acquires a reference to the underlying reader
pub fn get_ref(&self) -> &R {
self.inner.get_ref().get_ref()
}
/// Acquires a mutable reference to the underlying stream
///
/// Note that mutation of the stream may result in surprising results if
/// this encoder is continued to be used.
pub fn get_mut(&mut self) -> &mut R {
self.inner.get_mut().get_mut()
}
/// Consumes this encoder, returning the underlying reader.
///
/// Note that there may be buffered bytes which are not re-acquired as part
/// of this transition. It's recommended to only call this function after
/// EOF has been reached.
pub fn into_inner(self) -> R {
self.inner.into_inner().into_inner()
}
/// Returns the number of bytes that have been read into this compressor.
///
/// Note that not all bytes read from the underlying object may be accounted
/// for, there may still be some active buffering.
pub fn total_in(&self) -> u64 {
self.inner.total_in()
}
/// Returns the number of bytes that the compressor has produced.
///
/// Note that not all bytes may have been read yet, some may still be
/// buffered.
pub fn total_out(&self) -> u64 {
self.inner.total_out()
}
}
impl<R: Read> Read for DeflateEncoder<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf)
}
}
impl<W: Read + Write> Write for DeflateEncoder<W> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.get_mut().write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.get_mut().flush()
}
}
/// A DEFLATE decoder, or decompressor.
///
/// This structure implements a [`Read`] interface. When read from, it reads
/// compressed data from the underlying [`Read`] and provides the uncompressed data.
///
/// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
///
/// # Examples
///
/// ```
/// use std::io::prelude::*;
/// use std::io;
/// # use flate2::Compression;
/// # use flate2::write::DeflateEncoder;
/// use flate2::read::DeflateDecoder;
///
/// # fn main() {
/// # let mut e = DeflateEncoder::new(Vec::new(), Compression::default());
/// # e.write_all(b"Hello World").unwrap();
/// # let bytes = e.finish().unwrap();
/// # println!("{}", decode_reader(bytes).unwrap());
/// # }
/// // Uncompresses a Deflate 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 deflater = DeflateDecoder::new(&bytes[..]);
/// let mut s = String::new();
/// deflater.read_to_string(&mut s)?;
/// Ok(s)
/// }
/// ```
#[derive(Debug)]
pub struct DeflateDecoder<R> {
inner: bufread::DeflateDecoder<BufReader<R>>,
}
impl<R: Read> DeflateDecoder<R> {
/// Creates a new decoder which will decompress data read from the given
/// stream.
pub fn new(r: R) -> DeflateDecoder<R> {
DeflateDecoder::new_with_buf(r, vec![0; 32 * 1024])
}
/// Same as `new`, but the intermediate buffer for data is specified.
///
/// Note that the capacity of the intermediate buffer is never increased,
/// and it is recommended for it to be large.
pub fn new_with_buf(r: R, buf: Vec<u8>) -> DeflateDecoder<R> {
DeflateDecoder {
inner: bufread::DeflateDecoder::new(BufReader::with_buf(buf, r)),
}
}
}
impl<R> DeflateDecoder<R> {
/// Resets the state of this decoder entirely, swapping out the input
/// stream for another.
///
/// This will reset the internal state of this decoder and replace the
/// input stream with the one provided, returning the previous input
/// stream. Future data read from this decoder will be the decompressed
/// version of `r`'s data.
///
/// Note that there may be currently buffered data when this function is
/// called, and in that case the buffered data is discarded.
pub fn reset(&mut self, r: R) -> R {
super::bufread::reset_decoder_data(&mut self.inner);
self.inner.get_mut().reset(r)
}
/// Acquires a reference to the underlying stream
pub fn get_ref(&self) -> &R {
self.inner.get_ref().get_ref()
}
/// Acquires a mutable reference to the underlying stream
///
/// Note that mutation of the stream may result in surprising results if
/// this decoder is continued to be used.
pub fn get_mut(&mut self) -> &mut R {
self.inner.get_mut().get_mut()
}
/// Consumes this decoder, returning the underlying reader.
///
/// Note that there may be buffered bytes which are not re-acquired as part
/// of this transition. It's recommended to only call this function after
/// EOF has been reached.
pub fn into_inner(self) -> R {
self.inner.into_inner().into_inner()
}
/// Returns the number of bytes that the decompressor has consumed.
///
/// Note that this will likely be smaller than what the decompressor
/// actually read from the underlying stream due to buffering.
pub fn total_in(&self) -> u64 {
self.inner.total_in()
}
/// Returns the number of bytes that the decompressor has produced.
pub fn total_out(&self) -> u64 {
self.inner.total_out()
}
}
impl<R: Read> Read for DeflateDecoder<R> {
fn read(&mut self, into: &mut [u8]) -> io::Result<usize> {
self.inner.read(into)
}
}
impl<W: Read + Write> Write for DeflateDecoder<W> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.get_mut().write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.get_mut().flush()
}
}

322
vendor/flate2/src/deflate/write.rs vendored Normal file
View File

@ -0,0 +1,322 @@
use std::io;
use std::io::prelude::*;
use crate::zio;
use crate::{Compress, Decompress};
/// A DEFLATE encoder, or compressor.
///
/// This structure implements a [`Write`] interface and takes a stream of
/// uncompressed data, writing the compressed data to the wrapped writer.
///
/// [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
///
/// # Examples
///
/// ```
/// use std::io::prelude::*;
/// use flate2::Compression;
/// use flate2::write::DeflateEncoder;
///
/// // Vec<u8> implements Write to print the compressed bytes of sample string
/// # fn main() {
///
/// let mut e = DeflateEncoder::new(Vec::new(), Compression::default());
/// e.write_all(b"Hello World").unwrap();
/// println!("{:?}", e.finish().unwrap());
/// # }
/// ```
#[derive(Debug)]
pub struct DeflateEncoder<W: Write> {
inner: zio::Writer<W, Compress>,
}
impl<W: Write> DeflateEncoder<W> {
/// Creates a new encoder which will write compressed data to the stream
/// given at the given compression level.
///
/// When this encoder is dropped or unwrapped the final pieces of data will
/// be flushed.
pub fn new(w: W, level: crate::Compression) -> DeflateEncoder<W> {
DeflateEncoder {
inner: zio::Writer::new(w, Compress::new(level, false)),
}
}
/// Acquires a reference to the underlying writer.
pub fn get_ref(&self) -> &W {
self.inner.get_ref()
}
/// Acquires a mutable reference to the underlying writer.
///
/// Note that mutating the output/input state of the stream may corrupt this
/// object, so care must be taken when using this method.
pub fn get_mut(&mut self) -> &mut W {
self.inner.get_mut()
}
/// Resets the state of this encoder entirely, swapping out the output
/// stream for another.
///
/// This function will finish encoding the current stream into the current
/// output stream before swapping out the two output streams. If the stream
/// cannot be finished an error is returned.
///
/// After the current stream has been finished, this will reset the internal
/// state of this encoder and replace the output stream with the one
/// provided, returning the previous output stream. Future data written to
/// this encoder will be the compressed into the stream `w` provided.
///
/// # Errors
///
/// This function will perform I/O to complete this stream, and any I/O
/// errors which occur will be returned from this function.
pub fn reset(&mut self, w: W) -> io::Result<W> {
self.inner.finish()?;
self.inner.data.reset();
Ok(self.inner.replace(w))
}
/// Attempt to finish this output stream, writing out final chunks of data.
///
/// Note that this function can only be used once data has finished being
/// written to the output stream. After this function is called then further
/// calls to `write` may result in a panic.
///
/// # Panics
///
/// Attempts to write data to this stream may result in a panic after this
/// function is called.
///
/// # Errors
///
/// This function will perform I/O to complete this stream, and any I/O
/// errors which occur will be returned from this function.
pub fn try_finish(&mut self) -> io::Result<()> {
self.inner.finish()
}
/// Consumes this encoder, flushing the output stream.
///
/// This will flush the underlying data stream, close off the compressed
/// stream and, if successful, return the contained writer.
///
/// Note that this function may not be suitable to call in a situation where
/// the underlying stream is an asynchronous I/O stream. To finish a stream
/// the `try_finish` (or `shutdown`) method should be used instead. To
/// re-acquire ownership of a stream it is safe to call this method after
/// `try_finish` or `shutdown` has returned `Ok`.
///
/// # Errors
///
/// This function will perform I/O to complete this stream, and any I/O
/// errors which occur will be returned from this function.
pub fn finish(mut self) -> io::Result<W> {
self.inner.finish()?;
Ok(self.inner.take_inner())
}
/// Consumes this encoder, flushing the output stream.
///
/// This will flush the underlying data stream and then return the contained
/// writer if the flush succeeded.
/// The compressed stream will not closed but only flushed. This
/// means that obtained byte array can by extended by another deflated
/// stream. To close the stream add the two bytes 0x3 and 0x0.
///
/// # Errors
///
/// This function will perform I/O to complete this stream, and any I/O
/// errors which occur will be returned from this function.
pub fn flush_finish(mut self) -> io::Result<W> {
self.inner.flush()?;
Ok(self.inner.take_inner())
}
/// 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.
pub fn total_in(&self) -> u64 {
self.inner.data.total_in()
}
/// Returns the number of bytes that the compressor has produced.
///
/// Note that not all bytes may have been written yet, some may still be
/// buffered.
pub fn total_out(&self) -> u64 {
self.inner.data.total_out()
}
}
impl<W: Write> Write for DeflateEncoder<W> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.inner.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.inner.flush()
}
}
impl<W: Read + Write> Read for DeflateEncoder<W> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.get_mut().read(buf)
}
}
/// A DEFLATE decoder, or decompressor.
///
/// This structure implements a [`Write`] and will emit a stream of decompressed
/// data when fed a stream of compressed data.
///
/// [`Write`]: https://doc.rust-lang.org/std/io/trait.Read.html
///
/// # Examples
///
/// ```
/// use std::io::prelude::*;
/// use std::io;
/// # use flate2::Compression;
/// # use flate2::write::DeflateEncoder;
/// use flate2::write::DeflateDecoder;
///
/// # fn main() {
/// # let mut e = DeflateEncoder::new(Vec::new(), Compression::default());
/// # e.write_all(b"Hello World").unwrap();
/// # let bytes = e.finish().unwrap();
/// # println!("{}", decode_writer(bytes).unwrap());
/// # }
/// // Uncompresses a Deflate Encoded vector of bytes and returns a string or error
/// // Here Vec<u8> implements Write
/// fn decode_writer(bytes: Vec<u8>) -> io::Result<String> {
/// let mut writer = Vec::new();
/// let mut deflater = DeflateDecoder::new(writer);
/// deflater.write_all(&bytes[..])?;
/// writer = deflater.finish()?;
/// let return_string = String::from_utf8(writer).expect("String parsing error");
/// Ok(return_string)
/// }
/// ```
#[derive(Debug)]
pub struct DeflateDecoder<W: Write> {
inner: zio::Writer<W, Decompress>,
}
impl<W: Write> DeflateDecoder<W> {
/// Creates a new decoder which will write uncompressed data to the stream.
///
/// When this encoder is dropped or unwrapped the final pieces of data will
/// be flushed.
pub fn new(w: W) -> DeflateDecoder<W> {
DeflateDecoder {
inner: zio::Writer::new(w, Decompress::new(false)),
}
}
/// Acquires a reference to the underlying writer.
pub fn get_ref(&self) -> &W {
self.inner.get_ref()
}
/// Acquires a mutable reference to the underlying writer.
///
/// Note that mutating the output/input state of the stream may corrupt this
/// object, so care must be taken when using this method.
pub fn get_mut(&mut self) -> &mut W {
self.inner.get_mut()
}
/// Resets the state of this decoder entirely, swapping out the output
/// stream for another.
///
/// This function will finish encoding the current stream into the current
/// output stream before swapping out the two output streams.
///
/// This will then reset the internal state of this decoder and replace the
/// output stream with the one provided, returning the previous output
/// stream. Future data written to this decoder will be decompressed into
/// the output stream `w`.
///
/// # Errors
///
/// This function will perform I/O to finish the stream, and if that I/O
/// returns an error then that will be returned from this function.
pub fn reset(&mut self, w: W) -> io::Result<W> {
self.inner.finish()?;
self.inner.data = Decompress::new(false);
Ok(self.inner.replace(w))
}
/// Attempt to finish this output stream, writing out final chunks of data.
///
/// Note that this function can only be used once data has finished being
/// written to the output stream. After this function is called then further
/// calls to `write` may result in a panic.
///
/// # Panics
///
/// Attempts to write data to this stream may result in a panic after this
/// function is called.
///
/// # Errors
///
/// This function will perform I/O to finish the stream, returning any
/// errors which happen.
pub fn try_finish(&mut self) -> io::Result<()> {
self.inner.finish()
}
/// Consumes this encoder, flushing the output stream.
///
/// This will flush the underlying data stream and then return the contained
/// writer if the flush succeeded.
///
/// Note that this function may not be suitable to call in a situation where
/// the underlying stream is an asynchronous I/O stream. To finish a stream
/// the `try_finish` (or `shutdown`) method should be used instead. To
/// re-acquire ownership of a stream it is safe to call this method after
/// `try_finish` or `shutdown` has returned `Ok`.
///
/// # Errors
///
/// This function will perform I/O to complete this stream, and any I/O
/// errors which occur will be returned from this function.
pub fn finish(mut self) -> io::Result<W> {
self.inner.finish()?;
Ok(self.inner.take_inner())
}
/// Returns the number of bytes that the decompressor has consumed for
/// decompression.
///
/// Note that this will likely be smaller than the number of bytes
/// successfully written to this stream due to internal buffering.
pub fn total_in(&self) -> u64 {
self.inner.data.total_in()
}
/// Returns the number of bytes that the decompressor has written to its
/// output stream.
pub fn total_out(&self) -> u64 {
self.inner.data.total_out()
}
}
impl<W: Write> Write for DeflateDecoder<W> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.inner.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.inner.flush()
}
}
impl<W: Read + Write> Read for DeflateDecoder<W> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.get_mut().read(buf)
}
}

433
vendor/flate2/src/ffi/c.rs vendored Normal file
View File

@ -0,0 +1,433 @@
//! Implementation for C backends.
use std::alloc::{self, Layout};
use std::cmp;
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;
use super::*;
use crate::mem::{self, FlushDecompress, Status};
#[derive(Default)]
pub struct ErrorMessage(Option<&'static str>);
impl ErrorMessage {
pub fn get(&self) -> Option<&str> {
self.0
}
}
pub struct StreamWrapper {
pub inner: Box<mz_stream>,
}
impl fmt::Debug for StreamWrapper {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(f, "StreamWrapper")
}
}
impl Default for StreamWrapper {
fn default() -> StreamWrapper {
StreamWrapper {
inner: Box::new(mz_stream {
next_in: ptr::null_mut(),
avail_in: 0,
total_in: 0,
next_out: ptr::null_mut(),
avail_out: 0,
total_out: 0,
msg: ptr::null_mut(),
adler: 0,
data_type: 0,
reserved: 0,
opaque: ptr::null_mut(),
state: ptr::null_mut(),
#[cfg(all(feature = "any_zlib", not(feature = "cloudflare-zlib-sys")))]
zalloc,
#[cfg(all(feature = "any_zlib", not(feature = "cloudflare-zlib-sys")))]
zfree,
#[cfg(not(all(feature = "any_zlib", not(feature = "cloudflare-zlib-sys"))))]
zalloc: Some(zalloc),
#[cfg(not(all(feature = "any_zlib", not(feature = "cloudflare-zlib-sys"))))]
zfree: Some(zfree),
}),
}
}
}
const ALIGN: usize = std::mem::align_of::<usize>();
fn align_up(size: usize, align: usize) -> usize {
(size + align - 1) & !(align - 1)
}
extern "C" fn zalloc(_ptr: *mut c_void, items: AllocSize, item_size: AllocSize) -> *mut c_void {
// We need to multiply `items` and `item_size` to get the actual desired
// allocation size. Since `zfree` doesn't receive a size argument we
// also need to allocate space for a `usize` as a header so we can store
// how large the allocation is to deallocate later.
let size = match items
.checked_mul(item_size)
.and_then(|i| usize::try_from(i).ok())
.map(|size| align_up(size, ALIGN))
.and_then(|i| i.checked_add(std::mem::size_of::<usize>()))
{
Some(i) => i,
None => return ptr::null_mut(),
};
// Make sure the `size` isn't too big to fail `Layout`'s restrictions
let layout = match Layout::from_size_align(size, ALIGN) {
Ok(layout) => layout,
Err(_) => return ptr::null_mut(),
};
unsafe {
// Allocate the data, and if successful store the size we allocated
// at the beginning and then return an offset pointer.
let ptr = alloc::alloc(layout) as *mut usize;
if ptr.is_null() {
return ptr as *mut c_void;
}
*ptr = size;
ptr.add(1) as *mut c_void
}
}
extern "C" fn zfree(_ptr: *mut c_void, address: *mut c_void) {
unsafe {
// 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);
let size = *ptr;
let layout = Layout::from_size_align_unchecked(size, ALIGN);
alloc::dealloc(ptr as *mut u8, layout)
}
}
impl Deref for StreamWrapper {
type Target = mz_stream;
fn deref(&self) -> &Self::Target {
&*self.inner
}
}
impl DerefMut for StreamWrapper {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut *self.inner
}
}
unsafe impl<D: Direction> Send for Stream<D> {}
unsafe impl<D: Direction> Sync for Stream<D> {}
/// Trait used to call the right destroy/end function on the inner
/// stream object on drop.
pub trait Direction {
unsafe fn destroy(stream: *mut mz_stream) -> c_int;
}
#[derive(Debug)]
pub enum DirCompress {}
#[derive(Debug)]
pub enum DirDecompress {}
#[derive(Debug)]
pub struct Stream<D: Direction> {
pub stream_wrapper: StreamWrapper,
pub total_in: u64,
pub total_out: u64,
pub _marker: marker::PhantomData<D>,
}
impl<D: Direction> Stream<D> {
pub fn msg(&self) -> 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()
})
}
}
impl<D: Direction> Drop for Stream<D> {
fn drop(&mut self) {
unsafe {
let _ = D::destroy(&mut *self.stream_wrapper);
}
}
}
impl Direction for DirCompress {
unsafe fn destroy(stream: *mut mz_stream) -> c_int {
mz_deflateEnd(stream)
}
}
impl Direction for DirDecompress {
unsafe fn destroy(stream: *mut mz_stream) -> c_int {
mz_inflateEnd(stream)
}
}
#[derive(Debug)]
pub struct Inflate {
pub inner: Stream<DirDecompress>,
}
impl InflateBackend for Inflate {
fn make(zlib_header: bool, window_bits: u8) -> Self {
unsafe {
let mut state = StreamWrapper::default();
let ret = mz_inflateInit2(
&mut *state,
if zlib_header {
window_bits as c_int
} else {
-(window_bits as c_int)
},
);
assert_eq!(ret, 0);
Inflate {
inner: Stream {
stream_wrapper: state,
total_in: 0,
total_out: 0,
_marker: marker::PhantomData,
},
}
}
}
fn decompress(
&mut self,
input: &[u8],
output: &mut [u8],
flush: FlushDecompress,
) -> Result<Status, DecompressError> {
let raw = &mut *self.inner.stream_wrapper;
raw.msg = ptr::null_mut();
raw.next_in = input.as_ptr() as *mut u8;
raw.avail_in = cmp::min(input.len(), c_uint::MAX as usize) as c_uint;
raw.next_out = output.as_mut_ptr();
raw.avail_out = cmp::min(output.len(), c_uint::MAX as usize) as c_uint;
let rc = unsafe { mz_inflate(raw, flush as c_int) };
// Unfortunately the total counters provided by zlib might be only
// 32 bits wide and overflow while processing large amounts of data.
self.inner.total_in += (raw.next_in as usize - input.as_ptr() as usize) as u64;
self.inner.total_out += (raw.next_out as usize - output.as_ptr() as usize) as u64;
// reset these pointers so we don't accidentally read them later
raw.next_in = ptr::null_mut();
raw.avail_in = 0;
raw.next_out = ptr::null_mut();
raw.avail_out = 0;
match rc {
MZ_DATA_ERROR | MZ_STREAM_ERROR => mem::decompress_failed(self.inner.msg()),
MZ_OK => Ok(Status::Ok),
MZ_BUF_ERROR => Ok(Status::BufError),
MZ_STREAM_END => Ok(Status::StreamEnd),
MZ_NEED_DICT => mem::decompress_need_dict(raw.adler as u32),
c => panic!("unknown return code: {}", c),
}
}
fn reset(&mut self, zlib_header: bool) {
let bits = if zlib_header {
MZ_DEFAULT_WINDOW_BITS
} else {
-MZ_DEFAULT_WINDOW_BITS
};
unsafe {
inflateReset2(&mut *self.inner.stream_wrapper, bits);
}
self.inner.total_out = 0;
self.inner.total_in = 0;
}
}
impl Backend for Inflate {
#[inline]
fn total_in(&self) -> u64 {
self.inner.total_in
}
#[inline]
fn total_out(&self) -> u64 {
self.inner.total_out
}
}
#[derive(Debug)]
pub struct Deflate {
pub inner: Stream<DirCompress>,
}
impl DeflateBackend for Deflate {
fn make(level: Compression, zlib_header: bool, window_bits: u8) -> Self {
unsafe {
let mut state = StreamWrapper::default();
let ret = mz_deflateInit2(
&mut *state,
level.0 as c_int,
MZ_DEFLATED,
if zlib_header {
window_bits as c_int
} else {
-(window_bits as c_int)
},
8,
MZ_DEFAULT_STRATEGY,
);
assert_eq!(ret, 0);
Deflate {
inner: Stream {
stream_wrapper: state,
total_in: 0,
total_out: 0,
_marker: marker::PhantomData,
},
}
}
}
fn compress(
&mut self,
input: &[u8],
output: &mut [u8],
flush: FlushCompress,
) -> Result<Status, CompressError> {
let raw = &mut *self.inner.stream_wrapper;
raw.msg = ptr::null_mut();
raw.next_in = input.as_ptr() as *mut _;
raw.avail_in = cmp::min(input.len(), c_uint::MAX as usize) as c_uint;
raw.next_out = output.as_mut_ptr();
raw.avail_out = cmp::min(output.len(), c_uint::MAX as usize) as c_uint;
let rc = unsafe { mz_deflate(raw, flush as c_int) };
// Unfortunately the total counters provided by zlib might be only
// 32 bits wide and overflow while processing large amounts of data.
self.inner.total_in += (raw.next_in as usize - input.as_ptr() as usize) as u64;
self.inner.total_out += (raw.next_out as usize - output.as_ptr() as usize) as u64;
// reset these pointers so we don't accidentally read them later
raw.next_in = ptr::null_mut();
raw.avail_in = 0;
raw.next_out = ptr::null_mut();
raw.avail_out = 0;
match rc {
MZ_OK => Ok(Status::Ok),
MZ_BUF_ERROR => Ok(Status::BufError),
MZ_STREAM_END => Ok(Status::StreamEnd),
MZ_STREAM_ERROR => mem::compress_failed(self.inner.msg()),
c => panic!("unknown return code: {}", c),
}
}
fn reset(&mut self) {
self.inner.total_in = 0;
self.inner.total_out = 0;
let rc = unsafe { mz_deflateReset(&mut *self.inner.stream_wrapper) };
assert_eq!(rc, MZ_OK);
}
}
impl Backend for Deflate {
#[inline]
fn total_in(&self) -> u64 {
self.inner.total_in
}
#[inline]
fn total_out(&self) -> u64 {
self.inner.total_out
}
}
pub use self::c_backend::*;
/// For backwards compatibility, we provide symbols as `mz_` to mimic the miniz API
#[allow(bad_style)]
mod c_backend {
use std::mem;
use std::os::raw::{c_char, c_int};
#[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(all(not(feature = "cloudflare_zlib"), not(feature = "zlib-ng")))]
use libz_sys as libz;
pub use libz::deflate as mz_deflate;
pub use libz::deflateEnd as mz_deflateEnd;
pub use libz::deflateReset as mz_deflateReset;
pub use libz::inflate as mz_inflate;
pub use libz::inflateEnd as mz_inflateEnd;
pub use libz::z_stream as mz_stream;
pub use libz::*;
pub use libz::Z_BLOCK as MZ_BLOCK;
pub use libz::Z_BUF_ERROR as MZ_BUF_ERROR;
pub use libz::Z_DATA_ERROR as MZ_DATA_ERROR;
pub use libz::Z_DEFAULT_STRATEGY as MZ_DEFAULT_STRATEGY;
pub use libz::Z_DEFLATED as MZ_DEFLATED;
pub use libz::Z_FINISH as MZ_FINISH;
pub use libz::Z_FULL_FLUSH as MZ_FULL_FLUSH;
pub use libz::Z_NEED_DICT as MZ_NEED_DICT;
pub use libz::Z_NO_FLUSH as MZ_NO_FLUSH;
pub use libz::Z_OK as MZ_OK;
pub use libz::Z_PARTIAL_FLUSH as MZ_PARTIAL_FLUSH;
pub use libz::Z_STREAM_END as MZ_STREAM_END;
pub use libz::Z_STREAM_ERROR as MZ_STREAM_ERROR;
pub use libz::Z_SYNC_FLUSH as MZ_SYNC_FLUSH;
pub type AllocSize = libz::uInt;
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(
stream: *mut mz_stream,
level: c_int,
method: c_int,
window_bits: c_int,
mem_level: c_int,
strategy: c_int,
) -> c_int {
libz::deflateInit2_(
stream,
level,
method,
window_bits,
mem_level,
strategy,
ZLIB_VERSION.as_ptr() as *const c_char,
mem::size_of::<mz_stream>() as c_int,
)
}
pub unsafe extern "C" fn mz_inflateInit2(stream: *mut mz_stream, window_bits: c_int) -> c_int {
libz::inflateInit2_(
stream,
window_bits,
ZLIB_VERSION.as_ptr() as *const c_char,
mem::size_of::<mz_stream>() as c_int,
)
}
}

52
vendor/flate2/src/ffi/mod.rs vendored Normal file
View File

@ -0,0 +1,52 @@
//! This module contains backend-specific code.
use crate::mem::{CompressError, DecompressError, FlushCompress, FlushDecompress, Status};
use crate::Compression;
/// Traits specifying the interface of the backends.
///
/// Sync + Send are added as a condition to ensure they are available
/// for the frontend.
pub trait Backend: Sync + Send {
fn total_in(&self) -> u64;
fn total_out(&self) -> u64;
}
pub trait InflateBackend: Backend {
fn make(zlib_header: bool, window_bits: u8) -> Self;
fn decompress(
&mut self,
input: &[u8],
output: &mut [u8],
flush: FlushDecompress,
) -> Result<Status, DecompressError>;
fn reset(&mut self, zlib_header: bool);
}
pub trait DeflateBackend: Backend {
fn make(level: Compression, zlib_header: bool, window_bits: u8) -> Self;
fn compress(
&mut self,
input: &[u8],
output: &mut [u8],
flush: FlushCompress,
) -> Result<Status, CompressError>;
fn reset(&mut self);
}
// Default to Rust implementation unless explicitly opted in to a different backend.
#[cfg(feature = "any_zlib")]
mod c;
#[cfg(feature = "any_zlib")]
pub use self::c::*;
#[cfg(all(not(feature = "any_zlib"), feature = "miniz_oxide"))]
mod rust;
#[cfg(all(not(feature = "any_zlib"), feature = "miniz_oxide"))]
pub use self::rust::*;
impl std::fmt::Debug for ErrorMessage {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
self.get().fmt(f)
}
}

183
vendor/flate2/src/ffi/rust.rs vendored Normal file
View File

@ -0,0 +1,183 @@
//! Implementation for `miniz_oxide` rust backend.
use std::convert::TryInto;
use std::fmt;
use miniz_oxide::deflate::core::CompressorOxide;
use miniz_oxide::inflate::stream::InflateState;
pub use miniz_oxide::*;
pub const MZ_NO_FLUSH: isize = MZFlush::None as isize;
pub const MZ_PARTIAL_FLUSH: isize = MZFlush::Partial as isize;
pub const MZ_SYNC_FLUSH: isize = MZFlush::Sync as isize;
pub const MZ_FULL_FLUSH: isize = MZFlush::Full as isize;
pub const MZ_FINISH: isize = MZFlush::Finish as isize;
use super::*;
use crate::mem;
// miniz_oxide doesn't provide any error messages (yet?)
#[derive(Default)]
pub struct ErrorMessage;
impl ErrorMessage {
pub fn get(&self) -> Option<&str> {
None
}
}
fn format_from_bool(zlib_header: bool) -> DataFormat {
if zlib_header {
DataFormat::Zlib
} else {
DataFormat::Raw
}
}
pub struct Inflate {
inner: Box<InflateState>,
total_in: u64,
total_out: u64,
}
impl fmt::Debug for Inflate {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(
f,
"miniz_oxide inflate internal state. total_in: {}, total_out: {}",
self.total_in, self.total_out,
)
}
}
impl InflateBackend for Inflate {
fn make(zlib_header: bool, _window_bits: u8) -> Self {
let format = format_from_bool(zlib_header);
Inflate {
inner: InflateState::new_boxed(format),
total_in: 0,
total_out: 0,
}
}
fn decompress(
&mut self,
input: &[u8],
output: &mut [u8],
flush: FlushDecompress,
) -> Result<Status, DecompressError> {
let flush = MZFlush::new(flush as i32).unwrap();
let res = inflate::stream::inflate(&mut self.inner, input, output, flush);
self.total_in += res.bytes_consumed as u64;
self.total_out += res.bytes_written as u64;
match res.status {
Ok(status) => match status {
MZStatus::Ok => Ok(Status::Ok),
MZStatus::StreamEnd => Ok(Status::StreamEnd),
MZStatus::NeedDict => {
mem::decompress_need_dict(self.inner.decompressor().adler32().unwrap_or(0))
}
},
Err(status) => match status {
MZError::Buf => Ok(Status::BufError),
_ => mem::decompress_failed(ErrorMessage),
},
}
}
fn reset(&mut self, zlib_header: bool) {
self.inner.reset(format_from_bool(zlib_header));
self.total_in = 0;
self.total_out = 0;
}
}
impl Backend for Inflate {
#[inline]
fn total_in(&self) -> u64 {
self.total_in
}
#[inline]
fn total_out(&self) -> u64 {
self.total_out
}
}
pub struct Deflate {
inner: Box<CompressorOxide>,
total_in: u64,
total_out: u64,
}
impl fmt::Debug for Deflate {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(
f,
"miniz_oxide deflate internal state. total_in: {}, total_out: {}",
self.total_in, self.total_out,
)
}
}
impl DeflateBackend for Deflate {
fn make(level: Compression, zlib_header: bool, _window_bits: u8) -> Self {
// Check in case the integer value changes at some point.
debug_assert!(level.level() <= 10);
let mut inner: Box<CompressorOxide> = Box::default();
let format = format_from_bool(zlib_header);
inner.set_format_and_level(format, level.level().try_into().unwrap_or(1));
Deflate {
inner,
total_in: 0,
total_out: 0,
}
}
fn compress(
&mut self,
input: &[u8],
output: &mut [u8],
flush: FlushCompress,
) -> Result<Status, CompressError> {
let flush = MZFlush::new(flush as i32).unwrap();
let res = deflate::stream::deflate(&mut self.inner, input, output, flush);
self.total_in += res.bytes_consumed as u64;
self.total_out += res.bytes_written as u64;
match res.status {
Ok(status) => match status {
MZStatus::Ok => Ok(Status::Ok),
MZStatus::StreamEnd => Ok(Status::StreamEnd),
MZStatus::NeedDict => mem::compress_failed(ErrorMessage),
},
Err(status) => match status {
MZError::Buf => Ok(Status::BufError),
_ => mem::compress_failed(ErrorMessage),
},
}
}
fn reset(&mut self) {
self.total_in = 0;
self.total_out = 0;
self.inner.reset();
}
}
impl Backend for Deflate {
#[inline]
fn total_in(&self) -> u64 {
self.total_in
}
#[inline]
fn total_out(&self) -> u64 {
self.total_out
}
}

483
vendor/flate2/src/gz/bufread.rs vendored Normal file
View File

@ -0,0 +1,483 @@
use std::cmp;
use std::io;
use std::io::prelude::*;
use std::mem;
use super::{corrupt, read_into, GzBuilder, GzHeader, GzHeaderParser};
use crate::crc::CrcReader;
use crate::deflate;
use crate::Compression;
fn copy(into: &mut [u8], from: &[u8], pos: &mut usize) -> usize {
let min = cmp::min(into.len(), from.len() - *pos);
for (slot, val) in into.iter_mut().zip(from[*pos..*pos + min].iter()) {
*slot = *val;
}
*pos += min;
min
}
/// A gzip streaming encoder
///
/// This structure implements a [`Read`] interface. When read from, it reads
/// uncompressed data from the underlying [`BufRead`] and provides the compressed data.
///
/// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
/// [`BufRead`]: https://doc.rust-lang.org/std/io/trait.BufRead.html
///
/// # Examples
///
/// ```
/// use std::io::prelude::*;
/// use std::io;
/// use flate2::Compression;
/// use flate2::bufread::GzEncoder;
/// use std::fs::File;
/// use std::io::BufReader;
///
/// // Opens sample file, compresses the contents and returns a Vector or error
/// // File wrapped in a BufReader implements BufRead
///
/// fn open_hello_world() -> io::Result<Vec<u8>> {
/// let f = File::open("examples/hello_world.txt")?;
/// let b = BufReader::new(f);
/// let mut gz = GzEncoder::new(b, Compression::fast());
/// let mut buffer = Vec::new();
/// gz.read_to_end(&mut buffer)?;
/// Ok(buffer)
/// }
/// ```
#[derive(Debug)]
pub struct GzEncoder<R> {
inner: deflate::bufread::DeflateEncoder<CrcReader<R>>,
header: Vec<u8>,
pos: usize,
eof: bool,
}
pub fn gz_encoder<R: BufRead>(header: Vec<u8>, r: R, lvl: Compression) -> GzEncoder<R> {
let crc = CrcReader::new(r);
GzEncoder {
inner: deflate::bufread::DeflateEncoder::new(crc, lvl),
header,
pos: 0,
eof: false,
}
}
impl<R: BufRead> GzEncoder<R> {
/// Creates a new encoder which will use the given compression level.
///
/// The encoder is not configured specially for the emitted header. For
/// header configuration, see the `GzBuilder` type.
///
/// The data read from the stream `r` will be compressed and available
/// through the returned reader.
pub fn new(r: R, level: Compression) -> GzEncoder<R> {
GzBuilder::new().buf_read(r, level)
}
fn read_footer(&mut self, into: &mut [u8]) -> io::Result<usize> {
if self.pos == 8 {
return Ok(0);
}
let crc = self.inner.get_ref().crc();
let ref arr = [
(crc.sum() >> 0) as u8,
(crc.sum() >> 8) as u8,
(crc.sum() >> 16) as u8,
(crc.sum() >> 24) as u8,
(crc.amount() >> 0) as u8,
(crc.amount() >> 8) as u8,
(crc.amount() >> 16) as u8,
(crc.amount() >> 24) as u8,
];
Ok(copy(into, arr, &mut self.pos))
}
}
impl<R> GzEncoder<R> {
/// Acquires a reference to the underlying reader.
pub fn get_ref(&self) -> &R {
self.inner.get_ref().get_ref()
}
/// Acquires a mutable reference to the underlying reader.
///
/// Note that mutation of the reader may result in surprising results if
/// this encoder is continued to be used.
pub fn get_mut(&mut self) -> &mut R {
self.inner.get_mut().get_mut()
}
/// Returns the underlying stream, consuming this encoder
pub fn into_inner(self) -> R {
self.inner.into_inner().into_inner()
}
}
#[inline]
fn finish(buf: &[u8; 8]) -> (u32, u32) {
let crc = ((buf[0] as u32) << 0)
| ((buf[1] as u32) << 8)
| ((buf[2] as u32) << 16)
| ((buf[3] as u32) << 24);
let amt = ((buf[4] as u32) << 0)
| ((buf[5] as u32) << 8)
| ((buf[6] as u32) << 16)
| ((buf[7] as u32) << 24);
(crc, amt)
}
impl<R: BufRead> Read for GzEncoder<R> {
fn read(&mut self, mut into: &mut [u8]) -> io::Result<usize> {
let mut amt = 0;
if self.eof {
return self.read_footer(into);
} else if self.pos < self.header.len() {
amt += copy(into, &self.header, &mut self.pos);
if amt == into.len() {
return Ok(amt);
}
let tmp = into;
into = &mut tmp[amt..];
}
match self.inner.read(into)? {
0 => {
self.eof = true;
self.pos = 0;
self.read_footer(into)
}
n => Ok(amt + n),
}
}
}
impl<R: BufRead + Write> Write for GzEncoder<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()
}
}
/// A decoder for a single member of a [gzip file].
///
/// This structure implements a [`Read`] interface. When read from, it reads
/// compressed data from the underlying [`BufRead`] and provides the uncompressed data.
///
/// After reading a single member of the gzip data this reader will return
/// Ok(0) even if there are more bytes available in the underlying reader.
/// If you need the following bytes, call `into_inner()` after Ok(0) to
/// recover the underlying reader.
///
/// To handle gzip files that may have multiple members, see [`MultiGzDecoder`]
/// or read more
/// [in the introduction](../index.html#about-multi-member-gzip-files).
///
/// [gzip file]: https://www.rfc-editor.org/rfc/rfc1952#page-5
/// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
/// [`BufRead`]: https://doc.rust-lang.org/std/io/trait.BufRead.html
///
/// # Examples
///
/// ```
/// use std::io::prelude::*;
/// use std::io;
/// # use flate2::Compression;
/// # use flate2::write::GzEncoder;
/// use flate2::bufread::GzDecoder;
///
/// # fn main() {
/// # let mut e = GzEncoder::new(Vec::new(), Compression::default());
/// # e.write_all(b"Hello World").unwrap();
/// # let bytes = e.finish().unwrap();
/// # println!("{}", decode_reader(bytes).unwrap());
/// # }
/// #
/// // 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 s = String::new();
/// gz.read_to_string(&mut s)?;
/// Ok(s)
/// }
/// ```
#[derive(Debug)]
pub struct GzDecoder<R> {
state: GzState,
reader: CrcReader<deflate::bufread::DeflateDecoder<R>>,
multi: bool,
}
#[derive(Debug)]
enum GzState {
Header(GzHeaderParser),
Body(GzHeader),
Finished(GzHeader, usize, [u8; 8]),
Err(io::Error),
End(Option<GzHeader>),
}
impl<R: BufRead> GzDecoder<R> {
/// Creates a new decoder from the given reader, immediately parsing the
/// gzip header.
pub fn new(mut r: R) -> GzDecoder<R> {
let mut header_parser = GzHeaderParser::new();
let state = match header_parser.parse(&mut r) {
Ok(_) => GzState::Body(GzHeader::from(header_parser)),
Err(ref err) if io::ErrorKind::WouldBlock == err.kind() => {
GzState::Header(header_parser)
}
Err(err) => GzState::Err(err),
};
GzDecoder {
state,
reader: CrcReader::new(deflate::bufread::DeflateDecoder::new(r)),
multi: false,
}
}
fn multi(mut self, flag: bool) -> GzDecoder<R> {
self.multi = flag;
self
}
}
impl<R> GzDecoder<R> {
/// Returns the header associated with this stream, if it was valid
pub fn header(&self) -> Option<&GzHeader> {
match &self.state {
GzState::Body(header) | GzState::Finished(header, _, _) => Some(header),
GzState::End(header) => header.as_ref(),
_ => None,
}
}
/// Acquires a reference to the underlying reader.
pub fn get_ref(&self) -> &R {
self.reader.get_ref().get_ref()
}
/// Acquires a mutable reference to the underlying stream.
///
/// Note that mutation of the stream may result in surprising results if
/// this decoder is continued to be used.
pub fn get_mut(&mut self) -> &mut R {
self.reader.get_mut().get_mut()
}
/// Consumes this decoder, returning the underlying reader.
pub fn into_inner(self) -> R {
self.reader.into_inner().into_inner()
}
}
impl<R: BufRead> Read for GzDecoder<R> {
fn read(&mut self, into: &mut [u8]) -> io::Result<usize> {
loop {
match &mut self.state {
GzState::Header(parser) => {
parser.parse(self.reader.get_mut().get_mut())?;
self.state = GzState::Body(GzHeader::from(mem::take(parser)));
}
GzState::Body(header) => {
if into.is_empty() {
return Ok(0);
}
match self.reader.read(into)? {
0 => {
self.state = GzState::Finished(mem::take(header), 0, [0; 8]);
}
n => {
return Ok(n);
}
}
}
GzState::Finished(header, pos, buf) => {
if *pos < buf.len() {
*pos += read_into(self.reader.get_mut().get_mut(), &mut buf[*pos..])?;
} else {
let (crc, amt) = finish(&buf);
if crc != self.reader.crc().sum() || amt != self.reader.crc().amount() {
self.state = GzState::End(Some(mem::take(header)));
return Err(corrupt());
} else if self.multi {
let is_eof = self
.reader
.get_mut()
.get_mut()
.fill_buf()
.map(|buf| buf.is_empty())?;
if is_eof {
self.state = GzState::End(Some(mem::take(header)));
} else {
self.reader.reset();
self.reader.get_mut().reset_data();
self.state = GzState::Header(GzHeaderParser::new())
}
} else {
self.state = GzState::End(Some(mem::take(header)));
}
}
}
GzState::Err(err) => {
let result = Err(mem::replace(err, io::ErrorKind::Other.into()));
self.state = GzState::End(None);
return result;
}
GzState::End(_) => return Ok(0),
}
}
}
}
impl<R: BufRead + Write> Write for GzDecoder<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()
}
}
/// A gzip streaming decoder that decodes a [gzip file] that may have multiple members.
///
/// This structure implements a [`Read`] interface. When read from, it reads
/// compressed data from the underlying [`BufRead`] and provides the uncompressed data.
///
/// A gzip file consists of a series of *members* concatenated one after another.
/// MultiGzDecoder decodes all members from the data and only returns Ok(0) when the
/// underlying reader does. For a file, this reads to the end of the file.
///
/// To handle members seperately, see [GzDecoder] or read more
/// [in the introduction](../index.html#about-multi-member-gzip-files).
///
/// [gzip file]: https://www.rfc-editor.org/rfc/rfc1952#page-5
/// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
/// [`BufRead`]: https://doc.rust-lang.org/std/io/trait.BufRead.html
///
/// # Examples
///
/// ```
/// use std::io::prelude::*;
/// use std::io;
/// # use flate2::Compression;
/// # use flate2::write::GzEncoder;
/// use flate2::bufread::MultiGzDecoder;
///
/// # fn main() {
/// # let mut e = GzEncoder::new(Vec::new(), Compression::default());
/// # e.write_all(b"Hello World").unwrap();
/// # let bytes = e.finish().unwrap();
/// # println!("{}", decode_reader(bytes).unwrap());
/// # }
/// #
/// // 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 = MultiGzDecoder::new(&bytes[..]);
/// let mut s = String::new();
/// gz.read_to_string(&mut s)?;
/// Ok(s)
/// }
/// ```
#[derive(Debug)]
pub struct MultiGzDecoder<R>(GzDecoder<R>);
impl<R: BufRead> MultiGzDecoder<R> {
/// Creates a new decoder from the given reader, immediately parsing the
/// (first) gzip header. If the gzip stream contains multiple members all will
/// be decoded.
pub fn new(r: R) -> MultiGzDecoder<R> {
MultiGzDecoder(GzDecoder::new(r).multi(true))
}
}
impl<R> MultiGzDecoder<R> {
/// Returns the current header associated with this stream, if it's valid
pub fn header(&self) -> Option<&GzHeader> {
self.0.header()
}
/// Acquires a reference to the underlying reader.
pub fn get_ref(&self) -> &R {
self.0.get_ref()
}
/// Acquires a mutable reference to the underlying stream.
///
/// Note that mutation of the stream may result in surprising results if
/// this decoder is continued to be used.
pub fn get_mut(&mut self) -> &mut R {
self.0.get_mut()
}
/// Consumes this decoder, returning the underlying reader.
pub fn into_inner(self) -> R {
self.0.into_inner()
}
}
impl<R: BufRead> Read for MultiGzDecoder<R> {
fn read(&mut self, into: &mut [u8]) -> io::Result<usize> {
self.0.read(into)
}
}
#[cfg(test)]
mod test {
use crate::bufread::GzDecoder;
use crate::gz::write;
use crate::Compression;
use std::io::{Read, Write};
// GzDecoder consumes one gzip member and then returns 0 for subsequent reads, allowing any
// additional data to be consumed by the caller.
#[test]
fn decode_extra_data() {
let expected = "Hello World";
let compressed = {
let mut e = write::GzEncoder::new(Vec::new(), Compression::default());
e.write(expected.as_ref()).unwrap();
let mut b = e.finish().unwrap();
b.push(b'x');
b
};
let mut output = Vec::new();
let mut decoder = GzDecoder::new(compressed.as_slice());
let decoded_bytes = decoder.read_to_end(&mut output).unwrap();
assert_eq!(decoded_bytes, output.len());
let actual = std::str::from_utf8(&output).expect("String parsing error");
assert_eq!(
actual, expected,
"after decompression we obtain the original input"
);
output.clear();
assert_eq!(
decoder.read(&mut output).unwrap(),
0,
"subsequent read of decoder returns 0, but inner reader can return additional data"
);
let mut reader = decoder.into_inner();
assert_eq!(
reader.read_to_end(&mut output).unwrap(),
1,
"extra data is accessible in underlying buf-read"
);
assert_eq!(output, b"x");
}
}

644
vendor/flate2/src/gz/mod.rs vendored Normal file
View File

@ -0,0 +1,644 @@
use std::ffi::CString;
use std::io::{BufRead, Error, ErrorKind, Read, Result, Write};
use std::time;
use crate::bufreader::BufReader;
use crate::{Compression, Crc};
pub static FHCRC: u8 = 1 << 1;
pub static FEXTRA: u8 = 1 << 2;
pub static FNAME: u8 = 1 << 3;
pub static FCOMMENT: u8 = 1 << 4;
pub static FRESERVED: u8 = 1 << 5 | 1 << 6 | 1 << 7;
pub mod bufread;
pub mod read;
pub mod write;
// The maximum length of the header filename and comment fields. More than
// enough for these fields in reasonable use, but prevents possible attacks.
const MAX_HEADER_BUF: usize = 65535;
/// A structure representing the header of a gzip stream.
///
/// The header can contain metadata about the file that was compressed, if
/// present.
#[derive(PartialEq, Clone, Debug, Default)]
pub struct GzHeader {
extra: Option<Vec<u8>>,
filename: Option<Vec<u8>>,
comment: Option<Vec<u8>>,
operating_system: u8,
mtime: u32,
}
impl GzHeader {
/// Returns the `filename` field of this gzip stream's header, if present.
pub fn filename(&self) -> Option<&[u8]> {
self.filename.as_ref().map(|s| &s[..])
}
/// Returns the `extra` field of this gzip stream's header, if present.
pub fn extra(&self) -> Option<&[u8]> {
self.extra.as_ref().map(|s| &s[..])
}
/// Returns the `comment` field of this gzip stream's header, if present.
pub fn comment(&self) -> Option<&[u8]> {
self.comment.as_ref().map(|s| &s[..])
}
/// Returns the `operating_system` field of this gzip stream's header.
///
/// There are predefined values for various operating systems.
/// 255 means that the value is unknown.
pub fn operating_system(&self) -> u8 {
self.operating_system
}
/// This gives the most recent modification time of the original file being compressed.
///
/// The time is in Unix format, i.e., seconds since 00:00:00 GMT, Jan. 1, 1970.
/// (Note that this may cause problems for MS-DOS and other systems that use local
/// rather than Universal time.) If the compressed data did not come from a file,
/// `mtime` is set to the time at which compression started.
/// `mtime` = 0 means no time stamp is available.
///
/// The usage of `mtime` is discouraged because of Year 2038 problem.
pub fn mtime(&self) -> u32 {
self.mtime
}
/// Returns the most recent modification time represented by a date-time type.
/// Returns `None` if the value of the underlying counter is 0,
/// indicating no time stamp is available.
///
///
/// The time is measured as seconds since 00:00:00 GMT, Jan. 1 1970.
/// See [`mtime`](#method.mtime) for more detail.
pub fn mtime_as_datetime(&self) -> Option<time::SystemTime> {
if self.mtime == 0 {
None
} else {
let duration = time::Duration::new(u64::from(self.mtime), 0);
let datetime = time::UNIX_EPOCH + duration;
Some(datetime)
}
}
}
#[derive(Debug)]
pub enum GzHeaderState {
Start(u8, [u8; 10]),
Xlen(Option<Box<Crc>>, u8, [u8; 2]),
Extra(Option<Box<Crc>>, u16),
Filename(Option<Box<Crc>>),
Comment(Option<Box<Crc>>),
Crc(Option<Box<Crc>>, u8, [u8; 2]),
Complete,
}
impl Default for GzHeaderState {
fn default() -> Self {
Self::Complete
}
}
#[derive(Debug, Default)]
pub struct GzHeaderParser {
state: GzHeaderState,
flags: u8,
header: GzHeader,
}
impl GzHeaderParser {
fn new() -> Self {
GzHeaderParser {
state: GzHeaderState::Start(0, [0; 10]),
flags: 0,
header: GzHeader::default(),
}
}
fn parse<'a, R: Read>(&mut self, r: &'a mut R) -> Result<()> {
loop {
match &mut self.state {
GzHeaderState::Start(count, buffer) => {
while (*count as usize) < buffer.len() {
*count += read_into(r, &mut buffer[*count as usize..])? as u8;
}
// Gzip identification bytes
if buffer[0] != 0x1f || buffer[1] != 0x8b {
return Err(bad_header());
}
// Gzip compression method (8 = deflate)
if buffer[2] != 8 {
return Err(bad_header());
}
self.flags = buffer[3];
// RFC1952: "must give an error indication if any reserved bit is non-zero"
if self.flags & FRESERVED != 0 {
return Err(bad_header());
}
self.header.mtime = ((buffer[4] as u32) << 0)
| ((buffer[5] as u32) << 8)
| ((buffer[6] as u32) << 16)
| ((buffer[7] as u32) << 24);
let _xfl = buffer[8];
self.header.operating_system = buffer[9];
let crc = if self.flags & FHCRC != 0 {
let mut crc = Box::new(Crc::new());
crc.update(buffer);
Some(crc)
} else {
None
};
self.state = GzHeaderState::Xlen(crc, 0, [0; 2]);
}
GzHeaderState::Xlen(crc, count, buffer) => {
if self.flags & FEXTRA != 0 {
while (*count as usize) < buffer.len() {
*count += read_into(r, &mut buffer[*count as usize..])? as u8;
}
if let Some(crc) = crc {
crc.update(buffer);
}
let xlen = parse_le_u16(&buffer);
self.header.extra = Some(vec![0; xlen as usize]);
self.state = GzHeaderState::Extra(crc.take(), 0);
} else {
self.state = GzHeaderState::Filename(crc.take());
}
}
GzHeaderState::Extra(crc, count) => {
debug_assert!(self.header.extra.is_some());
let extra = self.header.extra.as_mut().unwrap();
while (*count as usize) < extra.len() {
*count += read_into(r, &mut extra[*count as usize..])? as u16;
}
if let Some(crc) = crc {
crc.update(extra);
}
self.state = GzHeaderState::Filename(crc.take());
}
GzHeaderState::Filename(crc) => {
if self.flags & FNAME != 0 {
let filename = self.header.filename.get_or_insert_with(Vec::new);
read_to_nul(r, filename)?;
if let Some(crc) = crc {
crc.update(filename);
crc.update(b"\0");
}
}
self.state = GzHeaderState::Comment(crc.take());
}
GzHeaderState::Comment(crc) => {
if self.flags & FCOMMENT != 0 {
let comment = self.header.comment.get_or_insert_with(Vec::new);
read_to_nul(r, comment)?;
if let Some(crc) = crc {
crc.update(comment);
crc.update(b"\0");
}
}
self.state = GzHeaderState::Crc(crc.take(), 0, [0; 2]);
}
GzHeaderState::Crc(crc, count, buffer) => {
if let Some(crc) = crc {
debug_assert!(self.flags & FHCRC != 0);
while (*count as usize) < buffer.len() {
*count += read_into(r, &mut buffer[*count as usize..])? as u8;
}
let stored_crc = parse_le_u16(&buffer);
let calced_crc = crc.sum() as u16;
if stored_crc != calced_crc {
return Err(corrupt());
}
}
self.state = GzHeaderState::Complete;
}
GzHeaderState::Complete => {
return Ok(());
}
}
}
}
fn header(&self) -> Option<&GzHeader> {
match self.state {
GzHeaderState::Complete => Some(&self.header),
_ => None,
}
}
}
impl From<GzHeaderParser> for GzHeader {
fn from(parser: GzHeaderParser) -> Self {
debug_assert!(matches!(parser.state, GzHeaderState::Complete));
parser.header
}
}
// Attempt to fill the `buffer` from `r`. Return the number of bytes read.
// Return an error if EOF is read before the buffer is full. This differs
// from `read` in that Ok(0) means that more data may be available.
fn read_into<R: Read>(r: &mut R, buffer: &mut [u8]) -> Result<usize> {
debug_assert!(!buffer.is_empty());
match r.read(buffer) {
Ok(0) => Err(ErrorKind::UnexpectedEof.into()),
Ok(n) => Ok(n),
Err(ref e) if e.kind() == ErrorKind::Interrupted => Ok(0),
Err(e) => Err(e),
}
}
// Read `r` up to the first nul byte, pushing non-nul bytes to `buffer`.
fn read_to_nul<R: Read>(r: &mut R, buffer: &mut Vec<u8>) -> Result<()> {
let mut bytes = r.bytes();
loop {
match bytes.next().transpose()? {
Some(byte) if byte == 0 => {
return Ok(());
}
Some(_) if buffer.len() == MAX_HEADER_BUF => {
return Err(Error::new(
ErrorKind::InvalidInput,
"gzip header field too long",
));
}
Some(byte) => {
buffer.push(byte);
}
None => {
return Err(ErrorKind::UnexpectedEof.into());
}
}
}
}
fn parse_le_u16(buffer: &[u8; 2]) -> u16 {
(buffer[0] as u16) | ((buffer[1] as u16) << 8)
}
fn bad_header() -> Error {
Error::new(ErrorKind::InvalidInput, "invalid gzip header")
}
fn corrupt() -> Error {
Error::new(
ErrorKind::InvalidInput,
"corrupt gzip stream does not have a matching checksum",
)
}
/// A builder structure to create a new gzip Encoder.
///
/// This structure controls header configuration options such as the filename.
///
/// # Examples
///
/// ```
/// use std::io::prelude::*;
/// # use std::io;
/// use std::fs::File;
/// use flate2::GzBuilder;
/// use flate2::Compression;
///
/// // GzBuilder opens a file and writes a sample string using GzBuilder pattern
///
/// # fn sample_builder() -> Result<(), io::Error> {
/// let f = File::create("examples/hello_world.gz")?;
/// let mut gz = GzBuilder::new()
/// .filename("hello_world.txt")
/// .comment("test file, please delete")
/// .write(f, Compression::default());
/// gz.write_all(b"hello world")?;
/// gz.finish()?;
/// # Ok(())
/// # }
/// ```
#[derive(Debug)]
pub struct GzBuilder {
extra: Option<Vec<u8>>,
filename: Option<CString>,
comment: Option<CString>,
operating_system: Option<u8>,
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 {
GzBuilder {
extra: None,
filename: None,
comment: None,
operating_system: None,
mtime: 0,
}
}
/// Configure the `mtime` field in the gzip header.
pub fn mtime(mut self, mtime: u32) -> GzBuilder {
self.mtime = mtime;
self
}
/// Configure the `operating_system` field in the gzip header.
pub fn operating_system(mut self, os: u8) -> GzBuilder {
self.operating_system = Some(os);
self
}
/// Configure the `extra` field in the gzip header.
pub fn extra<T: Into<Vec<u8>>>(mut self, extra: T) -> GzBuilder {
self.extra = Some(extra.into());
self
}
/// Configure the `filename` field in the gzip header.
///
/// # Panics
///
/// Panics if the `filename` slice contains a zero.
pub fn filename<T: Into<Vec<u8>>>(mut self, filename: T) -> GzBuilder {
self.filename = Some(CString::new(filename.into()).unwrap());
self
}
/// Configure the `comment` field in the gzip header.
///
/// # Panics
///
/// Panics if the `comment` slice contains a zero.
pub fn comment<T: Into<Vec<u8>>>(mut self, comment: T) -> GzBuilder {
self.comment = Some(CString::new(comment.into()).unwrap());
self
}
/// Consume this builder, creating a writer encoder in the process.
///
/// The data written to the returned encoder will be compressed and then
/// written out to the supplied parameter `w`.
pub fn write<W: Write>(self, w: W, lvl: Compression) -> write::GzEncoder<W> {
write::gz_encoder(self.into_header(lvl), w, lvl)
}
/// Consume this builder, creating a reader encoder in the process.
///
/// Data read from the returned encoder will be the compressed version of
/// the data read from the given reader.
pub fn read<R: Read>(self, r: R, lvl: Compression) -> read::GzEncoder<R> {
read::gz_encoder(self.buf_read(BufReader::new(r), lvl))
}
/// Consume this builder, creating a reader encoder in the process.
///
/// Data read from the returned encoder will be the compressed version of
/// the data read from the given reader.
pub fn buf_read<R>(self, r: R, lvl: Compression) -> bufread::GzEncoder<R>
where
R: BufRead,
{
bufread::gz_encoder(self.into_header(lvl), r, lvl)
}
fn into_header(self, lvl: Compression) -> Vec<u8> {
let GzBuilder {
extra,
filename,
comment,
operating_system,
mtime,
} = self;
let mut flg = 0;
let mut header = vec![0u8; 10];
if let Some(v) = extra {
flg |= FEXTRA;
header.push((v.len() >> 0) as u8);
header.push((v.len() >> 8) as u8);
header.extend(v);
}
if let Some(filename) = filename {
flg |= FNAME;
header.extend(filename.as_bytes_with_nul().iter().copied());
}
if let Some(comment) = comment {
flg |= FCOMMENT;
header.extend(comment.as_bytes_with_nul().iter().copied());
}
header[0] = 0x1f;
header[1] = 0x8b;
header[2] = 8;
header[3] = flg;
header[4] = (mtime >> 0) as u8;
header[5] = (mtime >> 8) as u8;
header[6] = (mtime >> 16) as u8;
header[7] = (mtime >> 24) as u8;
header[8] = if lvl.0 >= Compression::best().0 {
2
} else if lvl.0 <= Compression::fast().0 {
4
} else {
0
};
// Typically this byte indicates what OS the gz stream was created on,
// but in an effort to have cross-platform reproducible streams just
// 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);
header
}
}
#[cfg(test)]
mod tests {
use std::io::prelude::*;
use super::{read, write, GzBuilder, GzHeaderParser};
use crate::{Compression, GzHeader};
use rand::{thread_rng, Rng};
#[test]
fn roundtrip() {
let mut e = write::GzEncoder::new(Vec::new(), Compression::default());
e.write_all(b"foo bar baz").unwrap();
let inner = e.finish().unwrap();
let mut d = read::GzDecoder::new(&inner[..]);
let mut s = String::new();
d.read_to_string(&mut s).unwrap();
assert_eq!(s, "foo bar baz");
}
#[test]
fn roundtrip_zero() {
let e = write::GzEncoder::new(Vec::new(), Compression::default());
let inner = e.finish().unwrap();
let mut d = read::GzDecoder::new(&inner[..]);
let mut s = String::new();
d.read_to_string(&mut s).unwrap();
assert_eq!(s, "");
}
#[test]
fn roundtrip_big() {
let mut real = Vec::new();
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())];
real.extend(to_write.iter().copied());
w.write_all(to_write).unwrap();
}
let result = w.finish().unwrap();
let mut r = read::GzDecoder::new(&result[..]);
let mut v = Vec::new();
r.read_to_end(&mut v).unwrap();
assert_eq!(v, real);
}
#[test]
fn roundtrip_big2() {
let v = crate::random_bytes().take(1024 * 1024).collect::<Vec<_>>();
let mut r = read::GzDecoder::new(read::GzEncoder::new(&v[..], Compression::default()));
let mut res = Vec::new();
r.read_to_end(&mut res).unwrap();
assert_eq!(res, v);
}
// A Rust implementation of CRC that closely matches the C code in RFC1952.
// Only use this to create CRCs for tests.
struct Rfc1952Crc {
/* Table of CRCs of all 8-bit messages. */
crc_table: [u32; 256],
}
impl Rfc1952Crc {
fn new() -> Self {
let mut crc = Rfc1952Crc {
crc_table: [0; 256],
};
/* Make the table for a fast CRC. */
for n in 0usize..256 {
let mut c = n as u32;
for _k in 0..8 {
if c & 1 != 0 {
c = 0xedb88320 ^ (c >> 1);
} else {
c = c >> 1;
}
}
crc.crc_table[n] = c;
}
crc
}
/*
Update a running crc with the bytes buf and return
the updated crc. The crc should be initialized to zero. Pre- and
post-conditioning (one's complement) is performed within this
function so it shouldn't be done by the caller.
*/
fn update_crc(&self, crc: u32, buf: &[u8]) -> u32 {
let mut c = crc ^ 0xffffffff;
for b in buf {
c = self.crc_table[(c as u8 ^ *b) as usize] ^ (c >> 8);
}
c ^ 0xffffffff
}
/* Return the CRC of the bytes buf. */
fn crc(&self, buf: &[u8]) -> u32 {
self.update_crc(0, buf)
}
}
#[test]
fn roundtrip_header() {
let mut header = GzBuilder::new()
.mtime(1234)
.operating_system(57)
.filename("filename")
.comment("comment")
.into_header(Compression::fast());
// Add a CRC to the header
header[3] = header[3] ^ super::FHCRC;
let rfc1952_crc = Rfc1952Crc::new();
let crc32 = rfc1952_crc.crc(&header);
let crc16 = crc32 as u16;
header.extend(&crc16.to_le_bytes());
let mut parser = GzHeaderParser::new();
parser.parse(&mut header.as_slice()).unwrap();
let actual = parser.header().unwrap();
assert_eq!(
actual,
&GzHeader {
extra: None,
filename: Some("filename".as_bytes().to_vec()),
comment: Some("comment".as_bytes().to_vec()),
operating_system: 57,
mtime: 1234
}
)
}
#[test]
fn fields() {
let r = vec![0, 2, 4, 6];
let e = GzBuilder::new()
.filename("foo.rs")
.comment("bar")
.extra(vec![0, 1, 2, 3])
.read(&r[..], Compression::default());
let mut d = read::GzDecoder::new(e);
assert_eq!(d.header().unwrap().filename(), Some(&b"foo.rs"[..]));
assert_eq!(d.header().unwrap().comment(), Some(&b"bar"[..]));
assert_eq!(d.header().unwrap().extra(), Some(&b"\x00\x01\x02\x03"[..]));
let mut res = Vec::new();
d.read_to_end(&mut res).unwrap();
assert_eq!(res, vec![0, 2, 4, 6]);
}
#[test]
fn keep_reading_after_end() {
let mut e = write::GzEncoder::new(Vec::new(), Compression::default());
e.write_all(b"foo bar baz").unwrap();
let inner = e.finish().unwrap();
let mut d = read::GzDecoder::new(&inner[..]);
let mut s = String::new();
d.read_to_string(&mut s).unwrap();
assert_eq!(s, "foo bar baz");
d.read_to_string(&mut s).unwrap();
assert_eq!(s, "foo bar baz");
}
#[test]
fn qc_reader() {
::quickcheck::quickcheck(test as fn(_) -> _);
fn test(v: Vec<u8>) -> bool {
let r = read::GzEncoder::new(&v[..], Compression::default());
let mut r = read::GzDecoder::new(r);
let mut v2 = Vec::new();
r.read_to_end(&mut v2).unwrap();
v == v2
}
}
#[test]
fn flush_after_write() {
let mut f = write::GzEncoder::new(Vec::new(), Compression::default());
write!(f, "Hello world").unwrap();
f.flush().unwrap();
}
}

378
vendor/flate2/src/gz/read.rs vendored Normal file
View File

@ -0,0 +1,378 @@
use std::io;
use std::io::prelude::*;
use super::bufread;
use super::{GzBuilder, GzHeader};
use crate::bufreader::BufReader;
use crate::Compression;
/// A gzip streaming encoder
///
/// This structure implements a [`Read`] interface. When read from, it reads
/// uncompressed data from the underlying [`Read`] and provides the compressed data.
///
/// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
///
/// # Examples
///
/// ```
/// use std::io::prelude::*;
/// use std::io;
/// use flate2::Compression;
/// use flate2::read::GzEncoder;
///
/// // Return a vector containing the GZ compressed version of hello world
///
/// fn gzencode_hello_world() -> io::Result<Vec<u8>> {
/// let mut ret_vec = Vec::new();
/// let bytestring = b"hello world";
/// let mut gz = GzEncoder::new(&bytestring[..], Compression::fast());
/// gz.read_to_end(&mut ret_vec)?;
/// Ok(ret_vec)
/// }
/// ```
#[derive(Debug)]
pub struct GzEncoder<R> {
inner: bufread::GzEncoder<BufReader<R>>,
}
pub fn gz_encoder<R: Read>(inner: bufread::GzEncoder<BufReader<R>>) -> GzEncoder<R> {
GzEncoder { inner }
}
impl<R: Read> GzEncoder<R> {
/// Creates a new encoder which will use the given compression level.
///
/// The encoder is not configured specially for the emitted header. For
/// header configuration, see the `GzBuilder` type.
///
/// The data read from the stream `r` will be compressed and available
/// through the returned reader.
pub fn new(r: R, level: Compression) -> GzEncoder<R> {
GzBuilder::new().read(r, level)
}
}
impl<R> GzEncoder<R> {
/// Acquires a reference to the underlying reader.
pub fn get_ref(&self) -> &R {
self.inner.get_ref().get_ref()
}
/// Acquires a mutable reference to the underlying reader.
///
/// Note that mutation of the reader may result in surprising results if
/// this encoder is continued to be used.
pub fn get_mut(&mut self) -> &mut R {
self.inner.get_mut().get_mut()
}
/// Returns the underlying stream, consuming this encoder
pub fn into_inner(self) -> R {
self.inner.into_inner().into_inner()
}
}
impl<R: Read> Read for GzEncoder<R> {
fn read(&mut self, into: &mut [u8]) -> io::Result<usize> {
self.inner.read(into)
}
}
impl<R: Read + Write> Write for GzEncoder<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()
}
}
/// A decoder for a single member of a [gzip file].
///
/// This structure implements a [`Read`] interface. When read from, it reads
/// compressed data from the underlying [`Read`] and provides the uncompressed data.
///
/// After reading a single member of the gzip data this reader will return
/// Ok(0) even if there are more bytes available in the underlying reader.
/// `GzDecoder` may have read additional bytes past the end of the gzip data.
/// If you need the following bytes, wrap the `Reader` in a `std::io::BufReader`
/// and use `bufread::GzDecoder` instead.
///
/// To handle gzip files that may have multiple members, see [`MultiGzDecoder`]
/// or read more
/// [in the introduction](../index.html#about-multi-member-gzip-files).
///
/// [gzip file]: https://www.rfc-editor.org/rfc/rfc1952#page-5
///
/// # Examples
///
/// ```
/// use std::io::prelude::*;
/// use std::io;
/// # use flate2::Compression;
/// # use flate2::write::GzEncoder;
/// use flate2::read::GzDecoder;
///
/// # fn main() {
/// # let mut e = GzEncoder::new(Vec::new(), Compression::default());
/// # e.write_all(b"Hello World").unwrap();
/// # let bytes = e.finish().unwrap();
/// # println!("{}", decode_reader(bytes).unwrap());
/// # }
/// #
/// // 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 s = String::new();
/// gz.read_to_string(&mut s)?;
/// Ok(s)
/// }
/// ```
#[derive(Debug)]
pub struct GzDecoder<R> {
inner: bufread::GzDecoder<BufReader<R>>,
}
impl<R: Read> GzDecoder<R> {
/// Creates a new decoder from the given reader, immediately parsing the
/// gzip header.
pub fn new(r: R) -> GzDecoder<R> {
GzDecoder {
inner: bufread::GzDecoder::new(BufReader::new(r)),
}
}
}
impl<R> GzDecoder<R> {
/// Returns the header associated with this stream, if it was valid.
pub fn header(&self) -> Option<&GzHeader> {
self.inner.header()
}
/// Acquires a reference to the underlying reader.
///
/// Note that the decoder may have read past the end of the gzip data.
/// To prevent this use [`bufread::GzDecoder`] instead.
pub fn get_ref(&self) -> &R {
self.inner.get_ref().get_ref()
}
/// Acquires a mutable reference to the underlying stream.
///
/// Note that mutation of the stream may result in surprising results if
/// this decoder continues to be used.
///
/// Note that the decoder may have read past the end of the gzip data.
/// To prevent this use [`bufread::GzDecoder`] instead.
pub fn get_mut(&mut self) -> &mut R {
self.inner.get_mut().get_mut()
}
/// Consumes this decoder, returning the underlying reader.
///
/// Note that the decoder may have read past the end of the gzip data.
/// Subsequent reads will skip those bytes. To prevent this use
/// [`bufread::GzDecoder`] instead.
pub fn into_inner(self) -> R {
self.inner.into_inner().into_inner()
}
}
impl<R: Read> Read for GzDecoder<R> {
fn read(&mut self, into: &mut [u8]) -> io::Result<usize> {
self.inner.read(into)
}
}
impl<R: Read + Write> Write for GzDecoder<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()
}
}
/// A gzip streaming decoder that decodes a [gzip file] that may have multiple members.
///
/// This structure implements a [`Read`] interface. When read from, it reads
/// compressed data from the underlying [`Read`] and provides the uncompressed
/// data.
///
/// A gzip file consists of a series of *members* concatenated one after another.
/// MultiGzDecoder decodes all members of a file and returns Ok(0) once the
/// underlying reader does.
///
/// To handle members seperately, see [GzDecoder] or read more
/// [in the introduction](../index.html#about-multi-member-gzip-files).
///
/// [gzip file]: https://www.rfc-editor.org/rfc/rfc1952#page-5
///
/// # Examples
///
/// ```
/// use std::io::prelude::*;
/// use std::io;
/// # use flate2::Compression;
/// # use flate2::write::GzEncoder;
/// use flate2::read::MultiGzDecoder;
///
/// # fn main() {
/// # let mut e = GzEncoder::new(Vec::new(), Compression::default());
/// # e.write_all(b"Hello World").unwrap();
/// # let bytes = e.finish().unwrap();
/// # println!("{}", decode_reader(bytes).unwrap());
/// # }
/// #
/// // 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 = MultiGzDecoder::new(&bytes[..]);
/// let mut s = String::new();
/// gz.read_to_string(&mut s)?;
/// Ok(s)
/// }
/// ```
#[derive(Debug)]
pub struct MultiGzDecoder<R> {
inner: bufread::MultiGzDecoder<BufReader<R>>,
}
impl<R: Read> MultiGzDecoder<R> {
/// Creates a new decoder from the given reader, immediately parsing the
/// (first) gzip header. If the gzip stream contains multiple members all will
/// be decoded.
pub fn new(r: R) -> MultiGzDecoder<R> {
MultiGzDecoder {
inner: bufread::MultiGzDecoder::new(BufReader::new(r)),
}
}
}
impl<R> MultiGzDecoder<R> {
/// Returns the current header associated with this stream, if it's valid.
pub fn header(&self) -> Option<&GzHeader> {
self.inner.header()
}
/// Acquires a reference to the underlying reader.
pub fn get_ref(&self) -> &R {
self.inner.get_ref().get_ref()
}
/// Acquires a mutable reference to the underlying stream.
///
/// Note that mutation of the stream may result in surprising results if
/// this decoder is continued to be used.
pub fn get_mut(&mut self) -> &mut R {
self.inner.get_mut().get_mut()
}
/// Consumes this decoder, returning the underlying reader.
pub fn into_inner(self) -> R {
self.inner.into_inner().into_inner()
}
}
impl<R: Read> Read for MultiGzDecoder<R> {
fn read(&mut self, into: &mut [u8]) -> io::Result<usize> {
self.inner.read(into)
}
}
impl<R: Read + 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(test)]
mod tests {
use std::io::{Cursor, ErrorKind, Read, Result, Write};
use super::GzDecoder;
//a cursor turning EOF into blocking errors
#[derive(Debug)]
pub struct BlockingCursor {
pub cursor: Cursor<Vec<u8>>,
}
impl BlockingCursor {
pub fn new() -> BlockingCursor {
BlockingCursor {
cursor: Cursor::new(Vec::new()),
}
}
pub fn set_position(&mut self, pos: u64) {
return self.cursor.set_position(pos);
}
}
impl Write for BlockingCursor {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
return self.cursor.write(buf);
}
fn flush(&mut self) -> Result<()> {
return self.cursor.flush();
}
}
impl Read for BlockingCursor {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
//use the cursor, except it turns eof into blocking error
let r = self.cursor.read(buf);
match r {
Err(ref err) => {
if err.kind() == ErrorKind::UnexpectedEof {
return Err(ErrorKind::WouldBlock.into());
}
}
Ok(0) => {
//regular EOF turned into blocking error
return Err(ErrorKind::WouldBlock.into());
}
Ok(_n) => {}
}
return r;
}
}
#[test]
fn blocked_partial_header_read() {
// this is a reader which receives data afterwards
let mut r = BlockingCursor::new();
let data = vec![1, 2, 3];
match r.write_all(&data) {
Ok(()) => {}
_ => {
panic!("Unexpected result for write_all");
}
}
r.set_position(0);
// this is unused except for the buffering
let mut decoder = GzDecoder::new(r);
let mut out = Vec::with_capacity(7);
match decoder.read(&mut out) {
Err(e) => {
assert_eq!(e.kind(), ErrorKind::WouldBlock);
}
_ => {
panic!("Unexpected result for decoder.read");
}
}
}
}

641
vendor/flate2/src/gz/write.rs vendored Normal file
View File

@ -0,0 +1,641 @@
use std::cmp;
use std::io;
use std::io::prelude::*;
use super::{corrupt, GzBuilder, GzHeader, GzHeaderParser};
use crate::crc::{Crc, CrcWriter};
use crate::zio;
use crate::{Compress, Compression, Decompress, Status};
/// A gzip streaming encoder
///
/// This structure exposes a [`Write`] interface that will emit compressed data
/// to the underlying writer `W`.
///
/// [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
///
/// # Examples
///
/// ```
/// use std::io::prelude::*;
/// use flate2::Compression;
/// use flate2::write::GzEncoder;
///
/// // Vec<u8> implements Write to print the compressed bytes of sample string
/// # fn main() {
///
/// let mut e = GzEncoder::new(Vec::new(), Compression::default());
/// e.write_all(b"Hello World").unwrap();
/// println!("{:?}", e.finish().unwrap());
/// # }
/// ```
#[derive(Debug)]
pub struct GzEncoder<W: Write> {
inner: zio::Writer<W, Compress>,
crc: Crc,
crc_bytes_written: usize,
header: Vec<u8>,
}
pub fn gz_encoder<W: Write>(header: Vec<u8>, w: W, lvl: Compression) -> GzEncoder<W> {
GzEncoder {
inner: zio::Writer::new(w, Compress::new(lvl, false)),
crc: Crc::new(),
header,
crc_bytes_written: 0,
}
}
impl<W: Write> GzEncoder<W> {
/// Creates a new encoder which will use the given compression level.
///
/// The encoder is not configured specially for the emitted header. For
/// header configuration, see the `GzBuilder` type.
///
/// The data written to the returned encoder will be compressed and then
/// written to the stream `w`.
pub fn new(w: W, level: Compression) -> GzEncoder<W> {
GzBuilder::new().write(w, level)
}
/// Acquires a reference to the underlying writer.
pub fn get_ref(&self) -> &W {
self.inner.get_ref()
}
/// Acquires a mutable reference to the underlying writer.
///
/// Note that mutation of the writer may result in surprising results if
/// this encoder is continued to be used.
pub fn get_mut(&mut self) -> &mut W {
self.inner.get_mut()
}
/// Attempt to finish this output stream, writing out final chunks of data.
///
/// Note that this function can only be used once data has finished being
/// written to the output stream. After this function is called then further
/// calls to `write` may result in a panic.
///
/// # Panics
///
/// Attempts to write data to this stream may result in a panic after this
/// function is called.
///
/// # Errors
///
/// This function will perform I/O to complete this stream, and any I/O
/// errors which occur will be returned from this function.
pub fn try_finish(&mut self) -> io::Result<()> {
self.write_header()?;
self.inner.finish()?;
while self.crc_bytes_written < 8 {
let (sum, amt) = (self.crc.sum(), self.crc.amount());
let buf = [
(sum >> 0) as u8,
(sum >> 8) as u8,
(sum >> 16) as u8,
(sum >> 24) as u8,
(amt >> 0) as u8,
(amt >> 8) as u8,
(amt >> 16) as u8,
(amt >> 24) as u8,
];
let inner = self.inner.get_mut();
let n = inner.write(&buf[self.crc_bytes_written..])?;
self.crc_bytes_written += n;
}
Ok(())
}
/// Finish encoding this stream, returning the underlying writer once the
/// encoding is done.
///
/// Note that this function may not be suitable to call in a situation where
/// the underlying stream is an asynchronous I/O stream. To finish a stream
/// the `try_finish` (or `shutdown`) method should be used instead. To
/// re-acquire ownership of a stream it is safe to call this method after
/// `try_finish` or `shutdown` has returned `Ok`.
///
/// # Errors
///
/// This function will perform I/O to complete this stream, and any I/O
/// errors which occur will be returned from this function.
pub fn finish(mut self) -> io::Result<W> {
self.try_finish()?;
Ok(self.inner.take_inner())
}
fn write_header(&mut self) -> io::Result<()> {
while !self.header.is_empty() {
let n = self.inner.get_mut().write(&self.header)?;
self.header.drain(..n);
}
Ok(())
}
}
impl<W: Write> Write for GzEncoder<W> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
assert_eq!(self.crc_bytes_written, 0);
self.write_header()?;
let n = self.inner.write(buf)?;
self.crc.update(&buf[..n]);
Ok(n)
}
fn flush(&mut self) -> io::Result<()> {
assert_eq!(self.crc_bytes_written, 0);
self.write_header()?;
self.inner.flush()
}
}
impl<R: Read + Write> Read for GzEncoder<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.get_mut().read(buf)
}
}
impl<W: Write> Drop for GzEncoder<W> {
fn drop(&mut self) {
if self.inner.is_present() {
let _ = self.try_finish();
}
}
}
/// A decoder for a single member of a [gzip file].
///
/// This structure exposes a [`Write`] interface, receiving compressed data and
/// writing uncompressed data to the underlying writer.
///
/// After decoding a single member of the gzip data this writer will return the number of bytes up to
/// to the end of the gzip member and subsequent writes will return Ok(0) allowing the caller to
/// handle any data following the gzip member.
///
/// To handle gzip files that may have multiple members, see [`MultiGzDecoder`]
/// or read more
/// [in the introduction](../index.html#about-multi-member-gzip-files).
///
/// [gzip file]: https://www.rfc-editor.org/rfc/rfc1952#page-5
/// [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
///
/// # Examples
///
/// ```
/// use std::io::prelude::*;
/// use std::io;
/// use flate2::Compression;
/// use flate2::write::{GzEncoder, GzDecoder};
///
/// # fn main() {
/// # let mut e = GzEncoder::new(Vec::new(), Compression::default());
/// # e.write(b"Hello World").unwrap();
/// # let bytes = e.finish().unwrap();
/// # assert_eq!("Hello World", decode_writer(bytes).unwrap());
/// # }
/// // Uncompresses a gzip encoded vector of bytes and returns a string or error
/// // Here Vec<u8> implements Write
/// fn decode_writer(bytes: Vec<u8>) -> io::Result<String> {
/// let mut writer = Vec::new();
/// let mut decoder = GzDecoder::new(writer);
/// decoder.write_all(&bytes[..])?;
/// writer = decoder.finish()?;
/// let return_string = String::from_utf8(writer).expect("String parsing error");
/// Ok(return_string)
/// }
/// ```
#[derive(Debug)]
pub struct GzDecoder<W: Write> {
inner: zio::Writer<CrcWriter<W>, Decompress>,
crc_bytes: Vec<u8>,
header_parser: GzHeaderParser,
}
const CRC_BYTES_LEN: usize = 8;
impl<W: Write> GzDecoder<W> {
/// Creates a new decoder which will write uncompressed data to the stream.
///
/// When this encoder is dropped or unwrapped the final pieces of data will
/// be flushed.
pub fn new(w: W) -> GzDecoder<W> {
GzDecoder {
inner: zio::Writer::new(CrcWriter::new(w), Decompress::new(false)),
crc_bytes: Vec::with_capacity(CRC_BYTES_LEN),
header_parser: GzHeaderParser::new(),
}
}
/// Returns the header associated with this stream.
pub fn header(&self) -> Option<&GzHeader> {
self.header_parser.header()
}
/// Acquires a reference to the underlying writer.
pub fn get_ref(&self) -> &W {
self.inner.get_ref().get_ref()
}
/// Acquires a mutable reference to the underlying writer.
///
/// Note that mutating the output/input state of the stream may corrupt this
/// object, so care must be taken when using this method.
pub fn get_mut(&mut self) -> &mut W {
self.inner.get_mut().get_mut()
}
/// Attempt to finish this output stream, writing out final chunks of data.
///
/// Note that this function can only be used once data has finished being
/// written to the output stream. After this function is called then further
/// calls to `write` may result in a panic.
///
/// # Panics
///
/// Attempts to write data to this stream may result in a panic after this
/// function is called.
///
/// # Errors
///
/// This function will perform I/O to finish the stream, returning any
/// errors which happen.
pub fn try_finish(&mut self) -> io::Result<()> {
self.finish_and_check_crc()?;
Ok(())
}
/// Consumes this decoder, flushing the output stream.
///
/// This will flush the underlying data stream and then return the contained
/// writer if the flush succeeded.
///
/// Note that this function may not be suitable to call in a situation where
/// the underlying stream is an asynchronous I/O stream. To finish a stream
/// the `try_finish` (or `shutdown`) method should be used instead. To
/// re-acquire ownership of a stream it is safe to call this method after
/// `try_finish` or `shutdown` has returned `Ok`.
///
/// # Errors
///
/// This function will perform I/O to complete this stream, and any I/O
/// errors which occur will be returned from this function.
pub fn finish(mut self) -> io::Result<W> {
self.finish_and_check_crc()?;
Ok(self.inner.take_inner().into_inner())
}
fn finish_and_check_crc(&mut self) -> io::Result<()> {
self.inner.finish()?;
if self.crc_bytes.len() != 8 {
return Err(corrupt());
}
let crc = ((self.crc_bytes[0] as u32) << 0)
| ((self.crc_bytes[1] as u32) << 8)
| ((self.crc_bytes[2] as u32) << 16)
| ((self.crc_bytes[3] as u32) << 24);
let amt = ((self.crc_bytes[4] as u32) << 0)
| ((self.crc_bytes[5] as u32) << 8)
| ((self.crc_bytes[6] as u32) << 16)
| ((self.crc_bytes[7] as u32) << 24);
if crc != self.inner.get_ref().crc().sum() {
return Err(corrupt());
}
if amt != self.inner.get_ref().crc().amount() {
return Err(corrupt());
}
Ok(())
}
}
impl<W: Write> Write for GzDecoder<W> {
fn write(&mut self, mut buf: &[u8]) -> io::Result<usize> {
let buflen = buf.len();
if self.header().is_none() {
match self.header_parser.parse(&mut buf) {
Err(err) => {
if err.kind() == io::ErrorKind::UnexpectedEof {
// all data read but header still not complete
Ok(buflen)
} else {
Err(err)
}
}
Ok(_) => {
debug_assert!(self.header().is_some());
// buf now contains the unread part of the original buf
let n = buflen - buf.len();
Ok(n)
}
}
} else {
let (n, status) = self.inner.write_with_status(buf)?;
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)
}
}
fn flush(&mut self) -> io::Result<()> {
self.inner.flush()
}
}
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)
}
}
/// A gzip streaming decoder that decodes a [gzip file] with multiple members.
///
/// This structure exposes a [`Write`] interface that will consume compressed data and
/// write uncompressed data to the underlying writer.
///
/// A gzip file consists of a series of *members* concatenated one after another.
/// `MultiGzDecoder` decodes all members of a file and writes them to the
/// underlying writer one after another.
///
/// To handle members separately, see [GzDecoder] or read more
/// [in the introduction](../index.html#about-multi-member-gzip-files).
///
/// [gzip file]: https://www.rfc-editor.org/rfc/rfc1952#page-5
#[derive(Debug)]
pub struct MultiGzDecoder<W: Write> {
inner: GzDecoder<W>,
}
impl<W: Write> MultiGzDecoder<W> {
/// Creates a new decoder which will write uncompressed data to the stream.
/// If the gzip stream contains multiple members all will be decoded.
pub fn new(w: W) -> MultiGzDecoder<W> {
MultiGzDecoder {
inner: GzDecoder::new(w),
}
}
/// Returns the header associated with the current member.
pub fn header(&self) -> Option<&GzHeader> {
self.inner.header()
}
/// Acquires a reference to the underlying writer.
pub fn get_ref(&self) -> &W {
self.inner.get_ref()
}
/// Acquires a mutable reference to the underlying writer.
///
/// Note that mutating the output/input state of the stream may corrupt this
/// object, so care must be taken when using this method.
pub fn get_mut(&mut self) -> &mut W {
self.inner.get_mut()
}
/// Attempt to finish this output stream, writing out final chunks of data.
///
/// Note that this function can only be used once data has finished being
/// written to the output stream. After this function is called then further
/// calls to `write` may result in a panic.
///
/// # Panics
///
/// Attempts to write data to this stream may result in a panic after this
/// function is called.
///
/// # Errors
///
/// This function will perform I/O to finish the stream, returning any
/// errors which happen.
pub fn try_finish(&mut self) -> io::Result<()> {
self.inner.try_finish()
}
/// Consumes this decoder, flushing the output stream.
///
/// This will flush the underlying data stream and then return the contained
/// writer if the flush succeeded.
///
/// Note that this function may not be suitable to call in a situation where
/// the underlying stream is an asynchronous I/O stream. To finish a stream
/// the `try_finish` (or `shutdown`) method should be used instead. To
/// re-acquire ownership of a stream it is safe to call this method after
/// `try_finish` or `shutdown` has returned `Ok`.
///
/// # Errors
///
/// This function will perform I/O to complete this stream, and any I/O
/// errors which occur will be returned from this function.
pub fn finish(self) -> io::Result<W> {
self.inner.finish()
}
}
impl<W: Write> Write for MultiGzDecoder<W> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
if buf.is_empty() {
Ok(0)
} else {
match self.inner.write(buf) {
Ok(0) => {
// When the GzDecoder indicates that it has finished
// create a new GzDecoder to handle additional data.
self.inner.try_finish()?;
let w = self.inner.inner.take_inner().into_inner();
self.inner = GzDecoder::new(w);
self.inner.write(buf)
}
res => res,
}
}
}
fn flush(&mut self) -> io::Result<()> {
self.inner.flush()
}
}
#[cfg(test)]
mod tests {
use super::*;
const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World";
#[test]
fn decode_writer_one_chunk() {
let mut e = GzEncoder::new(Vec::new(), Compression::default());
e.write(STR.as_ref()).unwrap();
let bytes = e.finish().unwrap();
let mut writer = Vec::new();
let mut decoder = GzDecoder::new(writer);
let n = decoder.write(&bytes[..]).unwrap();
decoder.write(&bytes[n..]).unwrap();
decoder.try_finish().unwrap();
writer = decoder.finish().unwrap();
let return_string = String::from_utf8(writer).expect("String parsing error");
assert_eq!(return_string, STR);
}
#[test]
fn decode_writer_partial_header() {
let mut e = GzEncoder::new(Vec::new(), Compression::default());
e.write(STR.as_ref()).unwrap();
let bytes = e.finish().unwrap();
let mut writer = Vec::new();
let mut decoder = GzDecoder::new(writer);
assert_eq!(decoder.write(&bytes[..5]).unwrap(), 5);
let n = decoder.write(&bytes[5..]).unwrap();
if n < bytes.len() - 5 {
decoder.write(&bytes[n + 5..]).unwrap();
}
writer = decoder.finish().unwrap();
let return_string = String::from_utf8(writer).expect("String parsing error");
assert_eq!(return_string, STR);
}
#[test]
fn decode_writer_partial_header_filename() {
let filename = "test.txt";
let mut e = GzBuilder::new()
.filename(filename)
.read(STR.as_bytes(), Compression::default());
let mut bytes = Vec::new();
e.read_to_end(&mut bytes).unwrap();
let mut writer = Vec::new();
let mut decoder = GzDecoder::new(writer);
assert_eq!(decoder.write(&bytes[..12]).unwrap(), 12);
let n = decoder.write(&bytes[12..]).unwrap();
if n < bytes.len() - 12 {
decoder.write(&bytes[n + 12..]).unwrap();
}
assert_eq!(
decoder.header().unwrap().filename().unwrap(),
filename.as_bytes()
);
writer = decoder.finish().unwrap();
let return_string = String::from_utf8(writer).expect("String parsing error");
assert_eq!(return_string, STR);
}
#[test]
fn decode_writer_partial_header_comment() {
let comment = "test comment";
let mut e = GzBuilder::new()
.comment(comment)
.read(STR.as_bytes(), Compression::default());
let mut bytes = Vec::new();
e.read_to_end(&mut bytes).unwrap();
let mut writer = Vec::new();
let mut decoder = GzDecoder::new(writer);
assert_eq!(decoder.write(&bytes[..12]).unwrap(), 12);
let n = decoder.write(&bytes[12..]).unwrap();
if n < bytes.len() - 12 {
decoder.write(&bytes[n + 12..]).unwrap();
}
assert_eq!(
decoder.header().unwrap().comment().unwrap(),
comment.as_bytes()
);
writer = decoder.finish().unwrap();
let return_string = String::from_utf8(writer).expect("String parsing error");
assert_eq!(return_string, STR);
}
#[test]
fn decode_writer_exact_header() {
let mut e = GzEncoder::new(Vec::new(), Compression::default());
e.write(STR.as_ref()).unwrap();
let bytes = e.finish().unwrap();
let mut writer = Vec::new();
let mut decoder = GzDecoder::new(writer);
assert_eq!(decoder.write(&bytes[..10]).unwrap(), 10);
decoder.write(&bytes[10..]).unwrap();
writer = decoder.finish().unwrap();
let return_string = String::from_utf8(writer).expect("String parsing error");
assert_eq!(return_string, STR);
}
#[test]
fn decode_writer_partial_crc() {
let mut e = GzEncoder::new(Vec::new(), Compression::default());
e.write(STR.as_ref()).unwrap();
let bytes = e.finish().unwrap();
let mut writer = Vec::new();
let mut decoder = GzDecoder::new(writer);
let l = bytes.len() - 5;
let n = decoder.write(&bytes[..l]).unwrap();
decoder.write(&bytes[n..]).unwrap();
writer = decoder.finish().unwrap();
let return_string = String::from_utf8(writer).expect("String parsing error");
assert_eq!(return_string, STR);
}
// Two or more gzip files concatenated form a multi-member gzip file. MultiGzDecoder will
// concatenate the decoded contents of all members.
#[test]
fn decode_multi_writer() {
let mut e = GzEncoder::new(Vec::new(), Compression::default());
e.write(STR.as_ref()).unwrap();
let bytes = e.finish().unwrap().repeat(2);
let mut writer = Vec::new();
let mut decoder = MultiGzDecoder::new(writer);
let mut count = 0;
while count < bytes.len() {
let n = decoder.write(&bytes[count..]).unwrap();
assert!(n != 0);
count += n;
}
writer = decoder.finish().unwrap();
let return_string = String::from_utf8(writer).expect("String parsing error");
let expected = STR.repeat(2);
assert_eq!(return_string, expected);
}
// GzDecoder consumes one gzip member and then returns 0 for subsequent writes, allowing any
// additional data to be consumed by the caller.
#[test]
fn decode_extra_data() {
let compressed = {
let mut e = GzEncoder::new(Vec::new(), Compression::default());
e.write(STR.as_ref()).unwrap();
let mut b = e.finish().unwrap();
b.push(b'x');
b
};
let mut writer = Vec::new();
let mut decoder = GzDecoder::new(writer);
let mut consumed_bytes = 0;
loop {
let n = decoder.write(&compressed[consumed_bytes..]).unwrap();
if n == 0 {
break;
}
consumed_bytes += n;
}
writer = decoder.finish().unwrap();
let actual = String::from_utf8(writer).expect("String parsing error");
assert_eq!(actual, STR);
assert_eq!(&compressed[consumed_bytes..], b"x");
}
}

234
vendor/flate2/src/lib.rs vendored Normal file
View File

@ -0,0 +1,234 @@
//! A DEFLATE-based stream compression/decompression library
//!
//! This library provides support for compression and decompression of
//! DEFLATE-based streams:
//!
//! * the DEFLATE format itself
//! * the zlib format
//! * gzip
//!
//! These three formats are all closely related and largely only differ in their
//! headers/footers. This crate has three types in each submodule for dealing
//! with these three formats.
//!
//! # Implementation
//!
//! 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.
//!
//! * `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).
//!
//! 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
//!
//! This crate consists mainly of three modules, [`read`], [`write`], and
//! [`bufread`]. Each module contains a number of types used to encode and
//! decode various streams of data.
//!
//! All types in the [`write`] module work on instances of [`Write`][write],
//! whereas all types in the [`read`] module work on instances of
//! [`Read`][read] and [`bufread`] works with [`BufRead`][bufread]. If you
//! are decoding directly from a `&[u8]`, use the [`bufread`] types.
//!
//! ```
//! use flate2::write::GzEncoder;
//! use flate2::Compression;
//! use std::io;
//! use std::io::prelude::*;
//!
//! # fn main() { let _ = run(); }
//! # fn run() -> io::Result<()> {
//! let mut encoder = GzEncoder::new(Vec::new(), Compression::default());
//! encoder.write_all(b"Example")?;
//! # Ok(())
//! # }
//! ```
//!
//!
//! Other various types are provided at the top-level of the crate for
//! management and dealing with encoders/decoders. Also note that types which
//! operate over a specific trait often implement the mirroring trait as well.
//! For example a `flate2::read::DeflateDecoder<T>` *also* implements the
//! `Write` trait if `T: Write`. That is, the "dual trait" is forwarded directly
//! to the underlying object if available.
//!
//! # About multi-member Gzip files
//!
//! While most `gzip` files one encounters will have a single *member* that can be read
//! with the [`GzDecoder`], there may be some files which have multiple members.
//!
//! A [`GzDecoder`] will only read the first member of gzip data, which may unexpectedly
//! provide partial results when a multi-member gzip file is encountered. `GzDecoder` is appropriate
//! for data that is designed to be read as single members from a multi-member file. `bufread::GzDecoder`
//! and `write::GzDecoder` also allow non-gzip data following gzip data to be handled.
//!
//! The [`MultiGzDecoder`] on the other hand will decode all members of a `gzip` file
//! into one consecutive stream of bytes, which hides the underlying *members* entirely.
//! If a file contains contains non-gzip data after the gzip data, MultiGzDecoder will
//! emit an error after decoding the gzip data. This behavior matches the `gzip`,
//! `gunzip`, and `zcat` command line tools.
//!
//! [`read`]: read/index.html
//! [`bufread`]: bufread/index.html
//! [`write`]: write/index.html
//! [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
//! [`GzDecoder`]: read/struct.GzDecoder.html
//! [`MultiGzDecoder`]: read/struct.MultiGzDecoder.html
#![doc(html_root_url = "https://docs.rs/flate2/0.2")]
#![deny(missing_docs)]
#![deny(missing_debug_implementations)]
#![allow(trivial_numeric_casts)]
#![cfg_attr(test, deny(warnings))]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#[cfg(not(feature = "any_impl",))]
compile_error!("You need to choose a zlib backend");
pub use crate::crc::{Crc, CrcReader, CrcWriter};
pub use crate::gz::GzBuilder;
pub use crate::gz::GzHeader;
pub use crate::mem::{Compress, CompressError, Decompress, DecompressError, Status};
pub use crate::mem::{FlushCompress, FlushDecompress};
mod bufreader;
mod crc;
mod deflate;
mod ffi;
mod gz;
mod mem;
mod zio;
mod zlib;
/// Types which operate over [`Read`] streams, both encoders and decoders for
/// various formats.
///
/// Note that the `read` decoder types may read past the end of the compressed
/// data while decoding. If the caller requires subsequent reads to start
/// immediately following the compressed data wrap the `Read` type in a
/// [`BufReader`] and use the `BufReader` with the equivalent decoder from the
/// `bufread` module and also for the subsequent reads.
///
/// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
/// [`BufReader`]: https://doc.rust-lang.org/std/io/struct.BufReader.html
pub mod read {
pub use crate::deflate::read::DeflateDecoder;
pub use crate::deflate::read::DeflateEncoder;
pub use crate::gz::read::GzDecoder;
pub use crate::gz::read::GzEncoder;
pub use crate::gz::read::MultiGzDecoder;
pub use crate::zlib::read::ZlibDecoder;
pub use crate::zlib::read::ZlibEncoder;
}
/// Types which operate over [`Write`] streams, both encoders and decoders for
/// various formats.
///
/// [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
pub mod write {
pub use crate::deflate::write::DeflateDecoder;
pub use crate::deflate::write::DeflateEncoder;
pub use crate::gz::write::GzDecoder;
pub use crate::gz::write::GzEncoder;
pub use crate::gz::write::MultiGzDecoder;
pub use crate::zlib::write::ZlibDecoder;
pub use crate::zlib::write::ZlibEncoder;
}
/// Types which operate over [`BufRead`] streams, both encoders and decoders for
/// various formats.
///
/// [`BufRead`]: https://doc.rust-lang.org/std/io/trait.BufRead.html
pub mod bufread {
pub use crate::deflate::bufread::DeflateDecoder;
pub use crate::deflate::bufread::DeflateEncoder;
pub use crate::gz::bufread::GzDecoder;
pub use crate::gz::bufread::GzEncoder;
pub use crate::gz::bufread::MultiGzDecoder;
pub use crate::zlib::bufread::ZlibDecoder;
pub use crate::zlib::bufread::ZlibEncoder;
}
fn _assert_send_sync() {
fn _assert_send_sync<T: Send + Sync>() {}
_assert_send_sync::<read::DeflateEncoder<&[u8]>>();
_assert_send_sync::<read::DeflateDecoder<&[u8]>>();
_assert_send_sync::<read::ZlibEncoder<&[u8]>>();
_assert_send_sync::<read::ZlibDecoder<&[u8]>>();
_assert_send_sync::<read::GzEncoder<&[u8]>>();
_assert_send_sync::<read::GzDecoder<&[u8]>>();
_assert_send_sync::<read::MultiGzDecoder<&[u8]>>();
_assert_send_sync::<write::DeflateEncoder<Vec<u8>>>();
_assert_send_sync::<write::DeflateDecoder<Vec<u8>>>();
_assert_send_sync::<write::ZlibEncoder<Vec<u8>>>();
_assert_send_sync::<write::ZlibDecoder<Vec<u8>>>();
_assert_send_sync::<write::GzEncoder<Vec<u8>>>();
_assert_send_sync::<write::GzDecoder<Vec<u8>>>();
}
/// When compressing data, the compression level can be specified by a value in
/// this struct.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct Compression(u32);
impl Compression {
/// Creates a new description of the compression level with an explicitly
/// specified integer.
///
/// The integer here is typically on a scale of 0-9 where 0 means "no
/// compression" and 9 means "take as long as you'd like".
pub const fn new(level: u32) -> Compression {
Compression(level)
}
/// No compression is to be performed, this may actually inflate data
/// slightly when encoding.
pub const fn none() -> Compression {
Compression(0)
}
/// Optimize for the best speed of encoding.
pub const fn fast() -> Compression {
Compression(1)
}
/// Optimize for the size of data being encoded.
pub const fn best() -> Compression {
Compression(9)
}
/// Returns an integer representing the compression level, typically on a
/// scale of 0-9
pub fn level(&self) -> u32 {
self.0
}
}
impl Default for Compression {
fn default() -> Compression {
Compression(6)
}
}
#[cfg(test)]
fn random_bytes() -> impl Iterator<Item = u8> {
use rand::Rng;
use std::iter;
iter::repeat(()).map(|_| rand::thread_rng().gen())
}

772
vendor/flate2/src/mem.rs vendored Normal file
View File

@ -0,0 +1,772 @@
use std::error::Error;
use std::fmt;
use std::io;
use crate::ffi::{self, Backend, Deflate, DeflateBackend, ErrorMessage, Inflate, InflateBackend};
use crate::Compression;
/// Raw in-memory compression stream for blocks of data.
///
/// This type is the building block for the I/O streams in the rest of this
/// crate. It requires more management than the [`Read`]/[`Write`] API but is
/// maximally flexible in terms of accepting input from any source and being
/// able to produce output to any memory location.
///
/// It is recommended to use the I/O stream adaptors over this type as they're
/// easier to use.
///
/// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
/// [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
#[derive(Debug)]
pub struct Compress {
inner: Deflate,
}
/// Raw in-memory decompression stream for blocks of data.
///
/// This type is the building block for the I/O streams in the rest of this
/// crate. It requires more management than the [`Read`]/[`Write`] API but is
/// maximally flexible in terms of accepting input from any source and being
/// able to produce output to any memory location.
///
/// It is recommended to use the I/O stream adaptors over this type as they're
/// easier to use.
///
/// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
/// [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
#[derive(Debug)]
pub struct Decompress {
inner: Inflate,
}
/// Values which indicate the form of flushing to be used when compressing
/// in-memory data.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
#[non_exhaustive]
pub enum FlushCompress {
/// A typical parameter for passing to compression/decompression functions,
/// this indicates that the underlying stream to decide how much data to
/// accumulate before producing output in order to maximize compression.
None = ffi::MZ_NO_FLUSH as isize,
/// All pending output is flushed to the output buffer and the output is
/// aligned on a byte boundary so that the decompressor can get all input
/// data available so far.
///
/// Flushing may degrade compression for some compression algorithms and so
/// it should only be used when necessary. This will complete the current
/// deflate block and follow it with an empty stored block.
Sync = ffi::MZ_SYNC_FLUSH as isize,
/// All pending output is flushed to the output buffer, but the output is
/// not aligned to a byte boundary.
///
/// 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 decompressor to finish the
/// block before the empty fixed code block.
Partial = ffi::MZ_PARTIAL_FLUSH as isize,
/// All output is flushed as with `Flush::Sync` and the compression state is
/// reset so decompression can restart from this point if previous
/// compressed data has been damaged or if random access is desired.
///
/// Using this option too often can seriously degrade compression.
Full = ffi::MZ_FULL_FLUSH as isize,
/// Pending input is processed and pending output is flushed.
///
/// The return value may indicate that the stream is not yet done and more
/// data has yet to be processed.
Finish = ffi::MZ_FINISH as isize,
}
/// Values which indicate the form of flushing to be used when
/// decompressing in-memory data.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
#[non_exhaustive]
pub enum FlushDecompress {
/// A typical parameter for passing to compression/decompression functions,
/// this indicates that the underlying stream to decide how much data to
/// accumulate before producing output in order to maximize compression.
None = ffi::MZ_NO_FLUSH as isize,
/// All pending output is flushed to the output buffer and the output is
/// aligned on a byte boundary so that the decompressor can get all input
/// data available so far.
///
/// Flushing may degrade compression for some compression algorithms and so
/// it should only be used when necessary. This will complete the current
/// deflate block and follow it with an empty stored block.
Sync = ffi::MZ_SYNC_FLUSH as isize,
/// Pending input is processed and pending output is flushed.
///
/// The return value may indicate that the stream is not yet done and more
/// data has yet to be processed.
Finish = ffi::MZ_FINISH as isize,
}
/// The inner state for an error when decompressing
#[derive(Debug)]
pub(crate) enum DecompressErrorInner {
General { msg: ErrorMessage },
NeedsDictionary(u32),
}
/// Error returned when a decompression object finds that the input stream of
/// bytes was not a valid input stream of bytes.
#[derive(Debug)]
pub struct DecompressError(pub(crate) DecompressErrorInner);
impl DecompressError {
/// Indicates whether decompression failed due to requiring a dictionary.
///
/// The resulting integer is the Adler-32 checksum of the dictionary
/// required.
pub fn needs_dictionary(&self) -> Option<u32> {
match self.0 {
DecompressErrorInner::NeedsDictionary(adler) => Some(adler),
_ => None,
}
}
}
#[inline]
pub(crate) fn decompress_failed<T>(msg: ErrorMessage) -> Result<T, DecompressError> {
Err(DecompressError(DecompressErrorInner::General { msg }))
}
#[inline]
pub(crate) fn decompress_need_dict<T>(adler: u32) -> Result<T, DecompressError> {
Err(DecompressError(DecompressErrorInner::NeedsDictionary(
adler,
)))
}
/// Error returned when a compression object is used incorrectly or otherwise
/// generates an error.
#[derive(Debug)]
pub struct CompressError {
pub(crate) msg: ErrorMessage,
}
#[inline]
pub(crate) fn compress_failed<T>(msg: ErrorMessage) -> Result<T, CompressError> {
Err(CompressError { msg })
}
/// Possible status results of compressing some data or successfully
/// decompressing a block of data.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum Status {
/// Indicates success.
///
/// Means that more input may be needed but isn't available
/// and/or there's more output to be written but the output buffer is full.
Ok,
/// Indicates that forward progress is not possible due to input or output
/// buffers being empty.
///
/// For compression it means the input buffer needs some more data or the
/// output buffer needs to be freed up before trying again.
///
/// For decompression this means that more input is needed to continue or
/// the output buffer isn't large enough to contain the result. The function
/// can be called again after fixing both.
BufError,
/// Indicates that all input has been consumed and all output bytes have
/// been written. Decompression/compression should not be called again.
///
/// For decompression with zlib streams the adler-32 of the decompressed
/// data has also been verified.
StreamEnd,
}
impl Compress {
/// Creates a new object ready for compressing data that it's given.
///
/// The `level` argument here indicates what level of compression is going
/// to be performed, and the `zlib_header` argument indicates whether the
/// output data should have a zlib header or not.
pub fn new(level: Compression, zlib_header: bool) -> Compress {
Compress {
inner: Deflate::make(level, zlib_header, ffi::MZ_DEFAULT_WINDOW_BITS as u8),
}
}
/// Creates a new object ready for compressing data that it's given.
///
/// The `level` argument here indicates what level of compression is going
/// to be performed, and the `zlib_header` argument indicates whether the
/// output data should have a zlib header or not. The `window_bits` parameter
/// indicates the base-2 logarithm of the sliding window size and must be
/// between 9 and 15.
///
/// # Panics
///
/// If `window_bits` does not fall into the range 9 ..= 15,
/// `new_with_window_bits` will panic.
#[cfg(feature = "any_zlib")]
pub fn new_with_window_bits(
level: Compression,
zlib_header: bool,
window_bits: u8,
) -> Compress {
assert!(
window_bits > 8 && window_bits < 16,
"window_bits must be within 9 ..= 15"
);
Compress {
inner: Deflate::make(level, zlib_header, window_bits),
}
}
/// Creates a new object ready for compressing data that it's given.
///
/// The `level` argument here indicates what level of compression is going
/// to be performed.
///
/// The Compress object produced by this constructor outputs gzip headers
/// for the compressed data.
///
/// # Panics
///
/// If `window_bits` does not fall into the range 9 ..= 15,
/// `new_with_window_bits` will panic.
#[cfg(feature = "any_zlib")]
pub fn new_gzip(level: Compression, window_bits: u8) -> Compress {
assert!(
window_bits > 8 && window_bits < 16,
"window_bits must be within 9 ..= 15"
);
Compress {
inner: Deflate::make(level, true, window_bits + 16),
}
}
/// Returns the total number of input bytes which have been processed by
/// this compression object.
pub fn total_in(&self) -> u64 {
self.inner.total_in()
}
/// Returns the total number of output bytes which have been produced by
/// this compression object.
pub fn total_out(&self) -> u64 {
self.inner.total_out()
}
/// Specifies the compression dictionary to use.
///
/// Returns the Adler-32 checksum of the dictionary.
#[cfg(feature = "any_zlib")]
pub fn set_dictionary(&mut self, dictionary: &[u8]) -> Result<u32, CompressError> {
let stream = &mut *self.inner.inner.stream_wrapper;
stream.msg = std::ptr::null_mut();
let rc = unsafe {
assert!(dictionary.len() < ffi::uInt::MAX as usize);
ffi::deflateSetDictionary(stream, dictionary.as_ptr(), dictionary.len() as ffi::uInt)
};
match rc {
ffi::MZ_STREAM_ERROR => compress_failed(self.inner.inner.msg()),
ffi::MZ_OK => Ok(stream.adler as u32),
c => panic!("unknown return code: {}", c),
}
}
/// Quickly resets this compressor without having to reallocate anything.
///
/// This is equivalent to dropping this object and then creating a new one.
pub fn reset(&mut self) {
self.inner.reset();
}
/// Dynamically updates the compression level.
///
/// This can be used to switch between compression levels for different
/// kinds of data, or it can be used in conjunction with a call to reset
/// to reuse the compressor.
///
/// This may return an error if there wasn't enough output space to complete
/// the compression of the available input data before changing the
/// compression level. Flushing the stream before calling this method
/// 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 std::os::raw::c_int;
let stream = &mut *self.inner.inner.stream_wrapper;
stream.msg = std::ptr::null_mut();
let rc = unsafe { ffi::deflateParams(stream, level.0 as c_int, ffi::MZ_DEFAULT_STRATEGY) };
match rc {
ffi::MZ_OK => Ok(()),
ffi::MZ_BUF_ERROR => compress_failed(self.inner.inner.msg()),
c => panic!("unknown return code: {}", c),
}
}
/// Compresses the input data into the output, consuming only as much
/// input as needed and writing as much output as possible.
///
/// The flush option can be any of the available `FlushCompress` parameters.
///
/// To learn how much data was consumed or how much output was produced, use
/// the `total_in` and `total_out` functions before/after this is called.
pub fn compress(
&mut self,
input: &[u8],
output: &mut [u8],
flush: FlushCompress,
) -> Result<Status, CompressError> {
self.inner.compress(input, output, flush)
}
/// Compresses the input data into the extra space of the output, consuming
/// only as much input as needed and writing as much output as possible.
///
/// This function has the same semantics as `compress`, except that the
/// length of `vec` is managed by this function. This will not reallocate
/// the vector provided or attempt to grow it, so space for the output must
/// be reserved in the output vector by the caller before calling this
/// function.
pub fn compress_vec(
&mut self,
input: &[u8],
output: &mut Vec<u8>,
flush: FlushCompress,
) -> Result<Status, CompressError> {
write_to_spare_capacity_of_vec(output, |out| {
let before = self.total_out();
let ret = self.compress(input, out, flush);
let bytes_written = self.total_out() - before;
(bytes_written as usize, ret)
})
}
}
impl Decompress {
/// Creates a new object ready for decompressing data that it's given.
///
/// The `zlib_header` argument indicates whether the input data is expected
/// to have a zlib header or not.
pub fn new(zlib_header: bool) -> Decompress {
Decompress {
inner: Inflate::make(zlib_header, ffi::MZ_DEFAULT_WINDOW_BITS as u8),
}
}
/// Creates a new object ready for decompressing data that it's given.
///
/// The `zlib_header` argument indicates whether the input data is expected
/// to have a zlib header or not. The `window_bits` parameter indicates the
/// base-2 logarithm of the sliding window size and must be between 9 and 15.
///
/// # Panics
///
/// If `window_bits` does not fall into the range 9 ..= 15,
/// `new_with_window_bits` will panic.
#[cfg(feature = "any_zlib")]
pub fn new_with_window_bits(zlib_header: bool, window_bits: u8) -> Decompress {
assert!(
window_bits > 8 && window_bits < 16,
"window_bits must be within 9 ..= 15"
);
Decompress {
inner: Inflate::make(zlib_header, window_bits),
}
}
/// Creates a new object ready for decompressing data that it's given.
///
/// The Decompress object produced by this constructor expects gzip headers
/// for the compressed data.
///
/// # Panics
///
/// If `window_bits` does not fall into the range 9 ..= 15,
/// `new_with_window_bits` will panic.
#[cfg(feature = "any_zlib")]
pub fn new_gzip(window_bits: u8) -> Decompress {
assert!(
window_bits > 8 && window_bits < 16,
"window_bits must be within 9 ..= 15"
);
Decompress {
inner: Inflate::make(true, window_bits + 16),
}
}
/// Returns the total number of input bytes which have been processed by
/// this decompression object.
pub fn total_in(&self) -> u64 {
self.inner.total_in()
}
/// Returns the total number of output bytes which have been produced by
/// this decompression object.
pub fn total_out(&self) -> u64 {
self.inner.total_out()
}
/// Decompresses the input data into the output, consuming only as much
/// input as needed and writing as much output as possible.
///
/// The flush option can be any of the available `FlushDecompress` parameters.
///
/// If the first call passes `FlushDecompress::Finish` it is assumed that
/// the input and output buffers are both sized large enough to decompress
/// the entire stream in a single call.
///
/// A flush value of `FlushDecompress::Finish` indicates that there are no
/// more source bytes available beside what's already in the input buffer,
/// and the output buffer is large enough to hold the rest of the
/// decompressed data.
///
/// To learn how much data was consumed or how much output was produced, use
/// the `total_in` and `total_out` functions before/after this is called.
///
/// # Errors
///
/// If the input data to this instance of `Decompress` is not a valid
/// zlib/deflate stream then this function may return an instance of
/// `DecompressError` to indicate that the stream of input bytes is corrupted.
pub fn decompress(
&mut self,
input: &[u8],
output: &mut [u8],
flush: FlushDecompress,
) -> Result<Status, DecompressError> {
self.inner.decompress(input, output, flush)
}
/// Decompresses the input data into the extra space in the output vector
/// specified by `output`.
///
/// This function has the same semantics as `decompress`, except that the
/// length of `vec` is managed by this function. This will not reallocate
/// the vector provided or attempt to grow it, so space for the output must
/// be reserved in the output vector by the caller before calling this
/// function.
///
/// # Errors
///
/// If the input data to this instance of `Decompress` is not a valid
/// zlib/deflate stream then this function may return an instance of
/// `DecompressError` to indicate that the stream of input bytes is corrupted.
pub fn decompress_vec(
&mut self,
input: &[u8],
output: &mut Vec<u8>,
flush: FlushDecompress,
) -> Result<Status, DecompressError> {
write_to_spare_capacity_of_vec(output, |out| {
let before = self.total_out();
let ret = self.decompress(input, out, flush);
let bytes_written = self.total_out() - before;
(bytes_written as usize, ret)
})
}
/// Specifies the decompression dictionary to use.
#[cfg(feature = "any_zlib")]
pub fn set_dictionary(&mut self, dictionary: &[u8]) -> Result<u32, DecompressError> {
let stream = &mut *self.inner.inner.stream_wrapper;
stream.msg = std::ptr::null_mut();
let rc = unsafe {
assert!(dictionary.len() < ffi::uInt::MAX as usize);
ffi::inflateSetDictionary(stream, dictionary.as_ptr(), dictionary.len() as ffi::uInt)
};
match rc {
ffi::MZ_STREAM_ERROR => decompress_failed(self.inner.inner.msg()),
ffi::MZ_DATA_ERROR => decompress_need_dict(stream.adler as u32),
ffi::MZ_OK => Ok(stream.adler as u32),
c => panic!("unknown return code: {}", c),
}
}
/// Performs the equivalent of replacing this decompression state with a
/// freshly allocated copy.
///
/// This function may not allocate memory, though, and attempts to reuse any
/// previously existing resources.
///
/// The argument provided here indicates whether the reset state will
/// attempt to decode a zlib header first or not.
pub fn reset(&mut self, zlib_header: bool) {
self.inner.reset(zlib_header);
}
}
impl Error for DecompressError {}
impl DecompressError {
/// Retrieve the implementation's message about why the operation failed, if one exists.
pub fn message(&self) -> Option<&str> {
match &self.0 {
DecompressErrorInner::General { msg } => msg.get(),
_ => None,
}
}
}
impl From<DecompressError> for io::Error {
fn from(data: DecompressError) -> io::Error {
io::Error::new(io::ErrorKind::Other, data)
}
}
impl fmt::Display for DecompressError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let msg = match &self.0 {
DecompressErrorInner::General { msg } => msg.get(),
DecompressErrorInner::NeedsDictionary { .. } => Some("requires a dictionary"),
};
match msg {
Some(msg) => write!(f, "deflate decompression error: {}", msg),
None => write!(f, "deflate decompression error"),
}
}
}
impl Error for CompressError {}
impl CompressError {
/// Retrieve the implementation's message about why the operation failed, if one exists.
pub fn message(&self) -> Option<&str> {
self.msg.get()
}
}
impl From<CompressError> for io::Error {
fn from(data: CompressError) -> io::Error {
io::Error::new(io::ErrorKind::Other, data)
}
}
impl fmt::Display for CompressError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.msg.get() {
Some(msg) => write!(f, "deflate compression error: {}", msg),
None => write!(f, "deflate compression error"),
}
}
}
/// Allows `writer` to write data into the spare capacity of the `output` vector.
/// This will not reallocate the vector provided or attempt to grow it, so space
/// for the `output` must be reserved by the caller before calling this
/// function.
///
/// `writer` needs to return the number of bytes written (and can also return
/// another arbitrary return value).
fn write_to_spare_capacity_of_vec<T>(
output: &mut Vec<u8>,
writer: impl FnOnce(&mut [u8]) -> (usize, T),
) -> T {
let cap = output.capacity();
let len = output.len();
output.resize(output.capacity(), 0);
let (bytes_written, ret) = writer(&mut output[len..]);
let new_len = core::cmp::min(len + bytes_written, cap); // Sanitizes `bytes_written`.
output.resize(new_len, 0 /* unused */);
ret
}
#[cfg(test)]
mod tests {
use std::io::Write;
use crate::write;
use crate::{Compression, Decompress, FlushDecompress};
#[cfg(feature = "any_zlib")]
use crate::{Compress, FlushCompress};
#[test]
fn issue51() {
let data = vec![
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xb3, 0xc9, 0x28, 0xc9,
0xcd, 0xb1, 0xe3, 0xe5, 0xb2, 0xc9, 0x48, 0x4d, 0x4c, 0xb1, 0xb3, 0x29, 0xc9, 0x2c,
0xc9, 0x49, 0xb5, 0x33, 0x31, 0x30, 0x51, 0xf0, 0xcb, 0x2f, 0x51, 0x70, 0xcb, 0x2f,
0xcd, 0x4b, 0xb1, 0xd1, 0x87, 0x08, 0xda, 0xe8, 0x83, 0x95, 0x00, 0x95, 0x26, 0xe5,
0xa7, 0x54, 0x2a, 0x24, 0xa5, 0x27, 0xe7, 0xe7, 0xe4, 0x17, 0xd9, 0x2a, 0x95, 0x67,
0x64, 0x96, 0xa4, 0x2a, 0x81, 0x8c, 0x48, 0x4e, 0xcd, 0x2b, 0x49, 0x2d, 0xb2, 0xb3,
0xc9, 0x30, 0x44, 0x37, 0x01, 0x28, 0x62, 0xa3, 0x0f, 0x95, 0x06, 0xd9, 0x05, 0x54,
0x04, 0xe5, 0xe5, 0xa5, 0x67, 0xe6, 0x55, 0xe8, 0x1b, 0xea, 0x99, 0xe9, 0x19, 0x21,
0xab, 0xd0, 0x07, 0xd9, 0x01, 0x32, 0x53, 0x1f, 0xea, 0x3e, 0x00, 0x94, 0x85, 0xeb,
0xe4, 0xa8, 0x00, 0x00, 0x00,
];
let mut decoded = Vec::with_capacity(data.len() * 2);
let mut d = Decompress::new(false);
// decompressed whole deflate stream
assert!(d
.decompress_vec(&data[10..], &mut decoded, FlushDecompress::Finish)
.is_ok());
// decompress data that has nothing to do with the deflate stream (this
// used to panic)
drop(d.decompress_vec(&[0], &mut decoded, FlushDecompress::None));
}
#[test]
fn reset() {
let string = "hello world".as_bytes();
let mut zlib = Vec::new();
let mut deflate = Vec::new();
let comp = Compression::default();
write::ZlibEncoder::new(&mut zlib, comp)
.write_all(string)
.unwrap();
write::DeflateEncoder::new(&mut deflate, comp)
.write_all(string)
.unwrap();
let mut dst = [0; 1024];
let mut decoder = Decompress::new(true);
decoder
.decompress(&zlib, &mut dst, FlushDecompress::Finish)
.unwrap();
assert_eq!(decoder.total_out(), string.len() as u64);
assert!(dst.starts_with(string));
decoder.reset(false);
decoder
.decompress(&deflate, &mut dst, FlushDecompress::Finish)
.unwrap();
assert_eq!(decoder.total_out(), string.len() as u64);
assert!(dst.starts_with(string));
}
#[cfg(feature = "any_zlib")]
#[test]
fn set_dictionary_with_zlib_header() {
let string = "hello, hello!".as_bytes();
let dictionary = "hello".as_bytes();
let mut encoded = Vec::with_capacity(1024);
let mut encoder = Compress::new(Compression::default(), true);
let dictionary_adler = encoder.set_dictionary(&dictionary).unwrap();
encoder
.compress_vec(string, &mut encoded, FlushCompress::Finish)
.unwrap();
assert_eq!(encoder.total_in(), string.len() as u64);
assert_eq!(encoder.total_out(), encoded.len() as u64);
let mut decoder = Decompress::new(true);
let mut decoded = [0; 1024];
let decompress_error = decoder
.decompress(&encoded, &mut decoded, FlushDecompress::Finish)
.expect_err("decompression should fail due to requiring a dictionary");
let required_adler = decompress_error.needs_dictionary()
.expect("the first call to decompress should indicate a dictionary is required along with the required Adler-32 checksum");
assert_eq!(required_adler, dictionary_adler,
"the Adler-32 checksum should match the value when the dictionary was set on the compressor");
let actual_adler = decoder.set_dictionary(&dictionary).unwrap();
assert_eq!(required_adler, actual_adler);
// Decompress the rest of the input to the remainder of the output buffer
let total_in = decoder.total_in();
let total_out = decoder.total_out();
let decompress_result = decoder.decompress(
&encoded[total_in as usize..],
&mut decoded[total_out as usize..],
FlushDecompress::Finish,
);
assert!(decompress_result.is_ok());
assert_eq!(&decoded[..decoder.total_out() as usize], string);
}
#[cfg(feature = "any_zlib")]
#[test]
fn set_dictionary_raw() {
let string = "hello, hello!".as_bytes();
let dictionary = "hello".as_bytes();
let mut encoded = Vec::with_capacity(1024);
let mut encoder = Compress::new(Compression::default(), false);
encoder.set_dictionary(&dictionary).unwrap();
encoder
.compress_vec(string, &mut encoded, FlushCompress::Finish)
.unwrap();
assert_eq!(encoder.total_in(), string.len() as u64);
assert_eq!(encoder.total_out(), encoded.len() as u64);
let mut decoder = Decompress::new(false);
decoder.set_dictionary(&dictionary).unwrap();
let mut decoded = [0; 1024];
let decompress_result = decoder.decompress(&encoded, &mut decoded, FlushDecompress::Finish);
assert!(decompress_result.is_ok());
assert_eq!(&decoded[..decoder.total_out() as usize], string);
}
#[cfg(feature = "any_zlib")]
#[test]
fn test_gzip_flate() {
let string = "hello, hello!".as_bytes();
let mut encoded = Vec::with_capacity(1024);
let mut encoder = Compress::new_gzip(Compression::default(), 9);
encoder
.compress_vec(string, &mut encoded, FlushCompress::Finish)
.unwrap();
assert_eq!(encoder.total_in(), string.len() as u64);
assert_eq!(encoder.total_out(), encoded.len() as u64);
let mut decoder = Decompress::new_gzip(9);
let mut decoded = [0; 1024];
decoder
.decompress(&encoded, &mut decoded, FlushDecompress::Finish)
.unwrap();
assert_eq!(&decoded[..decoder.total_out() as usize], string);
}
#[cfg(feature = "any_zlib")]
#[test]
fn test_error_message() {
let mut decoder = Decompress::new(false);
let mut decoded = [0; 128];
let garbage = b"xbvxzi";
let err = decoder
.decompress(&*garbage, &mut decoded, FlushDecompress::Finish)
.unwrap_err();
assert_eq!(err.message(), Some("invalid stored block lengths"));
}
}

286
vendor/flate2/src/zio.rs vendored Normal file
View File

@ -0,0 +1,286 @@
use std::io;
use std::io::prelude::*;
use std::mem;
use crate::{Compress, Decompress, DecompressError, FlushCompress, FlushDecompress, Status};
#[derive(Debug)]
pub struct Writer<W: Write, D: Ops> {
obj: Option<W>,
pub data: D,
buf: Vec<u8>,
}
pub trait Ops {
type Flush: Flush;
fn total_in(&self) -> u64;
fn total_out(&self) -> u64;
fn run(
&mut self,
input: &[u8],
output: &mut [u8],
flush: Self::Flush,
) -> Result<Status, DecompressError>;
fn run_vec(
&mut self,
input: &[u8],
output: &mut Vec<u8>,
flush: Self::Flush,
) -> Result<Status, DecompressError>;
}
impl Ops for Compress {
type Flush = FlushCompress;
fn total_in(&self) -> u64 {
self.total_in()
}
fn total_out(&self) -> u64 {
self.total_out()
}
fn run(
&mut self,
input: &[u8],
output: &mut [u8],
flush: FlushCompress,
) -> Result<Status, DecompressError> {
Ok(self.compress(input, output, flush).unwrap())
}
fn run_vec(
&mut self,
input: &[u8],
output: &mut Vec<u8>,
flush: FlushCompress,
) -> Result<Status, DecompressError> {
Ok(self.compress_vec(input, output, flush).unwrap())
}
}
impl Ops for Decompress {
type Flush = FlushDecompress;
fn total_in(&self) -> u64 {
self.total_in()
}
fn total_out(&self) -> u64 {
self.total_out()
}
fn run(
&mut self,
input: &[u8],
output: &mut [u8],
flush: FlushDecompress,
) -> Result<Status, DecompressError> {
self.decompress(input, output, flush)
}
fn run_vec(
&mut self,
input: &[u8],
output: &mut Vec<u8>,
flush: FlushDecompress,
) -> Result<Status, DecompressError> {
self.decompress_vec(input, output, flush)
}
}
pub trait Flush {
fn none() -> Self;
fn sync() -> Self;
fn finish() -> Self;
}
impl Flush for FlushCompress {
fn none() -> Self {
FlushCompress::None
}
fn sync() -> Self {
FlushCompress::Sync
}
fn finish() -> Self {
FlushCompress::Finish
}
}
impl Flush for FlushDecompress {
fn none() -> Self {
FlushDecompress::None
}
fn sync() -> Self {
FlushDecompress::Sync
}
fn finish() -> Self {
FlushDecompress::Finish
}
}
pub fn read<R, D>(obj: &mut R, data: &mut D, dst: &mut [u8]) -> io::Result<usize>
where
R: BufRead,
D: Ops,
{
loop {
let (read, consumed, ret, eof);
{
let input = obj.fill_buf()?;
eof = input.is_empty();
let before_out = data.total_out();
let before_in = data.total_in();
let flush = if eof {
D::Flush::finish()
} else {
D::Flush::none()
};
ret = data.run(input, dst, flush);
read = (data.total_out() - before_out) as usize;
consumed = (data.total_in() - before_in) as usize;
}
obj.consume(consumed);
match ret {
// If we haven't ready any data and we haven't hit EOF yet,
// 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 | Status::BufError) if read == 0 && !eof && !dst.is_empty() => continue,
Ok(Status::Ok | Status::BufError | Status::StreamEnd) => return Ok(read),
Err(..) => {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
"corrupt deflate stream",
))
}
}
}
}
impl<W: Write, D: Ops> Writer<W, D> {
pub fn new(w: W, d: D) -> Writer<W, D> {
Writer {
obj: Some(w),
data: d,
buf: Vec::with_capacity(32 * 1024),
}
}
pub fn finish(&mut self) -> io::Result<()> {
loop {
self.dump()?;
let before = self.data.total_out();
self.data.run_vec(&[], &mut self.buf, D::Flush::finish())?;
if before == self.data.total_out() {
return Ok(());
}
}
}
pub fn replace(&mut self, w: W) -> W {
self.buf.truncate(0);
mem::replace(self.get_mut(), w)
}
pub fn get_ref(&self) -> &W {
self.obj.as_ref().unwrap()
}
pub fn get_mut(&mut self) -> &mut W {
self.obj.as_mut().unwrap()
}
// Note that this should only be called if the outer object is just about
// to be consumed!
//
// (e.g. an implementation of `into_inner`)
pub fn take_inner(&mut self) -> W {
self.obj.take().unwrap()
}
pub fn is_present(&self) -> bool {
self.obj.is_some()
}
// Returns total written bytes and status of underlying codec
pub(crate) fn write_with_status(&mut self, buf: &[u8]) -> io::Result<(usize, Status)> {
// miniz isn't guaranteed to actually write any of the buffer provided,
// it may be in a flushing mode where it's just giving us data before
// we're actually giving it any data. We don't want to spuriously return
// `Ok(0)` when possible as it will cause calls to write_all() to fail.
// As a result we execute this in a loop to ensure that we try our
// darndest to write the data.
loop {
self.dump()?;
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));
if !buf.is_empty() && written == 0 && ret.is_ok() && !is_stream_end {
continue;
}
return match ret {
Ok(st) => match st {
Status::Ok | Status::BufError | Status::StreamEnd => Ok((written, st)),
},
Err(..) => Err(io::Error::new(
io::ErrorKind::InvalidInput,
"corrupt deflate stream",
)),
};
}
}
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.is_empty() {
let n = self.obj.as_mut().unwrap().write(&self.buf)?;
if n == 0 {
return Err(io::ErrorKind::WriteZero.into());
}
self.buf.drain(..n);
}
Ok(())
}
}
impl<W: Write, D: Ops> Write for Writer<W, D> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.write_with_status(buf).map(|res| res.0)
}
fn flush(&mut self) -> io::Result<()> {
self.data
.run_vec(&[], &mut self.buf, D::Flush::sync())
.unwrap();
// Unfortunately miniz doesn't actually tell us when we're done with
// pulling out all the data from the internal stream. To remedy this we
// have to continually ask the stream for more memory until it doesn't
// give us a chunk of memory the same size as our own internal buffer,
// at which point we assume it's reached the end.
loop {
self.dump()?;
let before = self.data.total_out();
self.data
.run_vec(&[], &mut self.buf, D::Flush::none())
.unwrap();
if before == self.data.total_out() {
break;
}
}
self.obj.as_mut().unwrap().flush()
}
}
impl<W: Write, D: Ops> Drop for Writer<W, D> {
fn drop(&mut self) {
if self.obj.is_some() {
let _ = self.finish();
}
}
}

253
vendor/flate2/src/zlib/bufread.rs vendored Normal file
View File

@ -0,0 +1,253 @@
use std::io;
use std::io::prelude::*;
use std::mem;
use crate::zio;
use crate::{Compress, Decompress};
/// A ZLIB encoder, or compressor.
///
/// This structure implements a [`Read`] interface. When read from, it reads
/// uncompressed data from the underlying [`BufRead`] and provides the compressed data.
///
/// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
/// [`BufRead`]: https://doc.rust-lang.org/std/io/trait.BufRead.html
///
/// # Examples
///
/// ```
/// use std::io::prelude::*;
/// use flate2::Compression;
/// use flate2::bufread::ZlibEncoder;
/// use std::fs::File;
/// use std::io::BufReader;
///
/// // Use a buffered file to compress contents into a Vec<u8>
///
/// # fn open_hello_world() -> std::io::Result<Vec<u8>> {
/// let f = File::open("examples/hello_world.txt")?;
/// let b = BufReader::new(f);
/// let mut z = ZlibEncoder::new(b, Compression::fast());
/// let mut buffer = Vec::new();
/// z.read_to_end(&mut buffer)?;
/// # Ok(buffer)
/// # }
/// ```
#[derive(Debug)]
pub struct ZlibEncoder<R> {
obj: R,
data: Compress,
}
impl<R: BufRead> ZlibEncoder<R> {
/// Creates a new encoder which will read uncompressed data from the given
/// stream and emit the compressed stream.
pub fn new(r: R, level: crate::Compression) -> ZlibEncoder<R> {
ZlibEncoder {
obj: r,
data: Compress::new(level, true),
}
}
/// Creates a new encoder with the given `compression` settings which will
/// read uncompressed data from the given stream `r` and emit the compressed stream.
pub fn new_with_compress(r: R, compression: Compress) -> ZlibEncoder<R> {
ZlibEncoder {
obj: r,
data: compression,
}
}
}
pub fn reset_encoder_data<R>(zlib: &mut ZlibEncoder<R>) {
zlib.data.reset()
}
impl<R> ZlibEncoder<R> {
/// Resets the state of this encoder entirely, swapping out the input
/// stream for another.
///
/// This function will reset the internal state of this encoder and replace
/// the input stream with the one provided, returning the previous input
/// stream. Future data read from this encoder will be the compressed
/// version of `r`'s data.
pub fn reset(&mut self, r: R) -> R {
reset_encoder_data(self);
mem::replace(&mut self.obj, r)
}
/// Acquires a reference to the underlying reader
pub fn get_ref(&self) -> &R {
&self.obj
}
/// Acquires a mutable reference to the underlying stream
///
/// Note that mutation of the stream may result in surprising results if
/// this encoder is continued to be used.
pub fn get_mut(&mut self) -> &mut R {
&mut self.obj
}
/// Consumes this encoder, returning the underlying reader.
pub fn into_inner(self) -> R {
self.obj
}
/// Returns the number of bytes that have been read into this compressor.
///
/// Note that not all bytes read from the underlying object may be accounted
/// for, there may still be some active buffering.
pub fn total_in(&self) -> u64 {
self.data.total_in()
}
/// Returns the number of bytes that the compressor has produced.
///
/// Note that not all bytes may have been read yet, some may still be
/// buffered.
pub fn total_out(&self) -> u64 {
self.data.total_out()
}
}
impl<R: BufRead> Read for ZlibEncoder<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
zio::read(&mut self.obj, &mut self.data, buf)
}
}
impl<R: BufRead + Write> Write for ZlibEncoder<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()
}
}
/// A ZLIB decoder, or decompressor.
///
/// This structure implements a [`Read`] interface. When read from, it reads
/// compressed data from the underlying [`BufRead`] and provides the uncompressed data.
///
/// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
/// [`BufRead`]: https://doc.rust-lang.org/std/io/trait.BufRead.html
///
/// # Examples
///
/// ```
/// use std::io::prelude::*;
/// use std::io;
/// # use flate2::Compression;
/// # use flate2::write::ZlibEncoder;
/// use flate2::bufread::ZlibDecoder;
///
/// # fn main() {
/// # let mut e = ZlibEncoder::new(Vec::new(), Compression::default());
/// # e.write_all(b"Hello World").unwrap();
/// # let bytes = e.finish().unwrap();
/// # println!("{}", decode_bufreader(bytes).unwrap());
/// # }
/// #
/// // Uncompresses a Zlib Encoded vector of bytes and returns a string or error
/// // Here &[u8] implements BufRead
///
/// fn decode_bufreader(bytes: Vec<u8>) -> io::Result<String> {
/// let mut z = ZlibDecoder::new(&bytes[..]);
/// let mut s = String::new();
/// z.read_to_string(&mut s)?;
/// Ok(s)
/// }
/// ```
#[derive(Debug)]
pub struct ZlibDecoder<R> {
obj: R,
data: Decompress,
}
impl<R: BufRead> ZlibDecoder<R> {
/// Creates a new decoder which will decompress data read from the given
/// stream.
pub fn new(r: R) -> ZlibDecoder<R> {
ZlibDecoder {
obj: r,
data: Decompress::new(true),
}
}
/// Creates a new decoder which will decompress data read from the given
/// stream, using the given `decompression` settings.
pub fn new_with_decompress(r: R, decompression: Decompress) -> ZlibDecoder<R> {
ZlibDecoder {
obj: r,
data: decompression,
}
}
}
pub fn reset_decoder_data<R>(zlib: &mut ZlibDecoder<R>) {
zlib.data = Decompress::new(true);
}
impl<R> ZlibDecoder<R> {
/// Resets the state of this decoder entirely, swapping out the input
/// stream for another.
///
/// This will reset the internal state of this decoder and replace the
/// input stream with the one provided, returning the previous input
/// stream. Future data read from this decoder will be the decompressed
/// version of `r`'s data.
pub fn reset(&mut self, r: R) -> R {
reset_decoder_data(self);
mem::replace(&mut self.obj, r)
}
/// Acquires a reference to the underlying stream
pub fn get_ref(&self) -> &R {
&self.obj
}
/// Acquires a mutable reference to the underlying stream
///
/// Note that mutation of the stream may result in surprising results if
/// this decoder is continued to be used.
pub fn get_mut(&mut self) -> &mut R {
&mut self.obj
}
/// Consumes this decoder, returning the underlying reader.
pub fn into_inner(self) -> R {
self.obj
}
/// Returns the number of bytes that the decompressor has consumed.
///
/// Note that this will likely be smaller than what the decompressor
/// actually read from the underlying stream due to buffering.
pub fn total_in(&self) -> u64 {
self.data.total_in()
}
/// Returns the number of bytes that the decompressor has produced.
pub fn total_out(&self) -> u64 {
self.data.total_out()
}
}
impl<R: BufRead> Read for ZlibDecoder<R> {
fn read(&mut self, into: &mut [u8]) -> io::Result<usize> {
zio::read(&mut self.obj, &mut self.data, into)
}
}
impl<R: BufRead + Write> Write for ZlibDecoder<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()
}
}

159
vendor/flate2/src/zlib/mod.rs vendored Normal file
View File

@ -0,0 +1,159 @@
pub mod bufread;
pub mod read;
pub mod write;
#[cfg(test)]
mod tests {
use std::io;
use std::io::prelude::*;
use rand::{thread_rng, Rng};
use crate::zlib::{read, write};
use crate::Compression;
#[test]
fn roundtrip() {
let mut real = Vec::new();
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())];
real.extend(to_write.iter().copied());
w.write_all(to_write).unwrap();
}
let result = w.finish().unwrap();
let mut r = read::ZlibDecoder::new(&result[..]);
let mut ret = Vec::new();
r.read_to_end(&mut ret).unwrap();
assert_eq!(ret, real);
}
#[test]
fn drop_writes() {
let mut data = Vec::new();
write::ZlibEncoder::new(&mut data, Compression::default())
.write_all(b"foo")
.unwrap();
let mut r = read::ZlibDecoder::new(&data[..]);
let mut ret = Vec::new();
r.read_to_end(&mut ret).unwrap();
assert_eq!(ret, b"foo");
}
#[test]
fn total_in() {
let mut real = Vec::new();
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())];
real.extend(to_write.iter().copied());
w.write_all(to_write).unwrap();
}
let mut result = w.finish().unwrap();
let result_len = result.len();
for _ in 0..200 {
result.extend(v.iter().copied());
}
let mut r = read::ZlibDecoder::new(&result[..]);
let mut ret = Vec::new();
r.read_to_end(&mut ret).unwrap();
assert_eq!(ret, real);
assert_eq!(r.total_in(), result_len as u64);
}
#[test]
fn roundtrip2() {
let v = crate::random_bytes().take(1024 * 1024).collect::<Vec<_>>();
let mut r = read::ZlibDecoder::new(read::ZlibEncoder::new(&v[..], Compression::default()));
let mut ret = Vec::new();
r.read_to_end(&mut ret).unwrap();
assert_eq!(ret, v);
}
#[test]
fn roundtrip3() {
let v = crate::random_bytes().take(1024 * 1024).collect::<Vec<_>>();
let mut w =
write::ZlibEncoder::new(write::ZlibDecoder::new(Vec::new()), Compression::default());
w.write_all(&v).unwrap();
let w = w.finish().unwrap().finish().unwrap();
assert_eq!(w, v);
}
#[test]
fn reset_decoder() {
let v = crate::random_bytes().take(1024 * 1024).collect::<Vec<_>>();
let mut w = write::ZlibEncoder::new(Vec::new(), Compression::default());
w.write_all(&v).unwrap();
let data = w.finish().unwrap();
{
let (mut a, mut b, mut c) = (Vec::new(), Vec::new(), Vec::new());
let mut r = read::ZlibDecoder::new(&data[..]);
r.read_to_end(&mut a).unwrap();
r.reset(&data);
r.read_to_end(&mut b).unwrap();
let mut r = read::ZlibDecoder::new(&data[..]);
r.read_to_end(&mut c).unwrap();
assert!(a == b && b == c && c == v);
}
{
let mut w = write::ZlibDecoder::new(Vec::new());
w.write_all(&data).unwrap();
let a = w.reset(Vec::new()).unwrap();
w.write_all(&data).unwrap();
let b = w.finish().unwrap();
let mut w = write::ZlibDecoder::new(Vec::new());
w.write_all(&data).unwrap();
let c = w.finish().unwrap();
assert!(a == b && b == c && c == v);
}
}
#[test]
fn bad_input() {
// regress tests: previously caused a panic on drop
let mut out: Vec<u8> = Vec::new();
let data: Vec<u8> = (0..255).cycle().take(1024).collect();
let mut w = write::ZlibDecoder::new(&mut out);
match w.write_all(&data[..]) {
Ok(_) => panic!("Expected an error to be returned!"),
Err(e) => assert_eq!(e.kind(), io::ErrorKind::InvalidInput),
}
}
#[test]
fn qc_reader() {
::quickcheck::quickcheck(test as fn(_) -> _);
fn test(v: Vec<u8>) -> bool {
let mut r =
read::ZlibDecoder::new(read::ZlibEncoder::new(&v[..], Compression::default()));
let mut v2 = Vec::new();
r.read_to_end(&mut v2).unwrap();
v == v2
}
}
#[test]
fn qc_writer() {
::quickcheck::quickcheck(test as fn(_) -> _);
fn test(v: Vec<u8>) -> bool {
let mut w = write::ZlibEncoder::new(
write::ZlibDecoder::new(Vec::new()),
Compression::default(),
);
w.write_all(&v).unwrap();
v == w.finish().unwrap().finish().unwrap()
}
}
}

275
vendor/flate2/src/zlib/read.rs vendored Normal file
View File

@ -0,0 +1,275 @@
use std::io;
use std::io::prelude::*;
use super::bufread;
use crate::bufreader::BufReader;
use crate::Decompress;
/// A ZLIB encoder, or compressor.
///
/// This structure implements a [`Read`] interface. When read from, it reads
/// uncompressed data from the underlying [`Read`] and provides the compressed data.
///
/// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
///
/// # Examples
///
/// ```
/// use std::io::prelude::*;
/// use flate2::Compression;
/// use flate2::read::ZlibEncoder;
/// use std::fs::File;
///
/// // Open example file and compress the contents using Read interface
///
/// # fn open_hello_world() -> std::io::Result<Vec<u8>> {
/// let f = File::open("examples/hello_world.txt")?;
/// let mut z = ZlibEncoder::new(f, Compression::fast());
/// let mut buffer = Vec::new();
/// z.read_to_end(&mut buffer)?;
/// # Ok(buffer)
/// # }
/// ```
#[derive(Debug)]
pub struct ZlibEncoder<R> {
inner: bufread::ZlibEncoder<BufReader<R>>,
}
impl<R: Read> ZlibEncoder<R> {
/// Creates a new encoder which will read uncompressed data from the given
/// stream and emit the compressed stream.
pub fn new(r: R, level: crate::Compression) -> ZlibEncoder<R> {
ZlibEncoder {
inner: bufread::ZlibEncoder::new(BufReader::new(r), level),
}
}
/// Creates a new encoder with the given `compression` settings which will
/// read uncompressed data from the given stream `r` and emit the compressed stream.
pub fn new_with_compress(r: R, compression: crate::Compress) -> ZlibEncoder<R> {
ZlibEncoder {
inner: bufread::ZlibEncoder::new_with_compress(BufReader::new(r), compression),
}
}
}
impl<R> ZlibEncoder<R> {
/// Resets the state of this encoder entirely, swapping out the input
/// stream for another.
///
/// This function will reset the internal state of this encoder and replace
/// the input stream with the one provided, returning the previous input
/// stream. Future data read from this encoder will be the compressed
/// version of `r`'s data.
///
/// Note that there may be currently buffered data when this function is
/// called, and in that case the buffered data is discarded.
pub fn reset(&mut self, r: R) -> R {
super::bufread::reset_encoder_data(&mut self.inner);
self.inner.get_mut().reset(r)
}
/// Acquires a reference to the underlying stream
pub fn get_ref(&self) -> &R {
self.inner.get_ref().get_ref()
}
/// Acquires a mutable reference to the underlying stream
///
/// Note that mutation of the stream may result in surprising results if
/// this encoder is continued to be used.
pub fn get_mut(&mut self) -> &mut R {
self.inner.get_mut().get_mut()
}
/// Consumes this encoder, returning the underlying reader.
///
/// Note that there may be buffered bytes which are not re-acquired as part
/// of this transition. It's recommended to only call this function after
/// EOF has been reached.
pub fn into_inner(self) -> R {
self.inner.into_inner().into_inner()
}
/// Returns the number of bytes that have been read into this compressor.
///
/// Note that not all bytes read from the underlying object may be accounted
/// for, there may still be some active buffering.
pub fn total_in(&self) -> u64 {
self.inner.total_in()
}
/// Returns the number of bytes that the compressor has produced.
///
/// Note that not all bytes may have been read yet, some may still be
/// buffered.
pub fn total_out(&self) -> u64 {
self.inner.total_out()
}
}
impl<R: Read> Read for ZlibEncoder<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf)
}
}
impl<W: Read + Write> Write for ZlibEncoder<W> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.get_mut().write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.get_mut().flush()
}
}
/// A ZLIB decoder, or decompressor.
///
/// This structure implements a [`Read`] interface. When read from, it reads
/// compressed data from the underlying [`Read`] and provides the uncompressed data.
///
/// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
///
/// # Examples
///
/// ```
/// use std::io::prelude::*;
/// use std::io;
/// # use flate2::Compression;
/// # use flate2::write::ZlibEncoder;
/// use flate2::read::ZlibDecoder;
///
/// # fn main() {
/// # let mut e = ZlibEncoder::new(Vec::new(), Compression::default());
/// # e.write_all(b"Hello World").unwrap();
/// # let bytes = e.finish().unwrap();
/// # println!("{}", decode_reader(bytes).unwrap());
/// # }
/// #
/// // Uncompresses a Zlib 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 z = ZlibDecoder::new(&bytes[..]);
/// let mut s = String::new();
/// z.read_to_string(&mut s)?;
/// Ok(s)
/// }
/// ```
#[derive(Debug)]
pub struct ZlibDecoder<R> {
inner: bufread::ZlibDecoder<BufReader<R>>,
}
impl<R: Read> ZlibDecoder<R> {
/// Creates a new decoder which will decompress data read from the given
/// stream.
pub fn new(r: R) -> ZlibDecoder<R> {
ZlibDecoder::new_with_buf(r, vec![0; 32 * 1024])
}
/// Creates a new decoder which will decompress data read from the given
/// stream `r`, using `buf` as backing to speed up reading.
///
/// Note that the specified buffer will only be used up to its current
/// length. The buffer's capacity will also not grow over time.
pub fn new_with_buf(r: R, buf: Vec<u8>) -> ZlibDecoder<R> {
ZlibDecoder {
inner: bufread::ZlibDecoder::new(BufReader::with_buf(buf, r)),
}
}
/// Creates a new decoder which will decompress data read from the given
/// stream `r`, along with `decompression` settings.
pub fn new_with_decompress(r: R, decompression: Decompress) -> ZlibDecoder<R> {
ZlibDecoder::new_with_decompress_and_buf(r, vec![0; 32 * 1024], decompression)
}
/// Creates a new decoder which will decompress data read from the given
/// stream `r`, using `buf` as backing to speed up reading,
/// along with `decompression` settings to configure decoder.
///
/// Note that the specified buffer will only be used up to its current
/// length. The buffer's capacity will also not grow over time.
pub fn new_with_decompress_and_buf(
r: R,
buf: Vec<u8>,
decompression: Decompress,
) -> ZlibDecoder<R> {
ZlibDecoder {
inner: bufread::ZlibDecoder::new_with_decompress(
BufReader::with_buf(buf, r),
decompression,
),
}
}
}
impl<R> ZlibDecoder<R> {
/// Resets the state of this decoder entirely, swapping out the input
/// stream for another.
///
/// This will reset the internal state of this decoder and replace the
/// input stream with the one provided, returning the previous input
/// stream. Future data read from this decoder will be the decompressed
/// version of `r`'s data.
///
/// Note that there may be currently buffered data when this function is
/// called, and in that case the buffered data is discarded.
pub fn reset(&mut self, r: R) -> R {
super::bufread::reset_decoder_data(&mut self.inner);
self.inner.get_mut().reset(r)
}
/// Acquires a reference to the underlying stream
pub fn get_ref(&self) -> &R {
self.inner.get_ref().get_ref()
}
/// Acquires a mutable reference to the underlying stream
///
/// Note that mutation of the stream may result in surprising results if
/// this decoder is continued to be used.
pub fn get_mut(&mut self) -> &mut R {
self.inner.get_mut().get_mut()
}
/// Consumes this decoder, returning the underlying reader.
///
/// Note that there may be buffered bytes which are not re-acquired as part
/// of this transition. It's recommended to only call this function after
/// EOF has been reached.
pub fn into_inner(self) -> R {
self.inner.into_inner().into_inner()
}
/// Returns the number of bytes that the decompressor has consumed.
///
/// Note that this will likely be smaller than what the decompressor
/// actually read from the underlying stream due to buffering.
pub fn total_in(&self) -> u64 {
self.inner.total_in()
}
/// Returns the number of bytes that the decompressor has produced.
pub fn total_out(&self) -> u64 {
self.inner.total_out()
}
}
impl<R: Read> Read for ZlibDecoder<R> {
fn read(&mut self, into: &mut [u8]) -> io::Result<usize> {
self.inner.read(into)
}
}
impl<R: Read + Write> Write for ZlibDecoder<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()
}
}

340
vendor/flate2/src/zlib/write.rs vendored Normal file
View File

@ -0,0 +1,340 @@
use std::io;
use std::io::prelude::*;
use crate::zio;
use crate::{Compress, Decompress};
/// A ZLIB encoder, or compressor.
///
/// This structure implements a [`Write`] interface and takes a stream of
/// uncompressed data, writing the compressed data to the wrapped writer.
///
/// [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
///
/// # Examples
///
/// ```
/// use std::io::prelude::*;
/// use flate2::Compression;
/// use flate2::write::ZlibEncoder;
///
/// // Vec<u8> implements Write, assigning the compressed bytes of sample string
///
/// # fn zlib_encoding() -> std::io::Result<()> {
/// let mut e = ZlibEncoder::new(Vec::new(), Compression::default());
/// e.write_all(b"Hello World")?;
/// let compressed = e.finish()?;
/// # Ok(())
/// # }
/// ```
#[derive(Debug)]
pub struct ZlibEncoder<W: Write> {
inner: zio::Writer<W, Compress>,
}
impl<W: Write> ZlibEncoder<W> {
/// Creates a new encoder which will write compressed data to the stream
/// given at the given compression level.
///
/// When this encoder is dropped or unwrapped the final pieces of data will
/// be flushed.
pub fn new(w: W, level: crate::Compression) -> ZlibEncoder<W> {
ZlibEncoder {
inner: zio::Writer::new(w, Compress::new(level, true)),
}
}
/// Creates a new encoder which will write compressed data to the stream
/// `w` with the given `compression` settings.
pub fn new_with_compress(w: W, compression: Compress) -> ZlibEncoder<W> {
ZlibEncoder {
inner: zio::Writer::new(w, compression),
}
}
/// Acquires a reference to the underlying writer.
pub fn get_ref(&self) -> &W {
self.inner.get_ref()
}
/// Acquires a mutable reference to the underlying writer.
///
/// Note that mutating the output/input state of the stream may corrupt this
/// object, so care must be taken when using this method.
pub fn get_mut(&mut self) -> &mut W {
self.inner.get_mut()
}
/// Resets the state of this encoder entirely, swapping out the output
/// stream for another.
///
/// This function will finish encoding the current stream into the current
/// output stream before swapping out the two output streams.
///
/// After the current stream has been finished, this will reset the internal
/// state of this encoder and replace the output stream with the one
/// provided, returning the previous output stream. Future data written to
/// this encoder will be the compressed into the stream `w` provided.
///
/// # Errors
///
/// This function will perform I/O to complete this stream, and any I/O
/// errors which occur will be returned from this function.
pub fn reset(&mut self, w: W) -> io::Result<W> {
self.inner.finish()?;
self.inner.data.reset();
Ok(self.inner.replace(w))
}
/// Attempt to finish this output stream, writing out final chunks of data.
///
/// Note that this function can only be used once data has finished being
/// written to the output stream. After this function is called then further
/// calls to `write` may result in a panic.
///
/// # Panics
///
/// Attempts to write data to this stream may result in a panic after this
/// function is called.
///
/// # Errors
///
/// This function will perform I/O to complete this stream, and any I/O
/// errors which occur will be returned from this function.
pub fn try_finish(&mut self) -> io::Result<()> {
self.inner.finish()
}
/// Consumes this encoder, flushing the output stream.
///
/// This will flush the underlying data stream, close off the compressed
/// stream and, if successful, return the contained writer.
///
/// Note that this function may not be suitable to call in a situation where
/// the underlying stream is an asynchronous I/O stream. To finish a stream
/// the `try_finish` (or `shutdown`) method should be used instead. To
/// re-acquire ownership of a stream it is safe to call this method after
/// `try_finish` or `shutdown` has returned `Ok`.
///
/// # Errors
///
/// This function will perform I/O to complete this stream, and any I/O
/// errors which occur will be returned from this function.
pub fn finish(mut self) -> io::Result<W> {
self.inner.finish()?;
Ok(self.inner.take_inner())
}
/// Consumes this encoder, flushing the output stream.
///
/// This will flush the underlying data stream and then return the contained
/// writer if the flush succeeded.
/// The compressed stream will not closed but only flushed. This
/// means that obtained byte array can by extended by another deflated
/// stream. To close the stream add the two bytes 0x3 and 0x0.
///
/// # Errors
///
/// This function will perform I/O to complete this stream, and any I/O
/// errors which occur will be returned from this function.
pub fn flush_finish(mut self) -> io::Result<W> {
self.inner.flush()?;
Ok(self.inner.take_inner())
}
/// 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.
pub fn total_in(&self) -> u64 {
self.inner.data.total_in()
}
/// Returns the number of bytes that the compressor has produced.
///
/// Note that not all bytes may have been written yet, some may still be
/// buffered.
pub fn total_out(&self) -> u64 {
self.inner.data.total_out()
}
}
impl<W: Write> Write for ZlibEncoder<W> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.inner.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.inner.flush()
}
}
impl<W: Read + Write> Read for ZlibEncoder<W> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.get_mut().read(buf)
}
}
/// A ZLIB decoder, or decompressor.
///
/// This structure implements a [`Write`] and will emit a stream of decompressed
/// data when fed a stream of compressed data.
///
/// [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
///
/// # Examples
///
/// ```
/// use std::io::prelude::*;
/// use std::io;
/// # use flate2::Compression;
/// # use flate2::write::ZlibEncoder;
/// use flate2::write::ZlibDecoder;
///
/// # fn main() {
/// # let mut e = ZlibEncoder::new(Vec::new(), Compression::default());
/// # e.write_all(b"Hello World").unwrap();
/// # let bytes = e.finish().unwrap();
/// # println!("{}", decode_reader(bytes).unwrap());
/// # }
/// #
/// // Uncompresses a Zlib Encoded vector of bytes and returns a string or error
/// // Here Vec<u8> implements Write
///
/// fn decode_reader(bytes: Vec<u8>) -> io::Result<String> {
/// let mut writer = Vec::new();
/// let mut z = ZlibDecoder::new(writer);
/// z.write_all(&bytes[..])?;
/// writer = z.finish()?;
/// let return_string = String::from_utf8(writer).expect("String parsing error");
/// Ok(return_string)
/// }
/// ```
#[derive(Debug)]
pub struct ZlibDecoder<W: Write> {
inner: zio::Writer<W, Decompress>,
}
impl<W: Write> ZlibDecoder<W> {
/// Creates a new decoder which will write uncompressed data to the stream.
///
/// When this decoder is dropped or unwrapped the final pieces of data will
/// be flushed.
pub fn new(w: W) -> ZlibDecoder<W> {
ZlibDecoder {
inner: zio::Writer::new(w, Decompress::new(true)),
}
}
/// Creates a new decoder which will write uncompressed data to the stream `w`
/// using the given `decompression` settings.
///
/// When this decoder is dropped or unwrapped the final pieces of data will
/// be flushed.
pub fn new_with_decompress(w: W, decompression: Decompress) -> ZlibDecoder<W> {
ZlibDecoder {
inner: zio::Writer::new(w, decompression),
}
}
/// Acquires a reference to the underlying writer.
pub fn get_ref(&self) -> &W {
self.inner.get_ref()
}
/// Acquires a mutable reference to the underlying writer.
///
/// Note that mutating the output/input state of the stream may corrupt this
/// object, so care must be taken when using this method.
pub fn get_mut(&mut self) -> &mut W {
self.inner.get_mut()
}
/// Resets the state of this decoder entirely, swapping out the output
/// stream for another.
///
/// This will reset the internal state of this decoder and replace the
/// output stream with the one provided, returning the previous output
/// stream. Future data written to this decoder will be decompressed into
/// the output stream `w`.
///
/// # Errors
///
/// This function will perform I/O to complete this stream, and any I/O
/// errors which occur will be returned from this function.
pub fn reset(&mut self, w: W) -> io::Result<W> {
self.inner.finish()?;
self.inner.data = Decompress::new(true);
Ok(self.inner.replace(w))
}
/// Attempt to finish this output stream, writing out final chunks of data.
///
/// Note that this function can only be used once data has finished being
/// written to the output stream. After this function is called then further
/// calls to `write` may result in a panic.
///
/// # Panics
///
/// Attempts to write data to this stream may result in a panic after this
/// function is called.
///
/// # Errors
///
/// This function will perform I/O to complete this stream, and any I/O
/// errors which occur will be returned from this function.
pub fn try_finish(&mut self) -> io::Result<()> {
self.inner.finish()
}
/// Consumes this encoder, flushing the output stream.
///
/// This will flush the underlying data stream and then return the contained
/// writer if the flush succeeded.
///
/// Note that this function may not be suitable to call in a situation where
/// the underlying stream is an asynchronous I/O stream. To finish a stream
/// the `try_finish` (or `shutdown`) method should be used instead. To
/// re-acquire ownership of a stream it is safe to call this method after
/// `try_finish` or `shutdown` has returned `Ok`.
///
/// # Errors
///
/// This function will perform I/O to complete this stream, and any I/O
/// errors which occur will be returned from this function.
pub fn finish(mut self) -> io::Result<W> {
self.inner.finish()?;
Ok(self.inner.take_inner())
}
/// Returns the number of bytes that the decompressor has consumed for
/// decompression.
///
/// Note that this will likely be smaller than the number of bytes
/// successfully written to this stream due to internal buffering.
pub fn total_in(&self) -> u64 {
self.inner.data.total_in()
}
/// Returns the number of bytes that the decompressor has written to its
/// output stream.
pub fn total_out(&self) -> u64 {
self.inner.data.total_out()
}
}
impl<W: Write> Write for ZlibDecoder<W> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.inner.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.inner.flush()
}
}
impl<W: Read + Write> Read for ZlibDecoder<W> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.get_mut().read(buf)
}
}

BIN
vendor/flate2/tests/corrupt-gz-file.bin vendored Normal file

Binary file not shown.

18
vendor/flate2/tests/early-flush.rs vendored Normal file
View File

@ -0,0 +1,18 @@
use std::io::{Read, Write};
use flate2::read::GzDecoder;
use flate2::write::GzEncoder;
#[test]
fn smoke() {
let mut w = GzEncoder::new(Vec::new(), flate2::Compression::default());
w.flush().unwrap();
w.write_all(b"hello").unwrap();
let bytes = w.finish().unwrap();
let mut r = GzDecoder::new(&bytes[..]);
let mut s = String::new();
r.read_to_string(&mut s).unwrap();
assert_eq!(s, "hello");
}

80
vendor/flate2/tests/empty-read.rs vendored Normal file
View File

@ -0,0 +1,80 @@
use std::io::{Read, Write};
#[test]
fn deflate_decoder_empty_read() {
let original: &[u8] = b"Lorem ipsum dolor sit amet.";
let mut encoder =
flate2::write::DeflateEncoder::new(Vec::new(), flate2::Compression::default());
encoder.write_all(original).unwrap();
let encoded: Vec<u8> = encoder.finish().unwrap();
let mut decoder = flate2::read::DeflateDecoder::new(encoded.as_slice());
assert_eq!(decoder.read(&mut []).unwrap(), 0);
let mut decoded = Vec::new();
decoder.read_to_end(&mut decoded).unwrap();
assert_eq!(decoded.as_slice(), original);
}
#[test]
fn deflate_encoder_empty_read() {
let original: &[u8] = b"Lorem ipsum dolor sit amet.";
let mut encoder = flate2::read::DeflateEncoder::new(original, flate2::Compression::default());
assert_eq!(encoder.read(&mut []).unwrap(), 0);
let mut encoded = Vec::new();
encoder.read_to_end(&mut encoded).unwrap();
let mut decoder = flate2::read::DeflateDecoder::new(encoded.as_slice());
let mut decoded = Vec::new();
decoder.read_to_end(&mut decoded).unwrap();
assert_eq!(decoded.as_slice(), original);
}
#[test]
fn gzip_decoder_empty_read() {
let original: &[u8] = b"Lorem ipsum dolor sit amet.";
let mut encoder = flate2::write::GzEncoder::new(Vec::new(), flate2::Compression::default());
encoder.write_all(original).unwrap();
let encoded: Vec<u8> = encoder.finish().unwrap();
let mut decoder = flate2::read::GzDecoder::new(encoded.as_slice());
assert_eq!(decoder.read(&mut []).unwrap(), 0);
let mut decoded = Vec::new();
decoder.read_to_end(&mut decoded).unwrap();
assert_eq!(decoded.as_slice(), original);
}
#[test]
fn gzip_encoder_empty_read() {
let original: &[u8] = b"Lorem ipsum dolor sit amet.";
let mut encoder = flate2::read::GzEncoder::new(original, flate2::Compression::default());
assert_eq!(encoder.read(&mut []).unwrap(), 0);
let mut encoded = Vec::new();
encoder.read_to_end(&mut encoded).unwrap();
let mut decoder = flate2::read::GzDecoder::new(encoded.as_slice());
let mut decoded = Vec::new();
decoder.read_to_end(&mut decoded).unwrap();
assert_eq!(decoded.as_slice(), original);
}
#[test]
fn zlib_decoder_empty_read() {
let original: &[u8] = b"Lorem ipsum dolor sit amet.";
let mut encoder = flate2::write::ZlibEncoder::new(Vec::new(), flate2::Compression::default());
encoder.write_all(original).unwrap();
let encoded: Vec<u8> = encoder.finish().unwrap();
let mut decoder = flate2::read::ZlibDecoder::new(encoded.as_slice());
assert_eq!(decoder.read(&mut []).unwrap(), 0);
let mut decoded = Vec::new();
decoder.read_to_end(&mut decoded).unwrap();
assert_eq!(decoded.as_slice(), original);
}
#[test]
fn zlib_encoder_empty_read() {
let original: &[u8] = b"Lorem ipsum dolor sit amet.";
let mut encoder = flate2::read::ZlibEncoder::new(original, flate2::Compression::default());
assert_eq!(encoder.read(&mut []).unwrap(), 0);
let mut encoded = Vec::new();
encoder.read_to_end(&mut encoded).unwrap();
let mut decoder = flate2::read::ZlibDecoder::new(encoded.as_slice());
let mut decoded = Vec::new();
decoder.read_to_end(&mut decoded).unwrap();
assert_eq!(decoded.as_slice(), original);
}

BIN
vendor/flate2/tests/good-file.gz vendored Normal file

Binary file not shown.

733
vendor/flate2/tests/good-file.txt vendored Normal file
View File

@ -0,0 +1,733 @@
## ##
timestep simulated EIR patent hosts
0 0.136402 16855
1 0.146872 18564
2 0.150157 20334
3 0.146358 22159
4 0.136315 23655
5 0.122354 24848
6 0.104753 25887
7 0.084439 26770
8 0.06417 27238
9 0.0450397 27349
10 0.0295473 27274
11 0.0184662 26909
12 0.0110032 26324
13 0.00634348 25513
14 0.0036144 24469
15 0.00208133 23383
16 0.00122468 22345
17 0.000752514 21342
18 0.000545333 20416
19 0.000546139 19657
20 0.00054572 18806
21 0.000545757 18015
22 0.000545898 17349
23 0.000546719 16594
24 0.000547353 15955
25 0.000547944 15374
26 0.000547606 14765
27 0.000594773 14212
28 0.000969163 13677
29 0.00168295 13180
30 0.003059 12760
31 0.00571599 12313
32 0.0107918 11896
33 0.0201943 11512
34 0.0368013 11340
35 0.0640629 11323
36 0.104447 11769
37 0.157207 12728
38 0.216682 14261
39 0.271159 16491
40 0.303552 19274
41 0.303678 22157
42 0.271945 24875
43 0.215445 27027
44 0.154503 28690
45 0.100717 30046
46 0.0600343 30602
47 0.0328576 30709
48 0.016964 30315
49 0.00841526 29310
50 0.0040958 28058
51 0.0019953 26662
52 0.000986531 25259
53 0.000545786 24049
54 0.000546405 22966
55 0.000546036 21933
56 0.00054427 20953
57 0.000542769 20057
58 0.000541566 19304
59 0.000541822 18477
60 0.000541643 17695
61 0.000541989 17002
62 0.000769298 16391
63 0.00150811 15805
64 0.00295097 15172
65 0.00566197 14690
66 0.0105243 14206
67 0.0186965 13791
68 0.0313363 13470
69 0.0490605 13377
70 0.0711679 13631
71 0.0953625 14209
72 0.118026 15277
73 0.134612 16760
74 0.144311 18339
75 0.146328 20124
76 0.142936 21803
77 0.134029 23435
78 0.120562 24854
79 0.103157 25880
80 0.0834054 26597
81 0.0632474 27226
82 0.0447785 27294
83 0.0295654 27169
84 0.0184081 26803
85 0.0109489 26265
86 0.00631234 25375
87 0.00359978 24306
88 0.00206967 23260
89 0.00122197 22225
90 0.000751031 21277
91 0.000544507 20295
92 0.000543897 19417
93 0.000543483 18623
94 0.000542926 17837
95 0.000542685 17070
96 0.000542387 16424
97 0.000541194 15838
98 0.000540427 15177
99 0.000540774 14608
100 0.000588312 14066
101 0.000959183 13499
102 0.00166774 12979
103 0.00303278 12545
104 0.00567457 12067
105 0.0107272 11712
106 0.0200606 11368
107 0.0364637 11207
108 0.063339 11238
109 0.103717 11660
110 0.156884 12621
111 0.217072 14151
112 0.272311 16358
113 0.305046 19005
114 0.304927 21926
115 0.272427 24662
116 0.216478 27080
117 0.155168 29064
118 0.10079 30370
119 0.0599659 30992
120 0.0331287 30975
121 0.017235 30317
122 0.00860221 29455
123 0.00419286 28172
124 0.00203361 26809
125 0.000998847 25476
126 0.000551418 24230
127 0.000551119 23106
128 0.000552786 22147
129 0.000553814 21183
130 0.000553743 20280
131 0.000554428 19423
132 0.000555022 18598
133 0.000555921 17864
134 0.000556687 17187
135 0.000789996 16527
136 0.00154597 15870
137 0.00302776 15226
138 0.00581484 14685
139 0.010812 14234
140 0.0191832 13818
141 0.0321572 13571
142 0.050328 13538
143 0.072817 13812
144 0.0974321 14368
145 0.120225 15436
146 0.137418 16988
147 0.147086 18775
148 0.149165 20563
149 0.144943 22223
150 0.136631 23741
151 0.123355 24920
152 0.105401 25779
153 0.0851918 26781
154 0.0641702 27265
155 0.0450746 27505
156 0.0294136 27416
157 0.0183811 27028
158 0.0109285 26260
159 0.00634296 25451
160 0.00364513 24472
161 0.0021051 23427
162 0.00123693 22403
163 0.000759531 21393
164 0.000551727 20485
165 0.000552256 19660
166 0.000552303 18862
167 0.000550927 18094
168 0.000551098 17378
169 0.000551093 16691
170 0.000551885 16050
171 0.000552282 15420
172 0.000552591 14878
173 0.00060109 14357
174 0.000980446 13768
175 0.00170301 13241
176 0.003096 12745
177 0.00579971 12294
178 0.010976 11879
179 0.0205422 11636
180 0.0374515 11431
181 0.0649916 11517
182 0.106008 11966
183 0.159983 12918
184 0.221127 14484
185 0.276503 16696
186 0.310316 19518
187 0.311205 22301
188 0.276769 25047
189 0.220506 27360
190 0.159123 29133
191 0.103761 30440
192 0.0613797 31087
193 0.033583 31037
194 0.0173275 30555
195 0.00861968 29617
196 0.00419503 28292
197 0.00203304 26944
198 0.00100126 25569
199 0.000553511 24349
200 0.000554687 23257
201 0.00055586 22204
202 0.000555419 21176
203 0.000556032 20316
204 0.000555974 19509
205 0.000556859 18746
206 0.000556996 17978
207 0.000557102 17288
208 0.000790187 16672
209 0.00154711 16057
210 0.00303521 15449
211 0.00584201 14915
212 0.0108854 14397
213 0.0193386 14010
214 0.0324346 13730
215 0.0507192 13674
216 0.0736661 13874
217 0.0987887 14515
218 0.122411 15693
219 0.139964 17265
220 0.149125 18894
221 0.151434 20662
222 0.148067 22442
223 0.138894 24116
224 0.125436 25367
225 0.107664 26360
226 0.0865709 27044
227 0.0655588 27428
228 0.0459664 27714
229 0.0301384 27687
230 0.0186481 27262
231 0.01103 26677
232 0.00636957 25722
233 0.00366188 24662
234 0.00212213 23575
235 0.00125358 22520
236 0.000768665 21480
237 0.000556393 20563
238 0.000555892 19706
239 0.00055534 18914
240 0.000555027 18165
241 0.000555062 17432
242 0.000553766 16733
243 0.000552984 16070
244 0.000553634 15396
245 0.000554286 14867
246 0.000603759 14362
247 0.000982974 13867
248 0.00170532 13379
249 0.00310471 12907
250 0.00582577 12446
251 0.0110122 12018
252 0.0206284 11730
253 0.0375835 11546
254 0.0652192 11605
255 0.10646 11981
256 0.160858 12949
257 0.223122 14478
258 0.279678 16810
259 0.312171 19452
260 0.311778 22391
261 0.276966 25204
262 0.22251 27379
263 0.159246 29248
264 0.104109 30532
265 0.0617903 30995
266 0.0338421 31042
267 0.0174647 30620
268 0.00867821 29589
269 0.00419968 28293
270 0.00203244 26916
271 0.00100204 25464
272 0.000555586 24219
273 0.000555599 23207
274 0.00055582 22187
275 0.00055516 21136
276 0.000555436 20243
277 0.000555618 19426
278 0.000556778 18635
279 0.000556976 17870
280 0.000557162 17190
281 0.0007904 16506
282 0.00154557 15837
283 0.00302973 15234
284 0.00584543 14717
285 0.0108796 14225
286 0.0192919 13810
287 0.032329 13605
288 0.0505293 13536
289 0.0733417 13760
290 0.0982413 14378
291 0.121477 15400
292 0.138636 17017
293 0.14875 18764
294 0.150515 20516
295 0.146372 22389
296 0.137332 23975
297 0.124076 25120
298 0.106469 26137
299 0.0862987 26973
300 0.0650552 27584
301 0.0456456 27741
302 0.0300744 27565
303 0.0187879 27212
304 0.0112085 26432
305 0.00648306 25501
306 0.00370346 24466
307 0.00213399 23472
308 0.00125463 22415
309 0.000765794 21427
310 0.000552587 20533
311 0.000553175 19632
312 0.000553525 18831
313 0.000554941 18119
314 0.000556327 17336
315 0.000556008 16721
316 0.00055593 16086
317 0.000556421 15516
318 0.000557308 14918
319 0.00060681 14402
320 0.000990746 13849
321 0.00172359 13355
322 0.00313688 12902
323 0.0058708 12425
324 0.0110637 12087
325 0.0206777 11743
326 0.0376394 11531
327 0.0656182 11582
328 0.107414 12034
329 0.162101 12955
330 0.223525 14571
331 0.279935 16842
332 0.314601 19566
333 0.313556 22575
334 0.279571 25279
335 0.221638 27642
336 0.158038 29275
337 0.102505 30638
338 0.0608328 31209
339 0.0335531 31260
340 0.0173332 30520
341 0.00861545 29604
342 0.00419454 28370
343 0.00202587 26940
344 0.000994029 25614
345 0.000549339 24445
346 0.000551477 23239
347 0.000552891 22300
348 0.000551775 21280
349 0.000552425 20424
350 0.000552135 19571
351 0.000552542 18753
352 0.000552863 18058
353 0.000554438 17348
354 0.000786735 16671
355 0.00153958 16047
356 0.00301482 15500
357 0.00580589 14883
358 0.0108227 14347
359 0.0192357 13947
360 0.0321613 13672
361 0.050229 13606
362 0.0729462 13815
363 0.0978564 14566
364 0.120879 15674
365 0.137663 17049
366 0.147092 18813
367 0.150184 20578
368 0.146971 22245
369 0.136769 23723
370 0.12367 24905
371 0.106187 25871
372 0.0860921 26687
373 0.0645899 27375
374 0.0453473 27635
375 0.0298122 27551
376 0.0185448 27134
377 0.0110517 26468
378 0.00640294 25661
379 0.00367011 24653
380 0.00211832 23556
381 0.00125246 22513
382 0.00076891 21568
383 0.000557384 20672
384 0.000557295 19811
385 0.000556837 18982
386 0.000557433 18179
387 0.000557376 17457
388 0.000557751 16720
389 0.000556844 16112
390 0.000555603 15479
391 0.000554871 14809
392 0.00060335 14275
393 0.000982808 13757
394 0.00170757 13221
395 0.00310351 12758
396 0.0058181 12286
397 0.010991 11906
398 0.0205342 11557
399 0.0373486 11393
400 0.0647659 11487
401 0.105589 11887
402 0.15967 12798
403 0.220945 14260
404 0.277122 16477
405 0.310108 19295
406 0.308854 22110
407 0.274911 24915
408 0.218618 27273
409 0.156618 29189
410 0.101775 30572
411 0.0607503 31174
412 0.0334708 31316
413 0.0173443 30731
414 0.00865633 29636
415 0.00421141 28342
416 0.00204387 26991
417 0.00100602 25595
418 0.000555131 24336
419 0.000555037 23251
420 0.000555559 22267
421 0.000554916 21212
422 0.000554432 20306
423 0.000554751 19488
424 0.00055638 18727
425 0.000556727 17927
426 0.000556368 17198
427 0.000788004 16578
428 0.00154404 15944
429 0.00302383 15315
430 0.00582586 14786
431 0.0108457 14290
432 0.0192962 13815
433 0.0323072 13561
434 0.0505101 13456
435 0.0732162 13811
436 0.0978737 14403
437 0.121405 15460
438 0.138202 16993
439 0.1482 18710
440 0.149707 20578
441 0.146945 22256
442 0.137785 23713
443 0.123767 25058
444 0.105989 26087
445 0.085483 26759
446 0.0646144 27375
447 0.0454389 27680
448 0.0299337 27531
449 0.018663 27041
450 0.0111347 26416
451 0.00644197 25614
452 0.00369229 24666
453 0.00211986 23647
454 0.00124761 22650
455 0.000769104 21642
456 0.000558796 20693
457 0.000559908 19746
458 0.000559562 18952
459 0.00056042 18100
460 0.000559447 17401
461 0.000557893 16756
462 0.000557137 16148
463 0.000557269 15504
464 0.000557596 14974
465 0.000606298 14408
466 0.000987712 13909
467 0.00171257 13402
468 0.00311667 12891
469 0.00584794 12433
470 0.0110774 11980
471 0.0207006 11713
472 0.037673 11583
473 0.0654988 11677
474 0.106982 12072
475 0.161926 12898
476 0.224327 14548
477 0.281709 16796
478 0.314567 19512
479 0.313419 22428
480 0.278962 25186
481 0.221864 27755
482 0.158559 29556
483 0.103532 30572
484 0.0611592 31162
485 0.0337539 31197
486 0.0175096 30619
487 0.00865906 29606
488 0.00420125 28271
489 0.00203207 26856
490 0.00100238 25542
491 0.000554405 24306
492 0.00055373 23160
493 0.0005552 22152
494 0.000553776 21192
495 0.000553636 20302
496 0.000553165 19505
497 0.000554014 18719
498 0.00055519 17993
499 0.000556582 17233
500 0.000788165 16569
501 0.00154132 15953
502 0.00302099 15350
503 0.00581186 14752
504 0.0108291 14267
505 0.0192368 13946
506 0.0322191 13677
507 0.0503789 13594
508 0.0730706 13768
509 0.0980646 14416
510 0.121601 15634
511 0.139046 17110
512 0.147779 18876
513 0.149612 20734
514 0.145796 22414
515 0.136936 23884
516 0.123807 25078
517 0.106212 26066
518 0.0855482 26779
519 0.0643386 27340
520 0.0452926 27530
521 0.0298659 27573
522 0.0185447 27169
523 0.0110178 26489
524 0.00635235 25588
525 0.00362881 24549
526 0.00209238 23528
527 0.00123133 22541
528 0.000755917 21498
529 0.000546368 20607
530 0.000547382 19712
531 0.000547084 18975
532 0.000546453 18178
533 0.000546062 17452
534 0.000546085 16749
535 0.000546151 16135
536 0.000545628 15567
537 0.000545969 14968
538 0.000594606 14392
539 0.000968849 13854
540 0.00168489 13360
541 0.00306337 12899
542 0.00573505 12407
543 0.0108348 12017
544 0.02025 11713
545 0.0368201 11517
546 0.0639795 11556
547 0.104882 11941
548 0.158923 12854
549 0.219796 14396
550 0.275801 16733
551 0.307622 19367
552 0.30785 22230
553 0.272898 24873
554 0.217351 27152
555 0.156138 29108
556 0.101477 30379
557 0.0601091 30971
558 0.0331551 31126
559 0.017167 30418
560 0.00853886 29430
561 0.00415201 28190
562 0.00201849 26849
563 0.000991957 25528
564 0.000546751 24180
565 0.00054534 23090
566 0.000544403 22096
567 0.00054368 21140
568 0.000543407 20213
569 0.000544421 19405
570 0.000545241 18625
571 0.000546995 17868
572 0.000547101 17102
573 0.00077428 16423
574 0.00151348 15783
575 0.00296212 15220
576 0.00569555 14602
577 0.0106307 14154
578 0.0188783 13743
579 0.0316572 13538
580 0.0495211 13467
581 0.0718936 13665
582 0.0961304 14240
583 0.119127 15341
584 0.136233 16912
585 0.145327 18567
586 0.146983 20301
587 0.143022 21953
588 0.134931 23439
589 0.121892 24750
590 0.103955 25688
591 0.0833804 26253
592 0.0625106 26918
593 0.0440419 27279
594 0.0290823 27159
595 0.0180758 26786
596 0.0107654 26049
597 0.00622673 25202
598 0.00356716 24168
599 0.00205866 23122
600 0.00121254 22076
601 0.000745744 21100
602 0.000537789 20207
603 0.000537982 19340
604 0.000537795 18527
605 0.000537955 17768
606 0.000539259 17117
607 0.00053942 16425
608 0.000540477 15701
609 0.000540424 15134
610 0.000540084 14558
611 0.00058571 14069
612 0.00095364 13498
613 0.00165505 13054
614 0.00300205 12616
615 0.00561724 12142
616 0.0106079 11720
617 0.0198178 11410
618 0.0360368 11231
619 0.0623418 11314
620 0.101856 11688
621 0.15376 12623
622 0.213046 14078
623 0.267285 16225
624 0.299225 18856
625 0.299517 21756
626 0.26697 24652
627 0.2119 27051
628 0.151393 28925
629 0.098869 30065
630 0.0593653 30570
631 0.0327177 30483
632 0.0170081 29735
633 0.0084493 28844
634 0.00409333 27665
635 0.00197466 26356
636 0.000967996 25009
637 0.000533137 23839
638 0.000532992 22721
639 0.000534258 21676
640 0.000534251 20709
641 0.000534556 19798
642 0.000535287 19008
643 0.000536214 18278
644 0.000536647 17547
645 0.000536556 16901
646 0.000761043 16256
647 0.00149108 15621
648 0.00292808 15032
649 0.0056527 14504
650 0.0105421 14010
651 0.0186823 13646
652 0.0312164 13356
653 0.0485643 13404
654 0.0704061 13612
655 0.0945219 14230
656 0.117178 15374
657 0.134568 16843
658 0.144475 18492
659 0.146915 20238
660 0.14393 21958
661 0.134621 23537
662 0.121737 24773
663 0.104744 25772
664 0.0846226 26427
665 0.0639754 27040
666 0.0448457 27279
667 0.029482 27106
668 0.0183036 26853
669 0.0108721 26178
670 0.00627116 25425
671 0.0035776 24326
672 0.00206466 23279
673 0.00122064 22191
674 0.000751578 21231
675 0.000542574 20323
676 0.000540396 19496
677 0.000538805 18651
678 0.00053881 17920
679 0.000537801 17217
680 0.000537866 16520
681 0.000538522 15876
682 0.000538795 15229
683 0.000539519 14656
684 0.000587348 14121
685 0.000955855 13626
686 0.00165656 13086
687 0.00301095 12666
688 0.00564993 12250
689 0.0106767 11869
690 0.0199729 11524
691 0.03641 11331
692 0.0632378 11402
693 0.103483 11788
694 0.156399 12682
695 0.215591 14337
696 0.269462 16547
697 0.303615 19239
698 0.304506 22023
699 0.273068 24769
700 0.21682 27223
701 0.154934 29029
702 0.100495 30241
703 0.0597382 30801
704 0.0329221 30881
705 0.0170591 30288
706 0.00845353 29329
707 0.00408176 28108
708 0.00198037 26715
709 0.000977102 25340
710 0.000541566 24039
711 0.000542333 22965
712 0.000542417 21858
713 0.000541182 20952
714 0.00054038 20049
715 0.000539725 19192
716 0.000539603 18409
717 0.000539754 17700
718 0.000539679 16960
719 0.000763508 16287
720 0.00149327 15637
721 0.00292609 15057
722 0.00563308 14524
723 0.0104893 14003
724 0.0185874 13625
725 0.0310985 13319
726 0.0487417 13278
727 0.0707124 13502
728 0.0947795 14147
729 0.117155 15183
730 0.133995 16622

75
vendor/flate2/tests/gunzip.rs vendored Normal file
View File

@ -0,0 +1,75 @@
use flate2::read::GzDecoder;
use flate2::read::MultiGzDecoder;
use std::fs::File;
use std::io::prelude::*;
use std::io::{self, BufReader};
use std::path::Path;
// test extraction of a gzipped file
#[test]
fn test_extract_success() {
let content = extract_file(Path::new("tests/good-file.gz")).unwrap();
let mut expected = Vec::new();
File::open("tests/good-file.txt")
.unwrap()
.read_to_end(&mut expected)
.unwrap();
assert_eq!(content, expected);
}
//
// test partial extraction of a multistream gzipped file
#[test]
fn test_extract_success_partial_multi() {
let content = extract_file(Path::new("tests/multi.gz")).unwrap();
let mut expected = String::new();
BufReader::new(File::open("tests/multi.txt").unwrap())
.read_line(&mut expected)
.unwrap();
assert_eq!(content, expected.as_bytes());
}
// test extraction fails on a corrupt file
#[test]
fn test_extract_failure() {
let result = extract_file(Path::new("tests/corrupt-gz-file.bin"));
assert_eq!(result.err().unwrap().kind(), io::ErrorKind::InvalidInput);
}
//test complete extraction of a multistream gzipped file
#[test]
fn test_extract_success_multi() {
let content = extract_file_multi(Path::new("tests/multi.gz")).unwrap();
let mut expected = Vec::new();
File::open("tests/multi.txt")
.unwrap()
.read_to_end(&mut expected)
.unwrap();
assert_eq!(content, expected);
}
// Tries to extract path into memory (assuming a .gz file).
fn extract_file(path_compressed: &Path) -> io::Result<Vec<u8>> {
let mut v = Vec::new();
let f = File::open(path_compressed)?;
GzDecoder::new(f).read_to_end(&mut v)?;
Ok(v)
}
// Tries to extract path into memory (decompressing all members in case
// of a multi member .gz file).
fn extract_file_multi(path_compressed: &Path) -> io::Result<Vec<u8>> {
let mut v = Vec::new();
let f = File::open(path_compressed)?;
MultiGzDecoder::new(f).read_to_end(&mut v)?;
Ok(v)
}
#[test]
fn empty_error_once() {
let data: &[u8] = &[];
let cbjson = GzDecoder::new(data);
let reader = BufReader::new(cbjson);
let mut stream = reader.lines();
assert!(stream.next().unwrap().is_err());
assert!(stream.next().is_none());
}

BIN
vendor/flate2/tests/multi.gz vendored Normal file

Binary file not shown.

2
vendor/flate2/tests/multi.txt vendored Normal file
View File

@ -0,0 +1,2 @@
first
second

6
vendor/flate2/tests/zero-write.rs vendored Normal file
View File

@ -0,0 +1,6 @@
#[test]
fn zero_write_is_error() {
let mut buf = [0u8];
let writer = flate2::write::DeflateEncoder::new(&mut buf[..], flate2::Compression::default());
assert!(writer.finish().is_err());
}