Coverage Report

Created: 2025-07-11 07:11

/rust/registry/src/index.crates.io-6f17d22bba15001f/flate2-1.1.2/src/lib.rs
Line
Count
Source (jump to first uncovered line)
1
//! A DEFLATE-based stream compression/decompression library
2
//!
3
//! This library provides support for compression and decompression of
4
//! DEFLATE-based streams:
5
//!
6
//! * the DEFLATE format itself
7
//! * the zlib format
8
//! * gzip
9
//!
10
//! These three formats are all closely related and largely only differ in their
11
//! headers/footers. This crate has three types in each submodule for dealing
12
//! with these three formats.
13
//!
14
//! # Implementation
15
//!
16
//! In addition to supporting three formats, this crate supports several different
17
//! backends, controlled through this crate's features:
18
//!
19
//! * `default`, or `rust_backend` - this implementation uses the `miniz_oxide`
20
//!   crate which is a port of `miniz.c` to Rust. This feature does not
21
//!   require a C compiler, and only uses safe Rust code.
22
//!
23
//! * `zlib-rs` - this implementation utilizes the `zlib-rs` crate, a Rust rewrite of zlib.
24
//!   This backend is the fastest, at the cost of some `unsafe` Rust code.
25
//!
26
//! Several backends implemented in C are also available.
27
//! These are useful in case you are already using a specific C implementation
28
//! and need the result of compression to be bit-identical.
29
//! See the crate's README for details on the available C backends.
30
//!
31
//! The `zlib-rs` backend typically outperforms all the C implementations.
32
//!
33
//! # Organization
34
//!
35
//! This crate consists mainly of three modules, [`read`], [`write`], and
36
//! [`bufread`]. Each module contains a number of types used to encode and
37
//! decode various streams of data.
38
//!
39
//! All types in the [`write`] module work on instances of [`Write`][write],
40
//! whereas all types in the [`read`] module work on instances of
41
//! [`Read`][read] and [`bufread`] works with [`BufRead`][bufread]. If you
42
//! are decoding directly from a `&[u8]`, use the [`bufread`] types.
43
//!
44
//! ```
45
//! use flate2::write::GzEncoder;
46
//! use flate2::Compression;
47
//! use std::io;
48
//! use std::io::prelude::*;
49
//!
50
//! # fn main() { let _ = run(); }
51
//! # fn run() -> io::Result<()> {
52
//! let mut encoder = GzEncoder::new(Vec::new(), Compression::default());
53
//! encoder.write_all(b"Example")?;
54
//! # Ok(())
55
//! # }
56
//! ```
57
//!
58
//!
59
//! Other various types are provided at the top-level of the crate for
60
//! management and dealing with encoders/decoders. Also note that types which
61
//! operate over a specific trait often implement the mirroring trait as well.
62
//! For example a `flate2::read::DeflateDecoder<T>` *also* implements the
63
//! `Write` trait if `T: Write`. That is, the "dual trait" is forwarded directly
64
//! to the underlying object if available.
65
//!
66
//! # About multi-member Gzip files
67
//!
68
//! While most `gzip` files one encounters will have a single *member* that can be read
69
//! with the [`GzDecoder`], there may be some files which have multiple members.
70
//!
71
//! A [`GzDecoder`] will only read the first member of gzip data, which may unexpectedly
72
//! provide partial results when a multi-member gzip file is encountered. `GzDecoder` is appropriate
73
//! for data that is designed to be read as single members from a multi-member file. `bufread::GzDecoder`
74
//! and `write::GzDecoder` also allow non-gzip data following gzip data to be handled.
75
//!
76
//! The [`MultiGzDecoder`] on the other hand will decode all members of a `gzip` file
77
//! into one consecutive stream of bytes, which hides the underlying *members* entirely.
78
//! If a file contains non-gzip data after the gzip data, MultiGzDecoder will
79
//! emit an error after decoding the gzip data. This behavior matches the `gzip`,
80
//! `gunzip`, and `zcat` command line tools.
81
//!
82
//! [`read`]: read/index.html
83
//! [`bufread`]: bufread/index.html
84
//! [`write`]: write/index.html
85
//! [read]: https://doc.rust-lang.org/std/io/trait.Read.html
86
//! [write]: https://doc.rust-lang.org/std/io/trait.Write.html
87
//! [bufread]: https://doc.rust-lang.org/std/io/trait.BufRead.html
88
//! [`GzDecoder`]: read/struct.GzDecoder.html
89
//! [`MultiGzDecoder`]: read/struct.MultiGzDecoder.html
90
#![doc(html_root_url = "https://docs.rs/flate2/0.2")]
91
#![deny(missing_docs)]
92
#![deny(missing_debug_implementations)]
93
#![allow(trivial_numeric_casts)]
94
#![cfg_attr(test, deny(warnings))]
95
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
96
97
#[cfg(not(feature = "any_impl",))]
98
compile_error!("You need to choose a zlib backend");
99
100
pub use crate::crc::{Crc, CrcReader, CrcWriter};
101
pub use crate::gz::GzBuilder;
102
pub use crate::gz::GzHeader;
103
pub use crate::mem::{Compress, CompressError, Decompress, DecompressError, Status};
104
pub use crate::mem::{FlushCompress, FlushDecompress};
105
106
mod bufreader;
107
mod crc;
108
mod deflate;
109
mod ffi;
110
mod gz;
111
mod mem;
112
mod zio;
113
mod zlib;
114
115
/// Types which operate over [`Read`] streams, both encoders and decoders for
116
/// various formats.
117
///
118
/// Note that the `read` decoder types may read past the end of the compressed
119
/// data while decoding. If the caller requires subsequent reads to start
120
/// immediately following the compressed data  wrap the `Read` type in a
121
/// [`BufReader`] and use the `BufReader` with the equivalent decoder from the
122
/// `bufread` module and also for the subsequent reads.
123
///
124
/// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
125
/// [`BufReader`]: https://doc.rust-lang.org/std/io/struct.BufReader.html
126
pub mod read {
127
    pub use crate::deflate::read::DeflateDecoder;
128
    pub use crate::deflate::read::DeflateEncoder;
129
    pub use crate::gz::read::GzDecoder;
130
    pub use crate::gz::read::GzEncoder;
131
    pub use crate::gz::read::MultiGzDecoder;
132
    pub use crate::zlib::read::ZlibDecoder;
133
    pub use crate::zlib::read::ZlibEncoder;
134
}
135
136
/// Types which operate over [`Write`] streams, both encoders and decoders for
137
/// various formats.
138
///
139
/// [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
140
pub mod write {
141
    pub use crate::deflate::write::DeflateDecoder;
142
    pub use crate::deflate::write::DeflateEncoder;
143
    pub use crate::gz::write::GzDecoder;
144
    pub use crate::gz::write::GzEncoder;
145
    pub use crate::gz::write::MultiGzDecoder;
146
    pub use crate::zlib::write::ZlibDecoder;
147
    pub use crate::zlib::write::ZlibEncoder;
148
}
149
150
/// Types which operate over [`BufRead`] streams, both encoders and decoders for
151
/// various formats.
152
///
153
/// [`BufRead`]: https://doc.rust-lang.org/std/io/trait.BufRead.html
154
pub mod bufread {
155
    pub use crate::deflate::bufread::DeflateDecoder;
156
    pub use crate::deflate::bufread::DeflateEncoder;
157
    pub use crate::gz::bufread::GzDecoder;
158
    pub use crate::gz::bufread::GzEncoder;
159
    pub use crate::gz::bufread::MultiGzDecoder;
160
    pub use crate::zlib::bufread::ZlibDecoder;
161
    pub use crate::zlib::bufread::ZlibEncoder;
162
}
163
164
0
fn _assert_send_sync() {
165
0
    fn _assert_send_sync<T: Send + Sync>() {}
166
167
0
    _assert_send_sync::<read::DeflateEncoder<&[u8]>>();
168
0
    _assert_send_sync::<read::DeflateDecoder<&[u8]>>();
169
0
    _assert_send_sync::<read::ZlibEncoder<&[u8]>>();
170
0
    _assert_send_sync::<read::ZlibDecoder<&[u8]>>();
171
0
    _assert_send_sync::<read::GzEncoder<&[u8]>>();
172
0
    _assert_send_sync::<read::GzDecoder<&[u8]>>();
173
0
    _assert_send_sync::<read::MultiGzDecoder<&[u8]>>();
174
0
    _assert_send_sync::<write::DeflateEncoder<Vec<u8>>>();
175
0
    _assert_send_sync::<write::DeflateDecoder<Vec<u8>>>();
176
0
    _assert_send_sync::<write::ZlibEncoder<Vec<u8>>>();
177
0
    _assert_send_sync::<write::ZlibDecoder<Vec<u8>>>();
178
0
    _assert_send_sync::<write::GzEncoder<Vec<u8>>>();
179
0
    _assert_send_sync::<write::GzDecoder<Vec<u8>>>();
180
0
}
181
182
/// When compressing data, the compression level can be specified by a value in
183
/// this struct.
184
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
185
pub struct Compression(u32);
186
187
impl Compression {
188
    /// Creates a new description of the compression level with an explicitly
189
    /// specified integer.
190
    ///
191
    /// The integer here is typically on a scale of 0-9 where 0 means "no
192
    /// compression" and 9 means "take as long as you'd like".
193
    ///
194
    /// ### Backend differences
195
    ///
196
    /// The [`miniz_oxide`](https://crates.io/crates/miniz_oxide) backend for flate2
197
    /// does not support level 0 or `Compression::none()`. Instead it interprets them
198
    /// as the default compression level, which is quite slow.
199
    /// `Compression::fast()` should be used instead.
200
    ///
201
    /// `miniz_oxide` also supports a non-compliant compression level 10.
202
    /// It is even slower and may result in higher compression, but
203
    /// **only miniz_oxide will be able to read the data** compressed with level 10.
204
    /// Do **not** use level 10 if you need other software to be able to read it!
205
0
    pub const fn new(level: u32) -> Compression {
206
0
        Compression(level)
207
0
    }
208
209
    /// No compression is to be performed, this may actually inflate data
210
    /// slightly when encoding.
211
0
    pub const fn none() -> Compression {
212
0
        Compression(0)
213
0
    }
214
215
    /// Optimize for the best speed of encoding.
216
0
    pub const fn fast() -> Compression {
217
0
        Compression(1)
218
0
    }
219
220
    /// Optimize for the size of data being encoded.
221
0
    pub const fn best() -> Compression {
222
0
        Compression(9)
223
0
    }
224
225
    /// Returns an integer representing the compression level, typically on a
226
    /// scale of 0-9. See [`new`](Self::new) for details about compression levels.
227
0
    pub fn level(&self) -> u32 {
228
0
        self.0
229
0
    }
230
}
231
232
impl Default for Compression {
233
0
    fn default() -> Compression {
234
0
        Compression(6)
235
0
    }
236
}
237
238
#[cfg(test)]
239
fn random_bytes() -> impl Iterator<Item = u8> {
240
    use rand::Rng;
241
    use std::iter;
242
243
    iter::repeat(()).map(|_| rand::rng().random())
244
}