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 /// Creates a new encoder which will write compressed data to the stream
48 /// `w` with the given `compression` settings.
49 pub fn new_with_compress(w: W, compression: Compress) -> ZlibEncoder<W> {
50 ZlibEncoder {
51 inner: zio::Writer::new(w, compression),
52 }
53 }
54
55 /// Acquires a reference to the underlying writer.
56 pub fn get_ref(&self) -> &W {
57 self.inner.get_ref()
58 }
59
60 /// Acquires a mutable reference to the underlying writer.
61 ///
62 /// Note that mutating the output/input state of the stream may corrupt this
63 /// object, so care must be taken when using this method.
64 pub fn get_mut(&mut self) -> &mut W {
65 self.inner.get_mut()
66 }
67
68 /// Resets the state of this encoder entirely, swapping out the output
69 /// stream for another.
70 ///
71 /// This function will finish encoding the current stream into the current
72 /// output stream before swapping out the two output streams.
73 ///
74 /// After the current stream has been finished, this will reset the internal
75 /// state of this encoder and replace the output stream with the one
76 /// provided, returning the previous output stream. Future data written to
77 /// this encoder will be the compressed into the stream `w` provided.
78 ///
79 /// # Errors
80 ///
81 /// This function will perform I/O to complete this stream, and any I/O
82 /// errors which occur will be returned from this function.
83 pub fn reset(&mut self, w: W) -> io::Result<W> {
84 self.inner.finish()?;
85 self.inner.data.reset();
86 Ok(self.inner.replace(w))
87 }
88
89 /// Attempt to finish this output stream, writing out final chunks of data.
90 ///
91 /// Note that this function can only be used once data has finished being
92 /// written to the output stream. After this function is called then further
93 /// calls to `write` may result in a panic.
94 ///
95 /// # Panics
96 ///
97 /// Attempts to write data to this stream may result in a panic after this
98 /// function is called.
99 ///
100 /// # Errors
101 ///
102 /// This function will perform I/O to complete this stream, and any I/O
103 /// errors which occur will be returned from this function.
104 pub fn try_finish(&mut self) -> io::Result<()> {
105 self.inner.finish()
106 }
107
108 /// Consumes this encoder, flushing the output stream.
109 ///
110 /// This will flush the underlying data stream, close off the compressed
111 /// stream and, if successful, return the contained writer.
112 ///
113 /// Note that this function may not be suitable to call in a situation where
114 /// the underlying stream is an asynchronous I/O stream. To finish a stream
115 /// the `try_finish` (or `shutdown`) method should be used instead. To
116 /// re-acquire ownership of a stream it is safe to call this method after
117 /// `try_finish` or `shutdown` has returned `Ok`.
118 ///
119 /// # Errors
120 ///
121 /// This function will perform I/O to complete this stream, and any I/O
122 /// errors which occur will be returned from this function.
123 pub fn finish(mut self) -> io::Result<W> {
124 self.inner.finish()?;
125 Ok(self.inner.take_inner())
126 }
127
128 /// Consumes this encoder, flushing the output stream.
129 ///
130 /// This will flush the underlying data stream and then return the contained
131 /// writer if the flush succeeded.
132 /// The compressed stream will not closed but only flushed. This
133 /// means that obtained byte array can by extended by another deflated
134 /// stream. To close the stream add the two bytes 0x3 and 0x0.
135 ///
136 /// # Errors
137 ///
138 /// This function will perform I/O to complete this stream, and any I/O
139 /// errors which occur will be returned from this function.
140 pub fn flush_finish(mut self) -> io::Result<W> {
141 self.inner.flush()?;
142 Ok(self.inner.take_inner())
143 }
144
145 /// Returns the number of bytes that have been written to this compressor.
146 ///
147 /// Note that not all bytes written to this object may be accounted for,
148 /// there may still be some active buffering.
149 pub fn total_in(&self) -> u64 {
150 self.inner.data.total_in()
151 }
152
153 /// Returns the number of bytes that the compressor has produced.
154 ///
155 /// Note that not all bytes may have been written yet, some may still be
156 /// buffered.
157 pub fn total_out(&self) -> u64 {
158 self.inner.data.total_out()
159 }
160}
161
162impl<W: Write> Write for ZlibEncoder<W> {
163 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
164 self.inner.write(buf)
165 }
166
167 fn flush(&mut self) -> io::Result<()> {
168 self.inner.flush()
169 }
170}
171
172impl<W: Read + Write> Read for ZlibEncoder<W> {
173 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
174 self.get_mut().read(buf)
175 }
176}
177
178/// A ZLIB decoder, or decompressor.
179///
180/// This structure implements a [`Write`] and will emit a stream of decompressed
181/// data when fed a stream of compressed data.
182///
183/// [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
184///
185/// # Examples
186///
187/// ```
188/// use std::io::prelude::*;
189/// use std::io;
190/// # use flate2::Compression;
191/// # use flate2::write::ZlibEncoder;
192/// use flate2::write::ZlibDecoder;
193///
194/// # fn main() {
195/// # let mut e = ZlibEncoder::new(Vec::new(), Compression::default());
196/// # e.write_all(b"Hello World").unwrap();
197/// # let bytes = e.finish().unwrap();
198/// # println!("{}", decode_reader(bytes).unwrap());
199/// # }
200/// #
201/// // Uncompresses a Zlib Encoded vector of bytes and returns a string or error
202/// // Here Vec<u8> implements Write
203///
204/// fn decode_reader(bytes: Vec<u8>) -> io::Result<String> {
205/// let mut writer = Vec::new();
206/// let mut z = ZlibDecoder::new(writer);
207/// z.write_all(&bytes[..])?;
208/// writer = z.finish()?;
209/// let return_string = String::from_utf8(writer).expect("String parsing error");
210/// Ok(return_string)
211/// }
212/// ```
213#[derive(Debug)]
214pub struct ZlibDecoder<W: Write> {
215 inner: zio::Writer<W, Decompress>,
216}
217
218impl<W: Write> ZlibDecoder<W> {
219 /// Creates a new decoder which will write uncompressed data to the stream.
220 ///
221 /// When this decoder is dropped or unwrapped the final pieces of data will
222 /// be flushed.
223 pub fn new(w: W) -> ZlibDecoder<W> {
224 ZlibDecoder {
225 inner: zio::Writer::new(w, Decompress::new(true)),
226 }
227 }
228
229 /// Creates a new decoder which will write uncompressed data to the stream `w`
230 /// using the given `decompression` settings.
231 ///
232 /// When this decoder is dropped or unwrapped the final pieces of data will
233 /// be flushed.
234 pub fn new_with_decompress(w: W, decompression: Decompress) -> ZlibDecoder<W> {
235 ZlibDecoder {
236 inner: zio::Writer::new(w, decompression),
237 }
238 }
239
240 /// Acquires a reference to the underlying writer.
241 pub fn get_ref(&self) -> &W {
242 self.inner.get_ref()
243 }
244
245 /// Acquires a mutable reference to the underlying writer.
246 ///
247 /// Note that mutating the output/input state of the stream may corrupt this
248 /// object, so care must be taken when using this method.
249 pub fn get_mut(&mut self) -> &mut W {
250 self.inner.get_mut()
251 }
252
253 /// Resets the state of this decoder entirely, swapping out the output
254 /// stream for another.
255 ///
256 /// This will reset the internal state of this decoder and replace the
257 /// output stream with the one provided, returning the previous output
258 /// stream. Future data written to this decoder will be decompressed into
259 /// the output stream `w`.
260 ///
261 /// # Errors
262 ///
263 /// This function will perform I/O to complete this stream, and any I/O
264 /// errors which occur will be returned from this function.
265 pub fn reset(&mut self, w: W) -> io::Result<W> {
266 self.inner.finish()?;
267 self.inner.data = Decompress::new(true);
268 Ok(self.inner.replace(w))
269 }
270
271 /// Attempt to finish this output stream, writing out final chunks of data.
272 ///
273 /// Note that this function can only be used once data has finished being
274 /// written to the output stream. After this function is called then further
275 /// calls to `write` may result in a panic.
276 ///
277 /// # Panics
278 ///
279 /// Attempts to write data to this stream may result in a panic after this
280 /// function is called.
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 try_finish(&mut self) -> io::Result<()> {
287 self.inner.finish()
288 }
289
290 /// Consumes this encoder, flushing the output stream.
291 ///
292 /// This will flush the underlying data stream and then return the contained
293 /// writer if the flush succeeded.
294 ///
295 /// Note that this function may not be suitable to call in a situation where
296 /// the underlying stream is an asynchronous I/O stream. To finish a stream
297 /// the `try_finish` (or `shutdown`) method should be used instead. To
298 /// re-acquire ownership of a stream it is safe to call this method after
299 /// `try_finish` or `shutdown` has returned `Ok`.
300 ///
301 /// # Errors
302 ///
303 /// This function will perform I/O to complete this stream, and any I/O
304 /// errors which occur will be returned from this function.
305 pub fn finish(mut self) -> io::Result<W> {
306 self.inner.finish()?;
307 Ok(self.inner.take_inner())
308 }
309
310 /// Returns the number of bytes that the decompressor has consumed for
311 /// decompression.
312 ///
313 /// Note that this will likely be smaller than the number of bytes
314 /// successfully written to this stream due to internal buffering.
315 pub fn total_in(&self) -> u64 {
316 self.inner.data.total_in()
317 }
318
319 /// Returns the number of bytes that the decompressor has written to its
320 /// output stream.
321 pub fn total_out(&self) -> u64 {
322 self.inner.data.total_out()
323 }
324}
325
326impl<W: Write> Write for ZlibDecoder<W> {
327 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
328 self.inner.write(buf)
329 }
330
331 fn flush(&mut self) -> io::Result<()> {
332 self.inner.flush()
333 }
334}
335
336impl<W: Read + Write> Read for ZlibDecoder<W> {
337 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
338 self.inner.get_mut().read(buf)
339 }
340}
341