]>
Commit | Line | Data |
---|---|---|
7cac9316 XL |
1 | //! A DEFLATE-based stream compression/decompression library |
2 | //! | |
60c5eb7d XL |
3 | //! This library provides support for compression and decompression of |
4 | //! DEFLATE-based streams: | |
7cac9316 | 5 | //! |
60c5eb7d XL |
6 | //! * the DEFLATE format itself |
7 | //! * the zlib format | |
8 | //! * gzip | |
7cac9316 | 9 | //! |
60c5eb7d XL |
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. | |
7cac9316 XL |
40 | //! |
41 | //! # Organization | |
42 | //! | |
ff7c6d11 XL |
43 | //! This crate consists mainly of three modules, [`read`], [`write`], and |
44 | //! [`bufread`]. Each module contains a number of types used to encode and | |
0bf4aa26 XL |
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. | |
ea8adc8c XL |
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<()> { | |
ff7c6d11 | 60 | //! let mut encoder = GzEncoder::new(Vec::new(), Compression::default()); |
b7449926 | 61 | //! encoder.write_all(b"Example")?; |
ea8adc8c XL |
62 | //! # Ok(()) |
63 | //! # } | |
64 | //! ``` | |
65 | //! | |
7cac9316 XL |
66 | //! |
67 | //! Other various types are provided at the top-level of the crate for | |
ff7c6d11 XL |
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. | |
7cac9316 | 73 | //! |
ea8adc8c | 74 | //! [`read`]: read/index.html |
ff7c6d11 | 75 | //! [`bufread`]: bufread/index.html |
ea8adc8c | 76 | //! [`write`]: write/index.html |
ff7c6d11 XL |
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 | |
ea8adc8c | 80 | //! |
7cac9316 XL |
81 | //! # Async I/O |
82 | //! | |
ea8adc8c | 83 | //! This crate optionally can support async I/O streams with the [Tokio stack] via |
7cac9316 XL |
84 | //! the `tokio` feature of this crate: |
85 | //! | |
ea8adc8c XL |
86 | //! [Tokio stack]: https://tokio.rs/ |
87 | //! | |
7cac9316 XL |
88 | //! ```toml |
89 | //! flate2 = { version = "0.2", features = ["tokio"] } | |
90 | //! ``` | |
91 | //! | |
92 | //! All methods are internally capable of working with streams that may return | |
ea8adc8c | 93 | //! [`ErrorKind::WouldBlock`] when they're not ready to perform the particular |
7cac9316 XL |
94 | //! operation. |
95 | //! | |
ea8adc8c XL |
96 | //! [`ErrorKind::WouldBlock`]: https://doc.rust-lang.org/std/io/enum.ErrorKind.html |
97 | //! | |
7cac9316 XL |
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. | |
7cac9316 XL |
104 | #![doc(html_root_url = "https://docs.rs/flate2/0.2")] |
105 | #![deny(missing_docs)] | |
ea8adc8c | 106 | #![deny(missing_debug_implementations)] |
7cac9316 XL |
107 | #![allow(trivial_numeric_casts)] |
108 | #![cfg_attr(test, deny(warnings))] | |
109 | ||
60c5eb7d XL |
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}; | |
7cac9316 XL |
115 | |
116 | mod bufreader; | |
117 | mod crc; | |
118 | mod deflate; | |
119 | mod ffi; | |
120 | mod gz; | |
7cac9316 | 121 | mod mem; |
60c5eb7d | 122 | mod zio; |
7cac9316 XL |
123 | mod zlib; |
124 | ||
ea8adc8c | 125 | /// Types which operate over [`Read`] streams, both encoders and decoders for |
7cac9316 | 126 | /// various formats. |
ea8adc8c XL |
127 | /// |
128 | /// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html | |
7cac9316 | 129 | pub mod read { |
60c5eb7d XL |
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; | |
7cac9316 XL |
137 | } |
138 | ||
ea8adc8c | 139 | /// Types which operate over [`Write`] streams, both encoders and decoders for |
7cac9316 | 140 | /// various formats. |
ea8adc8c XL |
141 | /// |
142 | /// [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html | |
7cac9316 | 143 | pub mod write { |
60c5eb7d XL |
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; | |
7cac9316 XL |
150 | } |
151 | ||
ea8adc8c | 152 | /// Types which operate over [`BufRead`] streams, both encoders and decoders for |
7cac9316 | 153 | /// various formats. |
ea8adc8c XL |
154 | /// |
155 | /// [`BufRead`]: https://doc.rust-lang.org/std/io/trait.BufRead.html | |
7cac9316 | 156 | pub mod bufread { |
60c5eb7d XL |
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; | |
7cac9316 XL |
164 | } |
165 | ||
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>>>(); | |
b7449926 | 181 | _assert_send_sync::<write::GzDecoder<Vec<u8>>>(); |
7cac9316 XL |
182 | } |
183 | ||
184 | /// When compressing data, the compression level can be specified by a value in | |
185 | /// this enum. | |
ea8adc8c | 186 | #[derive(Copy, Clone, PartialEq, Eq, Debug)] |
ff7c6d11 XL |
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". | |
195 | pub fn new(level: u32) -> Compression { | |
196 | Compression(level) | |
ea8adc8c | 197 | } |
ea8adc8c | 198 | |
ff7c6d11 XL |
199 | /// No compression is to be performed, this may actually inflate data |
200 | /// slightly when encoding. | |
201 | pub fn none() -> Compression { | |
202 | Compression(0) | |
7cac9316 XL |
203 | } |
204 | ||
ff7c6d11 XL |
205 | /// Optimize for the best speed of encoding. |
206 | pub fn fast() -> Compression { | |
207 | Compression(1) | |
7cac9316 XL |
208 | } |
209 | ||
ff7c6d11 XL |
210 | /// Optimize for the size of data being encoded. |
211 | pub fn best() -> Compression { | |
212 | Compression(9) | |
7cac9316 XL |
213 | } |
214 | ||
ff7c6d11 XL |
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 | |
7cac9316 XL |
219 | } |
220 | } | |
221 | ||
ff7c6d11 XL |
222 | impl Default for Compression { |
223 | fn default() -> Compression { | |
224 | Compression(6) | |
7cac9316 XL |
225 | } |
226 | } | |
b7449926 XL |
227 | |
228 | #[cfg(test)] | |
229 | fn random_bytes() -> impl Iterator<Item = u8> { | |
b7449926 | 230 | use rand::Rng; |
60c5eb7d | 231 | use std::iter; |
b7449926 XL |
232 | |
233 | iter::repeat(()).map(|_| rand::thread_rng().gen()) | |
234 | } |