• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use std::io;
2 use std::io::prelude::*;
3 
4 use crate::zio;
5 use 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)]
30 pub struct DeflateEncoder<W: Write> {
31     inner: zio::Writer<W, Compress>,
32 }
33 
34 impl<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.
new(w: W, level: crate::Compression) -> DeflateEncoder<W>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.
get_ref(&self) -> &W47     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.
get_mut(&mut self) -> &mut W55     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.
reset(&mut self, w: W) -> io::Result<W>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.
try_finish(&mut self) -> io::Result<()>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.
finish(mut self) -> io::Result<W>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.
flush_finish(mut self) -> io::Result<W>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.
total_in(&self) -> u64141     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.
total_out(&self) -> u64149     pub fn total_out(&self) -> u64 {
150         self.inner.data.total_out()
151     }
152 }
153 
154 impl<W: Write> Write for DeflateEncoder<W> {
write(&mut self, buf: &[u8]) -> io::Result<usize>155     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
156         self.inner.write(buf)
157     }
158 
flush(&mut self) -> io::Result<()>159     fn flush(&mut self) -> io::Result<()> {
160         self.inner.flush()
161     }
162 }
163 
164 impl<W: Read + Write> Read for DeflateEncoder<W> {
read(&mut self, buf: &mut [u8]) -> io::Result<usize>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 /// After decoding a single member of the DEFLATE data this writer will return the number of bytes up to
176 /// to the end of the DEFLATE member and subsequent writes will return Ok(0) allowing the caller to
177 /// handle any data following the DEFLATE member.
178 ///
179 /// [`Write`]: https://doc.rust-lang.org/std/io/trait.Read.html
180 ///
181 /// # Examples
182 ///
183 /// ```
184 /// use std::io::prelude::*;
185 /// use std::io;
186 /// # use flate2::Compression;
187 /// # use flate2::write::DeflateEncoder;
188 /// use flate2::write::DeflateDecoder;
189 ///
190 /// # fn main() {
191 /// #    let mut e = DeflateEncoder::new(Vec::new(), Compression::default());
192 /// #    e.write_all(b"Hello World").unwrap();
193 /// #    let bytes = e.finish().unwrap();
194 /// #    println!("{}", decode_writer(bytes).unwrap());
195 /// # }
196 /// // Uncompresses a Deflate Encoded vector of bytes and returns a string or error
197 /// // Here Vec<u8> implements Write
198 /// fn decode_writer(bytes: Vec<u8>) -> io::Result<String> {
199 ///    let mut writer = Vec::new();
200 ///    let mut deflater = DeflateDecoder::new(writer);
201 ///    deflater.write_all(&bytes[..])?;
202 ///    writer = deflater.finish()?;
203 ///    let return_string = String::from_utf8(writer).expect("String parsing error");
204 ///    Ok(return_string)
205 /// }
206 /// ```
207 #[derive(Debug)]
208 pub struct DeflateDecoder<W: Write> {
209     inner: zio::Writer<W, Decompress>,
210 }
211 
212 impl<W: Write> DeflateDecoder<W> {
213     /// Creates a new decoder which will write uncompressed data to the stream.
214     ///
215     /// When this encoder is dropped or unwrapped the final pieces of data will
216     /// be flushed.
new(w: W) -> DeflateDecoder<W>217     pub fn new(w: W) -> DeflateDecoder<W> {
218         DeflateDecoder {
219             inner: zio::Writer::new(w, Decompress::new(false)),
220         }
221     }
222 
223     /// Acquires a reference to the underlying writer.
get_ref(&self) -> &W224     pub fn get_ref(&self) -> &W {
225         self.inner.get_ref()
226     }
227 
228     /// Acquires a mutable reference to the underlying writer.
229     ///
230     /// Note that mutating the output/input state of the stream may corrupt this
231     /// object, so care must be taken when using this method.
get_mut(&mut self) -> &mut W232     pub fn get_mut(&mut self) -> &mut W {
233         self.inner.get_mut()
234     }
235 
236     /// Resets the state of this decoder entirely, swapping out the output
237     /// stream for another.
238     ///
239     /// This function will finish encoding the current stream into the current
240     /// output stream before swapping out the two output streams.
241     ///
242     /// This will then reset the internal state of this decoder and replace the
243     /// output stream with the one provided, returning the previous output
244     /// stream. Future data written to this decoder will be decompressed into
245     /// the output stream `w`.
246     ///
247     /// # Errors
248     ///
249     /// This function will perform I/O to finish the stream, and if that I/O
250     /// returns an error then that will be returned from this function.
reset(&mut self, w: W) -> io::Result<W>251     pub fn reset(&mut self, w: W) -> io::Result<W> {
252         self.inner.finish()?;
253         self.inner.data = Decompress::new(false);
254         Ok(self.inner.replace(w))
255     }
256 
257     /// Attempt to finish this output stream, writing out final chunks of data.
258     ///
259     /// Note that this function can only be used once data has finished being
260     /// written to the output stream. After this function is called then further
261     /// calls to `write` may result in a panic.
262     ///
263     /// # Panics
264     ///
265     /// Attempts to write data to this stream may result in a panic after this
266     /// function is called.
267     ///
268     /// # Errors
269     ///
270     /// This function will perform I/O to finish the stream, returning any
271     /// errors which happen.
try_finish(&mut self) -> io::Result<()>272     pub fn try_finish(&mut self) -> io::Result<()> {
273         self.inner.finish()
274     }
275 
276     /// Consumes this encoder, flushing the output stream.
277     ///
278     /// This will flush the underlying data stream and then return the contained
279     /// writer if the flush succeeded.
280     ///
281     /// Note that this function may not be suitable to call in a situation where
282     /// the underlying stream is an asynchronous I/O stream. To finish a stream
283     /// the `try_finish` (or `shutdown`) method should be used instead. To
284     /// re-acquire ownership of a stream it is safe to call this method after
285     /// `try_finish` or `shutdown` has returned `Ok`.
286     ///
287     /// # Errors
288     ///
289     /// This function will perform I/O to complete this stream, and any I/O
290     /// errors which occur will be returned from this function.
finish(mut self) -> io::Result<W>291     pub fn finish(mut self) -> io::Result<W> {
292         self.inner.finish()?;
293         Ok(self.inner.take_inner())
294     }
295 
296     /// Returns the number of bytes that the decompressor has consumed for
297     /// decompression.
298     ///
299     /// Note that this will likely be smaller than the number of bytes
300     /// successfully written to this stream due to internal buffering.
total_in(&self) -> u64301     pub fn total_in(&self) -> u64 {
302         self.inner.data.total_in()
303     }
304 
305     /// Returns the number of bytes that the decompressor has written to its
306     /// output stream.
total_out(&self) -> u64307     pub fn total_out(&self) -> u64 {
308         self.inner.data.total_out()
309     }
310 }
311 
312 impl<W: Write> Write for DeflateDecoder<W> {
write(&mut self, buf: &[u8]) -> io::Result<usize>313     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
314         self.inner.write(buf)
315     }
316 
flush(&mut self) -> io::Result<()>317     fn flush(&mut self) -> io::Result<()> {
318         self.inner.flush()
319     }
320 }
321 
322 impl<W: Read + Write> Read for DeflateDecoder<W> {
read(&mut self, buf: &mut [u8]) -> io::Result<usize>323     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
324         self.inner.get_mut().read(buf)
325     }
326 }
327 
328 #[cfg(test)]
329 mod tests {
330     use super::*;
331     use crate::Compression;
332 
333     const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
334         Hello World Hello World Hello World Hello World Hello World \
335         Hello World Hello World Hello World Hello World Hello World \
336         Hello World Hello World Hello World Hello World Hello World \
337         Hello World Hello World Hello World Hello World Hello World";
338 
339     // DeflateDecoder consumes one zlib archive and then returns 0 for subsequent writes, allowing any
340     // additional data to be consumed by the caller.
341     #[test]
decode_extra_data()342     fn decode_extra_data() {
343         let compressed = {
344             let mut e = DeflateEncoder::new(Vec::new(), Compression::default());
345             e.write(STR.as_ref()).unwrap();
346             let mut b = e.finish().unwrap();
347             b.push(b'x');
348             b
349         };
350 
351         let mut writer = Vec::new();
352         let mut decoder = DeflateDecoder::new(writer);
353         let mut consumed_bytes = 0;
354         loop {
355             let n = decoder.write(&compressed[consumed_bytes..]).unwrap();
356             if n == 0 {
357                 break;
358             }
359             consumed_bytes += n;
360         }
361         writer = decoder.finish().unwrap();
362         let actual = String::from_utf8(writer).expect("String parsing error");
363         assert_eq!(actual, STR);
364         assert_eq!(&compressed[consumed_bytes..], b"x");
365     }
366 }
367