• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 three 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 //! * `miniz-sys` - when enabled this feature will enable this crate to instead
24 //!   use `miniz.c`, distributed with `miniz-sys`, to implement
25 //!   compression/decompression.
26 //!
27 //! * `zlib` - finally, this feature will enable linking against the `libz`
28 //!   library, typically found on most Linux systems by default. If the library
29 //!   isn't found to already be on the system it will be compiled from source
30 //!   (this is a C library).
31 //!
32 //! There's various tradeoffs associated with each implementation, but in
33 //! general you probably won't have to tweak the defaults. The default choice is
34 //! selected to avoid the need for a C compiler at build time. The `miniz-sys`
35 //! feature is largely a historical artifact at this point and is unlikely to be
36 //! needed, and `zlib` is often useful if you're already using `zlib` for other
37 //! C dependencies. The compression ratios and performance of each of these
38 //! feature should be roughly comparable, but you'll likely want to run your own
39 //! tests if you're curious about the performance.
40 //!
41 //! # Organization
42 //!
43 //! This crate consists mainly of three modules, [`read`], [`write`], and
44 //! [`bufread`]. Each module contains a number of types used to encode and
45 //! decode various streams of data.
46 //!
47 //! All types in the [`write`] module work on instances of [`Write`][write],
48 //! whereas all types in the [`read`] module work on instances of
49 //! [`Read`][read] and [`bufread`] works with [`BufRead`][bufread]. If you
50 //! are decoding directly from a `&[u8]`, use the [`bufread`] types.
51 //!
52 //! ```
53 //! use flate2::write::GzEncoder;
54 //! use flate2::Compression;
55 //! use std::io;
56 //! use std::io::prelude::*;
57 //!
58 //! # fn main() { let _ = run(); }
59 //! # fn run() -> io::Result<()> {
60 //! let mut encoder = GzEncoder::new(Vec::new(), Compression::default());
61 //! encoder.write_all(b"Example")?;
62 //! # Ok(())
63 //! # }
64 //! ```
65 //!
66 //!
67 //! Other various types are provided at the top-level of the crate for
68 //! management and dealing with encoders/decoders. Also note that types which
69 //! operate over a specific trait often implement the mirroring trait as well.
70 //! For example a `flate2::read::DeflateDecoder<T>` *also* implements the
71 //! `Write` trait if `T: Write`. That is, the "dual trait" is forwarded directly
72 //! to the underlying object if available.
73 //!
74 //! [`read`]: read/index.html
75 //! [`bufread`]: bufread/index.html
76 //! [`write`]: write/index.html
77 //! [read]: https://doc.rust-lang.org/std/io/trait.Read.html
78 //! [write]: https://doc.rust-lang.org/std/io/trait.Write.html
79 //! [bufread]: https://doc.rust-lang.org/std/io/trait.BufRead.html
80 //!
81 //! # Async I/O
82 //!
83 //! This crate optionally can support async I/O streams with the [Tokio stack] via
84 //! the `tokio` feature of this crate:
85 //!
86 //! [Tokio stack]: https://tokio.rs/
87 //!
88 //! ```toml
89 //! flate2 = { version = "0.2", features = ["tokio"] }
90 //! ```
91 //!
92 //! All methods are internally capable of working with streams that may return
93 //! [`ErrorKind::WouldBlock`] when they're not ready to perform the particular
94 //! operation.
95 //!
96 //! [`ErrorKind::WouldBlock`]: https://doc.rust-lang.org/std/io/enum.ErrorKind.html
97 //!
98 //! Note that care needs to be taken when using these objects, however. The
99 //! Tokio runtime, in particular, requires that data is fully flushed before
100 //! dropping streams. For compatibility with blocking streams all streams are
101 //! flushed/written when they are dropped, and this is not always a suitable
102 //! time to perform I/O. If I/O streams are flushed before drop, however, then
103 //! these operations will be a noop.
104 #![doc(html_root_url = "https://docs.rs/flate2/0.2")]
105 #![deny(missing_docs)]
106 #![deny(missing_debug_implementations)]
107 #![allow(trivial_numeric_casts)]
108 #![cfg_attr(test, deny(warnings))]
109 
110 pub use crate::crc::{Crc, CrcReader, CrcWriter};
111 pub use crate::gz::GzBuilder;
112 pub use crate::gz::GzHeader;
113 pub use crate::mem::{Compress, CompressError, Decompress, DecompressError, Status};
114 pub use crate::mem::{FlushCompress, FlushDecompress};
115 
116 mod bufreader;
117 mod crc;
118 mod deflate;
119 mod ffi;
120 mod gz;
121 mod mem;
122 mod zio;
123 mod zlib;
124 
125 /// Types which operate over [`Read`] streams, both encoders and decoders for
126 /// various formats.
127 ///
128 /// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
129 pub mod read {
130     pub use crate::deflate::read::DeflateDecoder;
131     pub use crate::deflate::read::DeflateEncoder;
132     pub use crate::gz::read::GzDecoder;
133     pub use crate::gz::read::GzEncoder;
134     pub use crate::gz::read::MultiGzDecoder;
135     pub use crate::zlib::read::ZlibDecoder;
136     pub use crate::zlib::read::ZlibEncoder;
137 }
138 
139 /// Types which operate over [`Write`] streams, both encoders and decoders for
140 /// various formats.
141 ///
142 /// [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
143 pub mod write {
144     pub use crate::deflate::write::DeflateDecoder;
145     pub use crate::deflate::write::DeflateEncoder;
146     pub use crate::gz::write::GzDecoder;
147     pub use crate::gz::write::GzEncoder;
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
156 pub 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 
_assert_send_sync()166 fn _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 enum.
186 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
187 pub struct Compression(u32);
188 
189 impl 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".
new(level: u32) -> Compression195     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.
none() -> Compression201     pub const fn none() -> Compression {
202         Compression(0)
203     }
204 
205     /// Optimize for the best speed of encoding.
fast() -> Compression206     pub const fn fast() -> Compression {
207         Compression(1)
208     }
209 
210     /// Optimize for the size of data being encoded.
best() -> Compression211     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
level(&self) -> u32217     pub fn level(&self) -> u32 {
218         self.0
219     }
220 }
221 
222 impl Default for Compression {
default() -> Compression223     fn default() -> Compression {
224         Compression(6)
225     }
226 }
227 
228 #[cfg(test)]
random_bytes() -> impl Iterator<Item = u8>229 fn 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