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::Compression;
19/// use flate2::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::Compression;
183/// # use flate2::write::ZlibEncoder;
184/// use flate2::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}
322