flate2/deflate/write.rs
1use crate::io;
2use crate::io::{Read, Write};
3
4use crate::zio;
5use crate::{Compress, Decompress};
6
7/// A DEFLATE encoder, or compressor.
8///
9/// This structure implements a [`Write`] interface and takes a stream of
10/// uncompressed data, writing the compressed data to the wrapped writer.
11///
12/// [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
13///
14/// # Examples
15///
16/// ```
17/// use std::io::prelude::*;
18/// use flate2::Compression;
19/// use flate2::write::DeflateEncoder;
20///
21/// // Vec<u8> implements Write to print the compressed bytes of sample string
22/// # fn main() {
23///
24/// let mut e = DeflateEncoder::new(Vec::new(), Compression::default());
25/// e.write_all(b"Hello World").unwrap();
26/// println!("{:?}", e.finish().unwrap());
27/// # }
28/// ```
29#[derive(Debug)]
30pub struct DeflateEncoder<W: Write> {
31 inner: zio::Writer<W, Compress>,
32}
33
34impl<W: Write> DeflateEncoder<W> {
35 /// Creates a new encoder which will write compressed data to the stream
36 /// given at the given compression level.
37 ///
38 /// When this encoder is dropped or unwrapped the final pieces of data will
39 /// be flushed.
40 pub fn new(w: W, level: crate::Compression) -> DeflateEncoder<W> {
41 DeflateEncoder {
42 inner: zio::Writer::new(w, Compress::new(level, false)),
43 }
44 }
45
46 /// Acquires a reference to the underlying writer.
47 pub fn get_ref(&self) -> &W {
48 self.inner.get_ref()
49 }
50
51 /// Acquires a mutable reference to the underlying writer.
52 ///
53 /// The underlying writer may be mutated or replaced as long as this
54 /// preserves the bytes and ordering of the logical output stream.
55 /// Concatenate output from each writer to reconstruct the complete stream.
56 ///
57 /// Replacing the writer does not require [`flush`](Write::flush). Call it
58 /// first when all input accepted so far must be decodable without output
59 /// from later writes. This inserts a sync-flush point and changes the output
60 /// bitstream. This is useful before applying [`std::mem::take`] to
61 /// [`get_mut`](Self::get_mut) when forwarding the stream incrementally.
62 ///
63 /// To start a new stream, use [`reset`](Self::reset); replacing the writer
64 /// does not reset this encoder.
65 pub fn get_mut(&mut self) -> &mut W {
66 self.inner.get_mut()
67 }
68
69 /// Resets the state of this encoder entirely, swapping out the output
70 /// stream for another.
71 ///
72 /// This function will finish encoding the current stream into the current
73 /// output stream before swapping out the two output streams. If the stream
74 /// cannot be finished an error is returned.
75 ///
76 /// After the current stream has been finished, this will reset the internal
77 /// state of this encoder and replace the output stream with the one
78 /// provided, returning the previous output stream. Future data written to
79 /// this encoder will be the compressed into the stream `w` provided.
80 ///
81 /// # Errors
82 ///
83 /// This function will perform I/O to complete this stream, and any I/O
84 /// errors which occur will be returned from this function.
85 pub fn reset(&mut self, w: W) -> io::Result<W> {
86 self.inner.finish()?;
87 self.inner.data.reset();
88 Ok(self.inner.replace(w))
89 }
90
91 /// Attempt to finish this output stream, writing out final chunks of data.
92 ///
93 /// Note that this function can only be used once data has finished being
94 /// written to the output stream. After this function is called then further
95 /// calls to `write` may result in a panic.
96 ///
97 /// # Panics
98 ///
99 /// Attempts to write data to this stream may result in a panic after this
100 /// function is called.
101 ///
102 /// # Errors
103 ///
104 /// This function will perform I/O to complete this stream, and any I/O
105 /// errors which occur will be returned from this function.
106 pub fn try_finish(&mut self) -> io::Result<()> {
107 self.inner.finish()
108 }
109
110 /// Consumes this encoder, flushing the output stream.
111 ///
112 /// This will flush the underlying data stream, close off the compressed
113 /// stream and, if successful, return the contained writer.
114 ///
115 /// Note that this function may not be suitable to call in a situation where
116 /// the underlying stream is an asynchronous I/O stream. To finish a stream
117 /// the `try_finish` (or `shutdown`) method should be used instead. To
118 /// re-acquire ownership of a stream it is safe to call this method after
119 /// `try_finish` or `shutdown` has returned `Ok`.
120 ///
121 /// # Errors
122 ///
123 /// This function will perform I/O to complete this stream, and any I/O
124 /// errors which occur will be returned from this function.
125 pub fn finish(mut self) -> io::Result<W> {
126 self.inner.finish()?;
127 Ok(self.inner.take_inner())
128 }
129
130 /// Consumes this encoder, flushing the output stream.
131 ///
132 /// This will flush the underlying data stream and then return the contained
133 /// writer if the flush succeeded.
134 /// The compressed stream will not closed but only flushed. This
135 /// means that obtained byte array can by extended by another deflated
136 /// stream. To close the stream add the two bytes 0x3 and 0x0.
137 ///
138 /// # Errors
139 ///
140 /// This function will perform I/O to complete this stream, and any I/O
141 /// errors which occur will be returned from this function.
142 pub fn flush_finish(mut self) -> io::Result<W> {
143 self.inner.flush()?;
144 Ok(self.inner.take_inner())
145 }
146
147 /// Returns the number of bytes that have been written to this compressor.
148 ///
149 /// Note that not all bytes written to this object may be accounted for,
150 /// there may still be some active buffering.
151 pub fn total_in(&self) -> u64 {
152 self.inner.data.total_in()
153 }
154
155 /// Returns the number of bytes that the compressor has produced.
156 ///
157 /// Note that not all bytes may have been written yet, some may still be
158 /// buffered.
159 pub fn total_out(&self) -> u64 {
160 self.inner.data.total_out()
161 }
162}
163
164impl<W: Write> Write for DeflateEncoder<W> {
165 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
166 self.inner.write(buf)
167 }
168
169 fn flush(&mut self) -> io::Result<()> {
170 self.inner.flush()
171 }
172}
173
174impl<W: Read + Write> Read for DeflateEncoder<W> {
175 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
176 self.inner.get_mut().read(buf)
177 }
178}
179
180/// A DEFLATE decoder, or decompressor.
181///
182/// This structure implements a [`Write`] and will emit a stream of decompressed
183/// data when fed a stream of compressed data.
184///
185/// After decoding a single member of the DEFLATE data this writer will return the number of bytes up to
186/// to the end of the DEFLATE member and subsequent writes will return Ok(0) allowing the caller to
187/// handle any data following the DEFLATE member.
188///
189/// [`Write`]: https://doc.rust-lang.org/std/io/trait.Read.html
190///
191/// # Examples
192///
193/// ```
194/// use std::io::prelude::*;
195/// use std::io;
196/// # use flate2::Compression;
197/// # use flate2::write::DeflateEncoder;
198/// use flate2::write::DeflateDecoder;
199///
200/// # fn main() {
201/// # let mut e = DeflateEncoder::new(Vec::new(), Compression::default());
202/// # e.write_all(b"Hello World").unwrap();
203/// # let bytes = e.finish().unwrap();
204/// # println!("{}", decode_writer(bytes).unwrap());
205/// # }
206/// // Uncompresses a Deflate Encoded vector of bytes and returns a string or error
207/// // Here Vec<u8> implements Write
208/// fn decode_writer(bytes: Vec<u8>) -> io::Result<String> {
209/// let mut writer = Vec::new();
210/// let mut deflater = DeflateDecoder::new(writer);
211/// deflater.write_all(&bytes[..])?;
212/// writer = deflater.finish()?;
213/// let return_string = String::from_utf8(writer).expect("String parsing error");
214/// Ok(return_string)
215/// }
216/// ```
217#[derive(Debug)]
218pub struct DeflateDecoder<W: Write> {
219 inner: zio::Writer<W, Decompress>,
220}
221
222impl<W: Write> DeflateDecoder<W> {
223 /// Creates a new decoder which will write uncompressed data to the stream.
224 ///
225 /// When this encoder is dropped or unwrapped the final pieces of data will
226 /// be flushed.
227 pub fn new(w: W) -> DeflateDecoder<W> {
228 DeflateDecoder {
229 inner: zio::Writer::new(w, Decompress::new(false)),
230 }
231 }
232
233 /// Acquires a reference to the underlying writer.
234 pub fn get_ref(&self) -> &W {
235 self.inner.get_ref()
236 }
237
238 /// Acquires a mutable reference to the underlying writer.
239 ///
240 /// The underlying writer may be mutated or replaced as long as this
241 /// preserves the bytes and ordering of the logical output stream.
242 /// Concatenate output from each writer to reconstruct the complete stream.
243 ///
244 /// Replacing the writer does not require [`flush`](Write::flush). Call it
245 /// first to write all decompressed output currently available to the
246 /// current writer. This is useful before applying [`std::mem::take`] to
247 /// [`get_mut`](Self::get_mut) when forwarding output incrementally.
248 ///
249 /// To start a new stream, use [`reset`](Self::reset); replacing the writer
250 /// does not reset this decoder.
251 pub fn get_mut(&mut self) -> &mut W {
252 self.inner.get_mut()
253 }
254
255 /// Resets the state of this decoder entirely, swapping out the output
256 /// stream for another.
257 ///
258 /// This function will finish encoding the current stream into the current
259 /// output stream before swapping out the two output streams.
260 ///
261 /// This will then reset the internal state of this decoder and replace the
262 /// output stream with the one provided, returning the previous output
263 /// stream. Future data written to this decoder will be decompressed into
264 /// the output stream `w`.
265 ///
266 /// # Errors
267 ///
268 /// This function will perform I/O to finish the stream, and if that I/O
269 /// returns an error then that will be returned from this function.
270 pub fn reset(&mut self, w: W) -> io::Result<W> {
271 self.inner.finish()?;
272 self.inner.data = Decompress::new(false);
273 Ok(self.inner.replace(w))
274 }
275
276 /// Attempt to finish this output stream, writing out final chunks of data.
277 ///
278 /// Note that this function can only be used once data has finished being
279 /// written to the output stream. After this function is called then further
280 /// calls to `write` may result in a panic.
281 ///
282 /// # Panics
283 ///
284 /// Attempts to write data to this stream may result in a panic after this
285 /// function is called.
286 ///
287 /// # Errors
288 ///
289 /// This function will perform I/O to finish the stream, returning any
290 /// errors which happen.
291 pub fn try_finish(&mut self) -> io::Result<()> {
292 self.inner.finish()
293 }
294
295 /// Consumes this encoder, flushing the output stream.
296 ///
297 /// This will flush the underlying data stream and then return the contained
298 /// writer if the flush succeeded.
299 ///
300 /// Note that this function may not be suitable to call in a situation where
301 /// the underlying stream is an asynchronous I/O stream. To finish a stream
302 /// the `try_finish` (or `shutdown`) method should be used instead. To
303 /// re-acquire ownership of a stream it is safe to call this method after
304 /// `try_finish` or `shutdown` has returned `Ok`.
305 ///
306 /// # Errors
307 ///
308 /// This function will perform I/O to complete this stream, and any I/O
309 /// errors which occur will be returned from this function.
310 pub fn finish(mut self) -> io::Result<W> {
311 self.inner.finish()?;
312 Ok(self.inner.take_inner())
313 }
314
315 /// Returns the number of bytes that the decompressor has consumed for
316 /// decompression.
317 ///
318 /// Note that this will likely be smaller than the number of bytes
319 /// successfully written to this stream due to internal buffering.
320 pub fn total_in(&self) -> u64 {
321 self.inner.data.total_in()
322 }
323
324 /// Returns the number of bytes that the decompressor has written to its
325 /// output stream.
326 pub fn total_out(&self) -> u64 {
327 self.inner.data.total_out()
328 }
329}
330
331impl<W: Write> Write for DeflateDecoder<W> {
332 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
333 self.inner.write(buf)
334 }
335
336 fn flush(&mut self) -> io::Result<()> {
337 self.inner.flush()
338 }
339}
340
341impl<W: Read + Write> Read for DeflateDecoder<W> {
342 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
343 self.inner.get_mut().read(buf)
344 }
345}
346
347#[cfg(test)]
348mod tests {
349 use super::*;
350 use crate::Compression;
351 use alloc::string::String;
352 use alloc::vec::Vec;
353
354 const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
355 Hello World Hello World Hello World Hello World Hello World \
356 Hello World Hello World Hello World Hello World Hello World \
357 Hello World Hello World Hello World Hello World Hello World \
358 Hello World Hello World Hello World Hello World Hello World";
359
360 // DeflateDecoder consumes one zlib archive and then returns 0 for subsequent writes, allowing any
361 // additional data to be consumed by the caller.
362 #[test]
363 fn decode_extra_data() {
364 let compressed = {
365 let mut e = DeflateEncoder::new(Vec::new(), Compression::default());
366 e.write_all(STR.as_ref()).unwrap();
367 let mut b = e.finish().unwrap();
368 b.push(b'x');
369 b
370 };
371
372 let mut writer = Vec::new();
373 let mut decoder = DeflateDecoder::new(writer);
374 let mut consumed_bytes = 0;
375 loop {
376 let n = decoder.write(&compressed[consumed_bytes..]).unwrap();
377 if n == 0 {
378 break;
379 }
380 consumed_bytes += n;
381 }
382 writer = decoder.finish().unwrap();
383 let actual = String::from_utf8(writer).expect("String parsing error");
384 assert_eq!(actual, STR);
385 assert_eq!(&compressed[consumed_bytes..], b"x");
386 }
387}