• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use std::io;
2 use std::io::prelude::*;
3 
4 #[cfg(feature = "tokio")]
5 use futures::Poll;
6 #[cfg(feature = "tokio")]
7 use tokio_io::{AsyncRead, AsyncWrite};
8 
9 use crate::zio;
10 use 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)]
35 pub struct DeflateEncoder<W: Write> {
36     inner: zio::Writer<W, Compress>,
37 }
38 
39 impl<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.
new(w: W, level: crate::Compression) -> DeflateEncoder<W>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.
get_ref(&self) -> &W52     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.
get_mut(&mut self) -> &mut W60     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.
reset(&mut self, w: W) -> io::Result<W>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.
try_finish(&mut self) -> io::Result<()>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.
finish(mut self) -> io::Result<W>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.
flush_finish(mut self) -> io::Result<W>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.
total_in(&self) -> u64146     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.
total_out(&self) -> u64154     pub fn total_out(&self) -> u64 {
155         self.inner.data.total_out()
156     }
157 }
158 
159 impl<W: Write> Write for DeflateEncoder<W> {
write(&mut self, buf: &[u8]) -> io::Result<usize>160     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
161         self.inner.write(buf)
162     }
163 
flush(&mut self) -> io::Result<()>164     fn flush(&mut self) -> io::Result<()> {
165         self.inner.flush()
166     }
167 }
168 
169 #[cfg(feature = "tokio")]
170 impl<W: AsyncWrite> AsyncWrite for DeflateEncoder<W> {
shutdown(&mut self) -> Poll<(), io::Error>171     fn shutdown(&mut self) -> Poll<(), io::Error> {
172         self.inner.finish()?;
173         self.inner.get_mut().shutdown()
174     }
175 }
176 
177 impl<W: Read + Write> Read for DeflateEncoder<W> {
read(&mut self, buf: &mut [u8]) -> io::Result<usize>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")]
184 impl<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)]
220 pub struct DeflateDecoder<W: Write> {
221     inner: zio::Writer<W, Decompress>,
222 }
223 
224 impl<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.
new(w: W) -> DeflateDecoder<W>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.
get_ref(&self) -> &W236     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.
get_mut(&mut self) -> &mut W244     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.
reset(&mut self, w: W) -> io::Result<W>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.
try_finish(&mut self) -> io::Result<()>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.
finish(mut self) -> io::Result<W>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.
total_in(&self) -> u64313     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.
total_out(&self) -> u64319     pub fn total_out(&self) -> u64 {
320         self.inner.data.total_out()
321     }
322 }
323 
324 impl<W: Write> Write for DeflateDecoder<W> {
write(&mut self, buf: &[u8]) -> io::Result<usize>325     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
326         self.inner.write(buf)
327     }
328 
flush(&mut self) -> io::Result<()>329     fn flush(&mut self) -> io::Result<()> {
330         self.inner.flush()
331     }
332 }
333 
334 #[cfg(feature = "tokio")]
335 impl<W: AsyncWrite> AsyncWrite for DeflateDecoder<W> {
shutdown(&mut self) -> Poll<(), io::Error>336     fn shutdown(&mut self) -> Poll<(), io::Error> {
337         self.inner.finish()?;
338         self.inner.get_mut().shutdown()
339     }
340 }
341 
342 impl<W: Read + Write> Read for DeflateDecoder<W> {
read(&mut self, buf: &mut [u8]) -> io::Result<usize>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")]
349 impl<W: AsyncRead + AsyncWrite> AsyncRead for DeflateDecoder<W> {}
350