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//! [`read`]: read/index.html
69//! [`bufread`]: bufread/index.html
70//! [`write`]: write/index.html
71//! [read]: https://doc.rust-lang.org/std/io/trait.Read.html
72//! [write]: https://doc.rust-lang.org/std/io/trait.Write.html
73//! [bufread]: https://doc.rust-lang.org/std/io/trait.BufRead.html
74#![doc(html_root_url = "https://docs.rs/flate2/0.2")]
75#![deny(missing_docs)]
76#![deny(missing_debug_implementations)]
77#![allow(trivial_numeric_casts)]
78#![cfg_attr(test, deny(warnings))]
79#![cfg_attr(docsrs, feature(doc_auto_cfg))]
80
81pub use crate::crc::{Crc, CrcReader, CrcWriter};
82pub use crate::gz::GzBuilder;
83pub use crate::gz::GzHeader;
84pub use crate::mem::{Compress, CompressError, Decompress, DecompressError, Status};
85pub use crate::mem::{FlushCompress, FlushDecompress};
86
87mod bufreader;
88mod crc;
89mod deflate;
90mod ffi;
91mod gz;
92mod mem;
93mod zio;
94mod zlib;
95
96/// Types which operate over [`Read`] streams, both encoders and decoders for
97/// various formats.
98///
99/// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
100pub mod read {
101 pub use crate::deflate::read::DeflateDecoder;
102 pub use crate::deflate::read::DeflateEncoder;
103 pub use crate::gz::read::GzDecoder;
104 pub use crate::gz::read::GzEncoder;
105 pub use crate::gz::read::MultiGzDecoder;
106 pub use crate::zlib::read::ZlibDecoder;
107 pub use crate::zlib::read::ZlibEncoder;
108}
109
110/// Types which operate over [`Write`] streams, both encoders and decoders for
111/// various formats.
112///
113/// [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
114pub mod write {
115 pub use crate::deflate::write::DeflateDecoder;
116 pub use crate::deflate::write::DeflateEncoder;
117 pub use crate::gz::write::GzDecoder;
118 pub use crate::gz::write::GzEncoder;
119 pub use crate::gz::write::MultiGzDecoder;
120 pub use crate::zlib::write::ZlibDecoder;
121 pub use crate::zlib::write::ZlibEncoder;
122}
123
124/// Types which operate over [`BufRead`] streams, both encoders and decoders for
125/// various formats.
126///
127/// [`BufRead`]: https://doc.rust-lang.org/std/io/trait.BufRead.html
128pub mod bufread {
129 pub use crate::deflate::bufread::DeflateDecoder;
130 pub use crate::deflate::bufread::DeflateEncoder;
131 pub use crate::gz::bufread::GzDecoder;
132 pub use crate::gz::bufread::GzEncoder;
133 pub use crate::gz::bufread::MultiGzDecoder;
134 pub use crate::zlib::bufread::ZlibDecoder;
135 pub use crate::zlib::bufread::ZlibEncoder;
136}
137
138fn _assert_send_sync() {
139 fn _assert_send_sync<T: Send + Sync>() {}
140
141 _assert_send_sync::<read::DeflateEncoder<&[u8]>>();
142 _assert_send_sync::<read::DeflateDecoder<&[u8]>>();
143 _assert_send_sync::<read::ZlibEncoder<&[u8]>>();
144 _assert_send_sync::<read::ZlibDecoder<&[u8]>>();
145 _assert_send_sync::<read::GzEncoder<&[u8]>>();
146 _assert_send_sync::<read::GzDecoder<&[u8]>>();
147 _assert_send_sync::<read::MultiGzDecoder<&[u8]>>();
148 _assert_send_sync::<write::DeflateEncoder<Vec<u8>>>();
149 _assert_send_sync::<write::DeflateDecoder<Vec<u8>>>();
150 _assert_send_sync::<write::ZlibEncoder<Vec<u8>>>();
151 _assert_send_sync::<write::ZlibDecoder<Vec<u8>>>();
152 _assert_send_sync::<write::GzEncoder<Vec<u8>>>();
153 _assert_send_sync::<write::GzDecoder<Vec<u8>>>();
154}
155
156/// When compressing data, the compression level can be specified by a value in
157/// this enum.
158#[derive(Copy, Clone, PartialEq, Eq, Debug)]
159pub struct Compression(u32);
160
161impl Compression {
162 /// Creates a new description of the compression level with an explicitly
163 /// specified integer.
164 ///
165 /// The integer here is typically on a scale of 0-9 where 0 means "no
166 /// compression" and 9 means "take as long as you'd like".
167 pub const fn new(level: u32) -> Compression {
168 Compression(level)
169 }
170
171 /// No compression is to be performed, this may actually inflate data
172 /// slightly when encoding.
173 pub const fn none() -> Compression {
174 Compression(0)
175 }
176
177 /// Optimize for the best speed of encoding.
178 pub const fn fast() -> Compression {
179 Compression(1)
180 }
181
182 /// Optimize for the size of data being encoded.
183 pub const fn best() -> Compression {
184 Compression(9)
185 }
186
187 /// Returns an integer representing the compression level, typically on a
188 /// scale of 0-9
189 pub fn level(&self) -> u32 {
190 self.0
191 }
192}
193
194impl Default for Compression {
195 fn default() -> Compression {
196 Compression(6)
197 }
198}
199
200#[cfg(test)]
201fn random_bytes() -> impl Iterator<Item = u8> {
202 use rand::Rng;
203 use std::iter;
204
205 iter::repeat(()).map(|_| rand::thread_rng().gen())
206}
207