flate2/zlib/
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 ZLIB 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::ZlibEncoder;
25///
26/// // Vec<u8> implements Write, assigning the compressed bytes of sample string
27///
28/// # fn zlib_encoding() -> std::io::Result<()> {
29/// let mut e = ZlibEncoder::new(Vec::new(), Compression::default());
30/// e.write_all(b"Hello World")?;
31/// let compressed = e.finish()?;
32/// # Ok(())
33/// # }
34/// ```
35#[derive(Debug)]
36pub struct ZlibEncoder<W: Write> {
37    inner: zio::Writer<W, Compress>,
38}
39
40impl<W: Write> ZlibEncoder<W> {
41    /// Creates a new encoder which will write compressed data to the stream
42    /// given at the given compression level.
43    ///
44    /// When this encoder is dropped or unwrapped the final pieces of data will
45    /// be flushed.
46    pub fn new(w: W, level: crate::Compression) -> ZlibEncoder<W> {
47        ZlibEncoder {
48            inner: zio::Writer::new(w, Compress::new(level, true)),
49        }
50    }
51
52    /// Acquires a reference to the underlying writer.
53    pub fn get_ref(&self) -> &W {
54        self.inner.get_ref()
55    }
56
57    /// Acquires a mutable reference to the underlying writer.
58    ///
59    /// Note that mutating the output/input state of the stream may corrupt this
60    /// object, so care must be taken when using this method.
61    pub fn get_mut(&mut self) -> &mut W {
62        self.inner.get_mut()
63    }
64
65    /// Resets the state of this encoder entirely, swapping out the output
66    /// stream for another.
67    ///
68    /// This function will finish encoding the current stream into the current
69    /// output stream before swapping out the two output streams.
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 ZlibEncoder<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 ZlibEncoder<W> {
171    fn shutdown(&mut self) -> Poll<(), io::Error> {
172        self.try_finish()?;
173        self.get_mut().shutdown()
174    }
175}
176
177impl<W: Read + Write> Read for ZlibEncoder<W> {
178    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
179        self.get_mut().read(buf)
180    }
181}
182
183#[cfg(feature = "tokio")]
184impl<W: AsyncRead + AsyncWrite> AsyncRead for ZlibEncoder<W> {}
185
186/// A ZLIB 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.Write.html
192///
193/// # Examples
194///
195/// ```
196/// use std::io::prelude::*;
197/// use std::io;
198/// # use flate2::Compression;
199/// # use flate2::write::ZlibEncoder;
200/// use flate2::write::ZlibDecoder;
201///
202/// # fn main() {
203/// #    let mut e = ZlibEncoder::new(Vec::new(), Compression::default());
204/// #    e.write_all(b"Hello World").unwrap();
205/// #    let bytes = e.finish().unwrap();
206/// #    println!("{}", decode_reader(bytes).unwrap());
207/// # }
208/// #
209/// // Uncompresses a Zlib Encoded vector of bytes and returns a string or error
210/// // Here Vec<u8> implements Write
211///
212/// fn decode_reader(bytes: Vec<u8>) -> io::Result<String> {
213///    let mut writer = Vec::new();
214///    let mut z = ZlibDecoder::new(writer);
215///    z.write_all(&bytes[..])?;
216///    writer = z.finish()?;
217///    let return_string = String::from_utf8(writer).expect("String parsing error");
218///    Ok(return_string)
219/// }
220/// ```
221#[derive(Debug)]
222pub struct ZlibDecoder<W: Write> {
223    inner: zio::Writer<W, Decompress>,
224}
225
226impl<W: Write> ZlibDecoder<W> {
227    /// Creates a new decoder which will write uncompressed data to the stream.
228    ///
229    /// When this decoder is dropped or unwrapped the final pieces of data will
230    /// be flushed.
231    pub fn new(w: W) -> ZlibDecoder<W> {
232        ZlibDecoder {
233            inner: zio::Writer::new(w, Decompress::new(true)),
234        }
235    }
236
237    /// Acquires a reference to the underlying writer.
238    pub fn get_ref(&self) -> &W {
239        self.inner.get_ref()
240    }
241
242    /// Acquires a mutable reference to the underlying writer.
243    ///
244    /// Note that mutating the output/input state of the stream may corrupt this
245    /// object, so care must be taken when using this method.
246    pub fn get_mut(&mut self) -> &mut W {
247        self.inner.get_mut()
248    }
249
250    /// Resets the state of this decoder entirely, swapping out the output
251    /// stream for another.
252    ///
253    /// This will reset the internal state of this decoder and replace the
254    /// output stream with the one provided, returning the previous output
255    /// stream. Future data written to this decoder will be decompressed into
256    /// the output stream `w`.
257    ///
258    /// # Errors
259    ///
260    /// This function will perform I/O to complete this stream, and any I/O
261    /// errors which occur will be returned from this function.
262    pub fn reset(&mut self, w: W) -> io::Result<W> {
263        self.inner.finish()?;
264        self.inner.data = Decompress::new(true);
265        Ok(self.inner.replace(w))
266    }
267
268    /// Attempt to finish this output stream, writing out final chunks of data.
269    ///
270    /// Note that this function can only be used once data has finished being
271    /// written to the output stream. After this function is called then further
272    /// calls to `write` may result in a panic.
273    ///
274    /// # Panics
275    ///
276    /// Attempts to write data to this stream may result in a panic after this
277    /// function is called.
278    ///
279    /// # Errors
280    ///
281    /// This function will perform I/O to complete this stream, and any I/O
282    /// errors which occur will be returned from this function.
283    pub fn try_finish(&mut self) -> io::Result<()> {
284        self.inner.finish()
285    }
286
287    /// Consumes this encoder, flushing the output stream.
288    ///
289    /// This will flush the underlying data stream and then return the contained
290    /// writer if the flush succeeded.
291    ///
292    /// Note that this function may not be suitable to call in a situation where
293    /// the underlying stream is an asynchronous I/O stream. To finish a stream
294    /// the `try_finish` (or `shutdown`) method should be used instead. To
295    /// re-acquire ownership of a stream it is safe to call this method after
296    /// `try_finish` or `shutdown` has returned `Ok`.
297    ///
298    /// # Errors
299    ///
300    /// This function will perform I/O to complete this stream, and any I/O
301    /// errors which occur will be returned from this function.
302    pub fn finish(mut self) -> io::Result<W> {
303        self.inner.finish()?;
304        Ok(self.inner.take_inner())
305    }
306
307    /// Returns the number of bytes that the decompressor has consumed for
308    /// decompression.
309    ///
310    /// Note that this will likely be smaller than the number of bytes
311    /// successfully written to this stream due to internal buffering.
312    pub fn total_in(&self) -> u64 {
313        self.inner.data.total_in()
314    }
315
316    /// Returns the number of bytes that the decompressor has written to its
317    /// output stream.
318    pub fn total_out(&self) -> u64 {
319        self.inner.data.total_out()
320    }
321}
322
323impl<W: Write> Write for ZlibDecoder<W> {
324    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
325        self.inner.write(buf)
326    }
327
328    fn flush(&mut self) -> io::Result<()> {
329        self.inner.flush()
330    }
331}
332
333#[cfg(feature = "tokio")]
334impl<W: AsyncWrite> AsyncWrite for ZlibDecoder<W> {
335    fn shutdown(&mut self) -> Poll<(), io::Error> {
336        self.inner.finish()?;
337        self.inner.get_mut().shutdown()
338    }
339}
340
341impl<W: Read + Write> Read for ZlibDecoder<W> {
342    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
343        self.inner.get_mut().read(buf)
344    }
345}
346
347#[cfg(feature = "tokio")]
348impl<W: AsyncRead + AsyncWrite> AsyncRead for ZlibDecoder<W> {}