flate2/deflate/
write.rs

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