1 use std::io;
2 use std::io::prelude::*;
3 
4 use super::bufread;
5 use crate::bufreader::BufReader;
6 use crate::Decompress;
7 
8 /// A ZLIB encoder, or compressor.
9 ///
10 /// This structure implements a [`Read`] interface. When read from, it reads
11 /// uncompressed data from the underlying [`Read`] and provides the compressed data.
12 ///
13 /// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
14 ///
15 /// # Examples
16 ///
17 /// ```
18 /// use std::io::prelude::*;
19 /// use flate2::Compression;
20 /// use flate2::read::ZlibEncoder;
21 /// use std::fs::File;
22 ///
23 /// // Open example file and compress the contents using Read interface
24 ///
25 /// # fn open_hello_world() -> std::io::Result<Vec<u8>> {
26 /// let f = File::open("examples/hello_world.txt")?;
27 /// let mut z = ZlibEncoder::new(f, Compression::fast());
28 /// let mut buffer = Vec::new();
29 /// z.read_to_end(&mut buffer)?;
30 /// # Ok(buffer)
31 /// # }
32 /// ```
33 #[derive(Debug)]
34 pub struct ZlibEncoder<R> {
35     inner: bufread::ZlibEncoder<BufReader<R>>,
36 }
37 
38 impl<R: Read> ZlibEncoder<R> {
39     /// Creates a new encoder which will read uncompressed data from the given
40     /// stream and emit the compressed stream.
new(r: R, level: crate::Compression) -> ZlibEncoder<R>41     pub fn new(r: R, level: crate::Compression) -> ZlibEncoder<R> {
42         ZlibEncoder {
43             inner: bufread::ZlibEncoder::new(BufReader::new(r), level),
44         }
45     }
46 
47     /// Creates a new encoder with the given `compression` settings which will
48     /// read uncompressed data from the given stream `r` and emit the compressed stream.
new_with_compress(r: R, compression: crate::Compress) -> ZlibEncoder<R>49     pub fn new_with_compress(r: R, compression: crate::Compress) -> ZlibEncoder<R> {
50         ZlibEncoder {
51             inner: bufread::ZlibEncoder::new_with_compress(BufReader::new(r), compression),
52         }
53     }
54 }
55 
56 impl<R> ZlibEncoder<R> {
57     /// Resets the state of this encoder entirely, swapping out the input
58     /// stream for another.
59     ///
60     /// This function will reset the internal state of this encoder and replace
61     /// the input stream with the one provided, returning the previous input
62     /// stream. Future data read from this encoder will be the compressed
63     /// version of `r`'s data.
64     ///
65     /// Note that there may be currently buffered data when this function is
66     /// called, and in that case the buffered data is discarded.
reset(&mut self, r: R) -> R67     pub fn reset(&mut self, r: R) -> R {
68         super::bufread::reset_encoder_data(&mut self.inner);
69         self.inner.get_mut().reset(r)
70     }
71 
72     /// Acquires a reference to the underlying stream
get_ref(&self) -> &R73     pub fn get_ref(&self) -> &R {
74         self.inner.get_ref().get_ref()
75     }
76 
77     /// Acquires a mutable reference to the underlying stream
78     ///
79     /// Note that mutation of the stream may result in surprising results if
80     /// this encoder is continued to be used.
get_mut(&mut self) -> &mut R81     pub fn get_mut(&mut self) -> &mut R {
82         self.inner.get_mut().get_mut()
83     }
84 
85     /// Consumes this encoder, returning the underlying reader.
86     ///
87     /// Note that there may be buffered bytes which are not re-acquired as part
88     /// of this transition. It's recommended to only call this function after
89     /// EOF has been reached.
into_inner(self) -> R90     pub fn into_inner(self) -> R {
91         self.inner.into_inner().into_inner()
92     }
93 
94     /// Returns the number of bytes that have been read into this compressor.
95     ///
96     /// Note that not all bytes read from the underlying object may be accounted
97     /// for, there may still be some active buffering.
total_in(&self) -> u6498     pub fn total_in(&self) -> u64 {
99         self.inner.total_in()
100     }
101 
102     /// Returns the number of bytes that the compressor has produced.
103     ///
104     /// Note that not all bytes may have been read yet, some may still be
105     /// buffered.
total_out(&self) -> u64106     pub fn total_out(&self) -> u64 {
107         self.inner.total_out()
108     }
109 }
110 
111 impl<R: Read> Read for ZlibEncoder<R> {
read(&mut self, buf: &mut [u8]) -> io::Result<usize>112     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
113         self.inner.read(buf)
114     }
115 }
116 
117 impl<W: Read + Write> Write for ZlibEncoder<W> {
write(&mut self, buf: &[u8]) -> io::Result<usize>118     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
119         self.get_mut().write(buf)
120     }
121 
flush(&mut self) -> io::Result<()>122     fn flush(&mut self) -> io::Result<()> {
123         self.get_mut().flush()
124     }
125 }
126 
127 /// A ZLIB decoder, or decompressor.
128 ///
129 /// This structure implements a [`Read`] interface. When read from, it reads
130 /// compressed data from the underlying [`Read`] and provides the uncompressed data.
131 ///
132 /// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
133 ///
134 /// # Examples
135 ///
136 /// ```
137 /// use std::io::prelude::*;
138 /// use std::io;
139 /// # use flate2::Compression;
140 /// # use flate2::write::ZlibEncoder;
141 /// use flate2::read::ZlibDecoder;
142 ///
143 /// # fn main() {
144 /// # let mut e = ZlibEncoder::new(Vec::new(), Compression::default());
145 /// # e.write_all(b"Hello World").unwrap();
146 /// # let bytes = e.finish().unwrap();
147 /// # println!("{}", decode_reader(bytes).unwrap());
148 /// # }
149 /// #
150 /// // Uncompresses a Zlib Encoded vector of bytes and returns a string or error
151 /// // Here &[u8] implements Read
152 ///
153 /// fn decode_reader(bytes: Vec<u8>) -> io::Result<String> {
154 ///     let mut z = ZlibDecoder::new(&bytes[..]);
155 ///     let mut s = String::new();
156 ///     z.read_to_string(&mut s)?;
157 ///     Ok(s)
158 /// }
159 /// ```
160 #[derive(Debug)]
161 pub struct ZlibDecoder<R> {
162     inner: bufread::ZlibDecoder<BufReader<R>>,
163 }
164 
165 impl<R: Read> ZlibDecoder<R> {
166     /// Creates a new decoder which will decompress data read from the given
167     /// stream.
new(r: R) -> ZlibDecoder<R>168     pub fn new(r: R) -> ZlibDecoder<R> {
169         ZlibDecoder::new_with_buf(r, vec![0; 32 * 1024])
170     }
171 
172     /// Creates a new decoder which will decompress data read from the given
173     /// stream `r`, using `buf` as backing to speed up reading.
174     ///
175     /// Note that the specified buffer will only be used up to its current
176     /// length. The buffer's capacity will also not grow over time.
new_with_buf(r: R, buf: Vec<u8>) -> ZlibDecoder<R>177     pub fn new_with_buf(r: R, buf: Vec<u8>) -> ZlibDecoder<R> {
178         ZlibDecoder {
179             inner: bufread::ZlibDecoder::new(BufReader::with_buf(buf, r)),
180         }
181     }
182 
183     /// Creates a new decoder which will decompress data read from the given
184     /// stream `r`, along with `decompression` settings.
new_with_decompress(r: R, decompression: Decompress) -> ZlibDecoder<R>185     pub fn new_with_decompress(r: R, decompression: Decompress) -> ZlibDecoder<R> {
186         ZlibDecoder::new_with_decompress_and_buf(r, vec![0; 32 * 1024], decompression)
187     }
188 
189     /// Creates a new decoder which will decompress data read from the given
190     /// stream `r`, using `buf` as backing to speed up reading,
191     /// along with `decompression` settings to configure decoder.
192     ///
193     /// Note that the specified buffer will only be used up to its current
194     /// length. The buffer's capacity will also not grow over time.
new_with_decompress_and_buf( r: R, buf: Vec<u8>, decompression: Decompress, ) -> ZlibDecoder<R>195     pub fn new_with_decompress_and_buf(
196         r: R,
197         buf: Vec<u8>,
198         decompression: Decompress,
199     ) -> ZlibDecoder<R> {
200         ZlibDecoder {
201             inner: bufread::ZlibDecoder::new_with_decompress(
202                 BufReader::with_buf(buf, r),
203                 decompression,
204             ),
205         }
206     }
207 }
208 
209 impl<R> ZlibDecoder<R> {
210     /// Resets the state of this decoder entirely, swapping out the input
211     /// stream for another.
212     ///
213     /// This will reset the internal state of this decoder and replace the
214     /// input stream with the one provided, returning the previous input
215     /// stream. Future data read from this decoder will be the decompressed
216     /// version of `r`'s data.
217     ///
218     /// Note that there may be currently buffered data when this function is
219     /// called, and in that case the buffered data is discarded.
reset(&mut self, r: R) -> R220     pub fn reset(&mut self, r: R) -> R {
221         super::bufread::reset_decoder_data(&mut self.inner);
222         self.inner.get_mut().reset(r)
223     }
224 
225     /// Acquires a reference to the underlying stream
get_ref(&self) -> &R226     pub fn get_ref(&self) -> &R {
227         self.inner.get_ref().get_ref()
228     }
229 
230     /// Acquires a mutable reference to the underlying stream
231     ///
232     /// Note that mutation of the stream may result in surprising results if
233     /// this decoder is continued to be used.
get_mut(&mut self) -> &mut R234     pub fn get_mut(&mut self) -> &mut R {
235         self.inner.get_mut().get_mut()
236     }
237 
238     /// Consumes this decoder, returning the underlying reader.
239     ///
240     /// Note that there may be buffered bytes which are not re-acquired as part
241     /// of this transition. It's recommended to only call this function after
242     /// EOF has been reached.
into_inner(self) -> R243     pub fn into_inner(self) -> R {
244         self.inner.into_inner().into_inner()
245     }
246 
247     /// Returns the number of bytes that the decompressor has consumed.
248     ///
249     /// Note that this will likely be smaller than what the decompressor
250     /// actually read from the underlying stream due to buffering.
total_in(&self) -> u64251     pub fn total_in(&self) -> u64 {
252         self.inner.total_in()
253     }
254 
255     /// Returns the number of bytes that the decompressor has produced.
total_out(&self) -> u64256     pub fn total_out(&self) -> u64 {
257         self.inner.total_out()
258     }
259 }
260 
261 impl<R: Read> Read for ZlibDecoder<R> {
read(&mut self, into: &mut [u8]) -> io::Result<usize>262     fn read(&mut self, into: &mut [u8]) -> io::Result<usize> {
263         self.inner.read(into)
264     }
265 }
266 
267 impl<R: Read + Write> Write for ZlibDecoder<R> {
write(&mut self, buf: &[u8]) -> io::Result<usize>268     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
269         self.get_mut().write(buf)
270     }
271 
flush(&mut self) -> io::Result<()>272     fn flush(&mut self) -> io::Result<()> {
273         self.get_mut().flush()
274     }
275 }
276