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` (below) to Rust. This feature does not
21//! require a C compiler and only requires Rust code.
22//!
23//! * `zlib` - this feature will enable linking against the `libz` library, typically found on most
24//! Linux systems by default. If the library isn't found to already be on the system it will be
25//! compiled from source (this is a C library).
26//!
27//! There's various tradeoffs associated with each implementation, but in general you probably
28//! won't have to tweak the defaults. The default choice is selected to avoid the need for a C
29//! compiler at build time. `zlib-ng-compat` is useful if you're using zlib for compatibility but
30//! want performance via zlib-ng's zlib-compat mode. `zlib` is useful if something else in your
31//! dependencies links the original zlib so you cannot use zlib-ng-compat. The compression ratios
32//! and performance of each of these feature should be roughly comparable, but you'll likely want
33//! to run your own tests if you're curious about the performance.
34//!
35//! # Organization
36//!
37//! This crate consists mainly of three modules, [`read`], [`write`], and
38//! [`bufread`]. Each module contains a number of types used to encode and
39//! decode various streams of data.
40//!
41//! All types in the [`write`] module work on instances of [`Write`][write],
42//! whereas all types in the [`read`] module work on instances of
43//! [`Read`][read] and [`bufread`] works with [`BufRead`][bufread]. If you
44//! are decoding directly from a `&[u8]`, use the [`bufread`] types.
45//!
46//! ```
47//! use flate2::write::GzEncoder;
48//! use flate2::Compression;
49//! use std::io;
50//! use std::io::prelude::*;
51//!
52//! # fn main() { let _ = run(); }
53//! # fn run() -> io::Result<()> {
54//! let mut encoder = GzEncoder::new(Vec::new(), Compression::default());
55//! encoder.write_all(b"Example")?;
56//! # Ok(())
57//! # }
58//! ```
59//!
60//!
61//! Other various types are provided at the top-level of the crate for
62//! management and dealing with encoders/decoders. Also note that types which
63//! operate over a specific trait often implement the mirroring trait as well.
64//! For example a `flate2::read::DeflateDecoder<T>` *also* implements the
65//! `Write` trait if `T: Write`. That is, the "dual trait" is forwarded directly
66//! to the underlying object if available.
67//!
68//! # About multi-member Gzip files
69//!
70//! While most `gzip` files one encounters will have a single *member* that can be read
71//! with the [`GzDecoder`], there may be some files which have multiple members.
72//!
73//! A [`GzDecoder`] will only read the first member of gzip data, which may unexpectedly
74//! provide partial results when a multi-member gzip file is encountered. `GzDecoder` is appropriate
75//! for data that is designed to be read as single members from a multi-member file. `bufread::GzDecoder`
76//! and `write::GzDecoder` also allow non-gzip data following gzip data to be handled.
77//!
78//! The [`MultiGzDecoder`] on the other hand will decode all members of a `gzip` file
79//! into one consecutive stream of bytes, which hides the underlying *members* entirely.
80//! If a file contains contains non-gzip data after the gzip data, MultiGzDecoder will
81//! emit an error after decoding the gzip data. This behavior matches the `gzip`,
82//! `gunzip`, and `zcat` command line tools.
83//!
84//! [`read`]: read/index.html
85//! [`bufread`]: bufread/index.html
86//! [`write`]: write/index.html
87//! [read]: https://doc.rust-lang.org/std/io/trait.Read.html
88//! [write]: https://doc.rust-lang.org/std/io/trait.Write.html
89//! [bufread]: https://doc.rust-lang.org/std/io/trait.BufRead.html
90//! [`GzDecoder`]: read/struct.GzDecoder.html
91//! [`MultiGzDecoder`]: read/struct.MultiGzDecoder.html
92#![doc(html_root_url = "https://docs.rs/flate2/0.2")]
93#![deny(missing_docs)]
94#![deny(missing_debug_implementations)]
95#![allow(trivial_numeric_casts)]
96#![cfg_attr(test, deny(warnings))]
97#![cfg_attr(docsrs, feature(doc_auto_cfg))]
98
99#[cfg(not(feature = "any_impl",))]
100compile_error!("You need to choose a zlib backend");
101
102pub use crate::crc::{Crc, CrcReader, CrcWriter};
103pub use crate::gz::GzBuilder;
104pub use crate::gz::GzHeader;
105pub use crate::mem::{Compress, CompressError, Decompress, DecompressError, Status};
106pub use crate::mem::{FlushCompress, FlushDecompress};
107
108mod bufreader;
109mod crc;
110mod deflate;
111mod ffi;
112mod gz;
113mod mem;
114mod zio;
115mod zlib;
116
117/// Types which operate over [`Read`] streams, both encoders and decoders for
118/// various formats.
119///
120/// Note that the `read` decoder types may read past the end of the compressed
121/// data while decoding. If the caller requires subsequent reads to start
122/// immediately following the compressed data wrap the `Read` type in a
123/// [`BufReader`] and use the `BufReader` with the equivalent decoder from the
124/// `bufread` module and also for the subsequent reads.
125///
126/// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
127/// [`BufReader`]: https://doc.rust-lang.org/std/io/struct.BufReader.html
128pub mod read {
129 pub use crate::deflate::read::DeflateDecoder;
130 pub use crate::deflate::read::DeflateEncoder;
131 pub use crate::gz::read::GzDecoder;
132 pub use crate::gz::read::GzEncoder;
133 pub use crate::gz::read::MultiGzDecoder;
134 pub use crate::zlib::read::ZlibDecoder;
135 pub use crate::zlib::read::ZlibEncoder;
136}
137
138/// Types which operate over [`Write`] streams, both encoders and decoders for
139/// various formats.
140///
141/// [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
142pub mod write {
143 pub use crate::deflate::write::DeflateDecoder;
144 pub use crate::deflate::write::DeflateEncoder;
145 pub use crate::gz::write::GzDecoder;
146 pub use crate::gz::write::GzEncoder;
147 pub use crate::gz::write::MultiGzDecoder;
148 pub use crate::zlib::write::ZlibDecoder;
149 pub use crate::zlib::write::ZlibEncoder;
150}
151
152/// Types which operate over [`BufRead`] streams, both encoders and decoders for
153/// various formats.
154///
155/// [`BufRead`]: https://doc.rust-lang.org/std/io/trait.BufRead.html
156pub mod bufread {
157 pub use crate::deflate::bufread::DeflateDecoder;
158 pub use crate::deflate::bufread::DeflateEncoder;
159 pub use crate::gz::bufread::GzDecoder;
160 pub use crate::gz::bufread::GzEncoder;
161 pub use crate::gz::bufread::MultiGzDecoder;
162 pub use crate::zlib::bufread::ZlibDecoder;
163 pub use crate::zlib::bufread::ZlibEncoder;
164}
165
166fn _assert_send_sync() {
167 fn _assert_send_sync<T: Send + Sync>() {}
168
169 _assert_send_sync::<read::DeflateEncoder<&[u8]>>();
170 _assert_send_sync::<read::DeflateDecoder<&[u8]>>();
171 _assert_send_sync::<read::ZlibEncoder<&[u8]>>();
172 _assert_send_sync::<read::ZlibDecoder<&[u8]>>();
173 _assert_send_sync::<read::GzEncoder<&[u8]>>();
174 _assert_send_sync::<read::GzDecoder<&[u8]>>();
175 _assert_send_sync::<read::MultiGzDecoder<&[u8]>>();
176 _assert_send_sync::<write::DeflateEncoder<Vec<u8>>>();
177 _assert_send_sync::<write::DeflateDecoder<Vec<u8>>>();
178 _assert_send_sync::<write::ZlibEncoder<Vec<u8>>>();
179 _assert_send_sync::<write::ZlibDecoder<Vec<u8>>>();
180 _assert_send_sync::<write::GzEncoder<Vec<u8>>>();
181 _assert_send_sync::<write::GzDecoder<Vec<u8>>>();
182}
183
184/// When compressing data, the compression level can be specified by a value in
185/// this struct.
186#[derive(Copy, Clone, PartialEq, Eq, Debug)]
187pub struct Compression(u32);
188
189impl Compression {
190 /// Creates a new description of the compression level with an explicitly
191 /// specified integer.
192 ///
193 /// The integer here is typically on a scale of 0-9 where 0 means "no
194 /// compression" and 9 means "take as long as you'd like".
195 pub const fn new(level: u32) -> Compression {
196 Compression(level)
197 }
198
199 /// No compression is to be performed, this may actually inflate data
200 /// slightly when encoding.
201 pub const fn none() -> Compression {
202 Compression(0)
203 }
204
205 /// Optimize for the best speed of encoding.
206 pub const fn fast() -> Compression {
207 Compression(1)
208 }
209
210 /// Optimize for the size of data being encoded.
211 pub const fn best() -> Compression {
212 Compression(9)
213 }
214
215 /// Returns an integer representing the compression level, typically on a
216 /// scale of 0-9
217 pub fn level(&self) -> u32 {
218 self.0
219 }
220}
221
222impl Default for Compression {
223 fn default() -> Compression {
224 Compression(6)
225 }
226}
227
228#[cfg(test)]
229fn random_bytes() -> impl Iterator<Item = u8> {
230 use rand::Rng;
231 use std::iter;
232
233 iter::repeat(()).map(|_| rand::thread_rng().gen())
234}
235