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