Skip to main content

flate2_expose/deflate/
write.rs

1use std::io;
2use std::io::prelude::*;
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_expose::Compression;
19/// use flate2_expose::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    /// Note that mutating the output/input state of the stream may corrupt this
54    /// object, so care must be taken when using this method.
55    pub fn get_mut(&mut self) -> &mut W {
56        self.inner.get_mut()
57    }
58
59    /// Resets the state of this encoder entirely, swapping out the output
60    /// stream for another.
61    ///
62    /// This function will finish encoding the current stream into the current
63    /// output stream before swapping out the two output streams. If the stream
64    /// cannot be finished an error is returned.
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 DeflateEncoder<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 DeflateEncoder<W> {
165    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
166        self.inner.get_mut().read(buf)
167    }
168}
169
170/// A DEFLATE 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.Read.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::DeflateEncoder;
184/// use flate2_expose::write::DeflateDecoder;
185///
186/// # fn main() {
187/// #    let mut e = DeflateEncoder::new(Vec::new(), Compression::default());
188/// #    e.write_all(b"Hello World").unwrap();
189/// #    let bytes = e.finish().unwrap();
190/// #    println!("{}", decode_writer(bytes).unwrap());
191/// # }
192/// // Uncompresses a Deflate Encoded vector of bytes and returns a string or error
193/// // Here Vec<u8> implements Write
194/// fn decode_writer(bytes: Vec<u8>) -> io::Result<String> {
195///    let mut writer = Vec::new();
196///    let mut deflater = DeflateDecoder::new(writer);
197///    deflater.write_all(&bytes[..])?;
198///    writer = deflater.finish()?;
199///    let return_string = String::from_utf8(writer).expect("String parsing error");
200///    Ok(return_string)
201/// }
202/// ```
203#[derive(Debug)]
204pub struct DeflateDecoder<W: Write> {
205    inner: zio::Writer<W, Decompress>,
206}
207
208impl<W: Write> DeflateDecoder<W> {
209    /// Creates a new decoder which will write uncompressed data to the stream.
210    ///
211    /// When this encoder is dropped or unwrapped the final pieces of data will
212    /// be flushed.
213    pub fn new(w: W) -> DeflateDecoder<W> {
214        DeflateDecoder {
215            inner: zio::Writer::new(w, Decompress::new(false)),
216        }
217    }
218
219    /// Acquires a reference to the underlying writer.
220    pub fn get_ref(&self) -> &W {
221        self.inner.get_ref()
222    }
223
224    /// Acquires a mutable reference to the underlying writer.
225    ///
226    /// Note that mutating the output/input state of the stream may corrupt this
227    /// object, so care must be taken when using this method.
228    pub fn get_mut(&mut self) -> &mut W {
229        self.inner.get_mut()
230    }
231
232    /// Resets the state of this decoder entirely, swapping out the output
233    /// stream for another.
234    ///
235    /// This function will finish encoding the current stream into the current
236    /// output stream before swapping out the two output streams.
237    ///
238    /// This will then reset the internal state of this decoder and replace the
239    /// output stream with the one provided, returning the previous output
240    /// stream. Future data written to this decoder will be decompressed into
241    /// the output stream `w`.
242    ///
243    /// # Errors
244    ///
245    /// This function will perform I/O to finish the stream, and if that I/O
246    /// returns an error then that will be returned from this function.
247    pub fn reset(&mut self, w: W) -> io::Result<W> {
248        self.inner.finish()?;
249        self.inner.data = Decompress::new(false);
250        Ok(self.inner.replace(w))
251    }
252
253    /// Attempt to finish this output stream, writing out final chunks of data.
254    ///
255    /// Note that this function can only be used once data has finished being
256    /// written to the output stream. After this function is called then further
257    /// calls to `write` may result in a panic.
258    ///
259    /// # Panics
260    ///
261    /// Attempts to write data to this stream may result in a panic after this
262    /// function is called.
263    ///
264    /// # Errors
265    ///
266    /// This function will perform I/O to finish the stream, returning any
267    /// errors which happen.
268    pub fn try_finish(&mut self) -> io::Result<()> {
269        self.inner.finish()
270    }
271
272    /// Consumes this encoder, flushing the output stream.
273    ///
274    /// This will flush the underlying data stream and then return the contained
275    /// writer if the flush succeeded.
276    ///
277    /// Note that this function may not be suitable to call in a situation where
278    /// the underlying stream is an asynchronous I/O stream. To finish a stream
279    /// the `try_finish` (or `shutdown`) method should be used instead. To
280    /// re-acquire ownership of a stream it is safe to call this method after
281    /// `try_finish` or `shutdown` has returned `Ok`.
282    ///
283    /// # Errors
284    ///
285    /// This function will perform I/O to complete this stream, and any I/O
286    /// errors which occur will be returned from this function.
287    pub fn finish(mut self) -> io::Result<W> {
288        self.inner.finish()?;
289        Ok(self.inner.take_inner())
290    }
291
292    /// Returns the number of bytes that the decompressor has consumed for
293    /// decompression.
294    ///
295    /// Note that this will likely be smaller than the number of bytes
296    /// successfully written to this stream due to internal buffering.
297    pub fn total_in(&self) -> u64 {
298        self.inner.data.total_in()
299    }
300
301    /// Returns the number of bytes that the decompressor has written to its
302    /// output stream.
303    pub fn total_out(&self) -> u64 {
304        self.inner.data.total_out()
305    }
306}
307
308impl<W: Write> Write for DeflateDecoder<W> {
309    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
310        self.inner.write(buf)
311    }
312
313    fn flush(&mut self) -> io::Result<()> {
314        self.inner.flush()
315    }
316}
317
318impl<W: Read + Write> Read for DeflateDecoder<W> {
319    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
320        self.inner.get_mut().read(buf)
321    }
322}