• 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 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