flate2_expose/zlib/
write.rs

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