• 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 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)]
36 pub struct ZlibEncoder<W: Write> {
37     inner: zio::Writer<W, Compress>,
38 }
39 
40 impl<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.
new(w: W, level: crate::Compression) -> ZlibEncoder<W>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.
get_ref(&self) -> &W53     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.
get_mut(&mut self) -> &mut W61     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.
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 ZlibEncoder<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 ZlibEncoder<W> {
shutdown(&mut self) -> Poll<(), io::Error>171     fn shutdown(&mut self) -> Poll<(), io::Error> {
172         self.try_finish()?;
173         self.get_mut().shutdown()
174     }
175 }
176 
177 impl<W: Read + Write> Read for ZlibEncoder<W> {
read(&mut self, buf: &mut [u8]) -> io::Result<usize>178     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
179         self.get_mut().read(buf)
180     }
181 }
182 
183 #[cfg(feature = "tokio")]
184 impl<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)]
222 pub struct ZlibDecoder<W: Write> {
223     inner: zio::Writer<W, Decompress>,
224 }
225 
226 impl<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.
new(w: W) -> ZlibDecoder<W>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.
get_ref(&self) -> &W238     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.
get_mut(&mut self) -> &mut W246     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.
reset(&mut self, w: W) -> io::Result<W>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.
try_finish(&mut self) -> io::Result<()>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.
finish(mut self) -> io::Result<W>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.
total_in(&self) -> u64312     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.
total_out(&self) -> u64318     pub fn total_out(&self) -> u64 {
319         self.inner.data.total_out()
320     }
321 }
322 
323 impl<W: Write> Write for ZlibDecoder<W> {
write(&mut self, buf: &[u8]) -> io::Result<usize>324     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
325         self.inner.write(buf)
326     }
327 
flush(&mut self) -> io::Result<()>328     fn flush(&mut self) -> io::Result<()> {
329         self.inner.flush()
330     }
331 }
332 
333 #[cfg(feature = "tokio")]
334 impl<W: AsyncWrite> AsyncWrite for ZlibDecoder<W> {
shutdown(&mut self) -> Poll<(), io::Error>335     fn shutdown(&mut self) -> Poll<(), io::Error> {
336         self.inner.finish()?;
337         self.inner.get_mut().shutdown()
338     }
339 }
340 
341 impl<W: Read + Write> Read for ZlibDecoder<W> {
read(&mut self, buf: &mut [u8]) -> io::Result<usize>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")]
348 impl<W: AsyncRead + AsyncWrite> AsyncRead for ZlibDecoder<W> {}
349