1 use std::io;
2 use std::io::prelude::*;
3 use std::mem;
4 
5 use crate::zio;
6 use crate::{Compress, 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 [`BufRead`] and provides the compressed data.
12 ///
13 /// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
14 /// [`BufRead`]: https://doc.rust-lang.org/std/io/trait.BufRead.html
15 ///
16 /// # Examples
17 ///
18 /// ```
19 /// use std::io::prelude::*;
20 /// use flate2::Compression;
21 /// use flate2::bufread::ZlibEncoder;
22 /// use std::fs::File;
23 /// use std::io::BufReader;
24 ///
25 /// // Use a buffered file to compress contents into a Vec<u8>
26 ///
27 /// # fn open_hello_world() -> std::io::Result<Vec<u8>> {
28 /// let f = File::open("examples/hello_world.txt")?;
29 /// let b = BufReader::new(f);
30 /// let mut z = ZlibEncoder::new(b, Compression::fast());
31 /// let mut buffer = Vec::new();
32 /// z.read_to_end(&mut buffer)?;
33 /// # Ok(buffer)
34 /// # }
35 /// ```
36 #[derive(Debug)]
37 pub struct ZlibEncoder<R> {
38     obj: R,
39     data: Compress,
40 }
41 
42 impl<R: BufRead> ZlibEncoder<R> {
43     /// Creates a new encoder which will read uncompressed data from the given
44     /// stream and emit the compressed stream.
new(r: R, level: crate::Compression) -> ZlibEncoder<R>45     pub fn new(r: R, level: crate::Compression) -> ZlibEncoder<R> {
46         ZlibEncoder {
47             obj: r,
48             data: Compress::new(level, true),
49         }
50     }
51 
52     /// Creates a new encoder with the given `compression` settings which will
53     /// read uncompressed data from the given stream `r` and emit the compressed stream.
new_with_compress(r: R, compression: Compress) -> ZlibEncoder<R>54     pub fn new_with_compress(r: R, compression: Compress) -> ZlibEncoder<R> {
55         ZlibEncoder {
56             obj: r,
57             data: compression,
58         }
59     }
60 }
61 
reset_encoder_data<R>(zlib: &mut ZlibEncoder<R>)62 pub fn reset_encoder_data<R>(zlib: &mut ZlibEncoder<R>) {
63     zlib.data.reset()
64 }
65 
66 impl<R> ZlibEncoder<R> {
67     /// Resets the state of this encoder entirely, swapping out the input
68     /// stream for another.
69     ///
70     /// This function will reset the internal state of this encoder and replace
71     /// the input stream with the one provided, returning the previous input
72     /// stream. Future data read from this encoder will be the compressed
73     /// version of `r`'s data.
reset(&mut self, r: R) -> R74     pub fn reset(&mut self, r: R) -> R {
75         reset_encoder_data(self);
76         mem::replace(&mut self.obj, r)
77     }
78 
79     /// Acquires a reference to the underlying reader
get_ref(&self) -> &R80     pub fn get_ref(&self) -> &R {
81         &self.obj
82     }
83 
84     /// Acquires a mutable reference to the underlying stream
85     ///
86     /// Note that mutation of the stream may result in surprising results if
87     /// this encoder is continued to be used.
get_mut(&mut self) -> &mut R88     pub fn get_mut(&mut self) -> &mut R {
89         &mut self.obj
90     }
91 
92     /// Consumes this encoder, returning the underlying reader.
into_inner(self) -> R93     pub fn into_inner(self) -> R {
94         self.obj
95     }
96 
97     /// Returns the number of bytes that have been read into this compressor.
98     ///
99     /// Note that not all bytes read from the underlying object may be accounted
100     /// for, there may still be some active buffering.
total_in(&self) -> u64101     pub fn total_in(&self) -> u64 {
102         self.data.total_in()
103     }
104 
105     /// Returns the number of bytes that the compressor has produced.
106     ///
107     /// Note that not all bytes may have been read yet, some may still be
108     /// buffered.
total_out(&self) -> u64109     pub fn total_out(&self) -> u64 {
110         self.data.total_out()
111     }
112 }
113 
114 impl<R: BufRead> Read for ZlibEncoder<R> {
read(&mut self, buf: &mut [u8]) -> io::Result<usize>115     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
116         zio::read(&mut self.obj, &mut self.data, buf)
117     }
118 }
119 
120 impl<R: BufRead + Write> Write for ZlibEncoder<R> {
write(&mut self, buf: &[u8]) -> io::Result<usize>121     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
122         self.get_mut().write(buf)
123     }
124 
flush(&mut self) -> io::Result<()>125     fn flush(&mut self) -> io::Result<()> {
126         self.get_mut().flush()
127     }
128 }
129 
130 /// A ZLIB decoder, or decompressor.
131 ///
132 /// This structure implements a [`Read`] interface. When read from, it reads
133 /// compressed data from the underlying [`BufRead`] and provides the uncompressed data.
134 ///
135 /// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
136 /// [`BufRead`]: https://doc.rust-lang.org/std/io/trait.BufRead.html
137 ///
138 /// # Examples
139 ///
140 /// ```
141 /// use std::io::prelude::*;
142 /// use std::io;
143 /// # use flate2::Compression;
144 /// # use flate2::write::ZlibEncoder;
145 /// use flate2::bufread::ZlibDecoder;
146 ///
147 /// # fn main() {
148 /// # let mut e = ZlibEncoder::new(Vec::new(), Compression::default());
149 /// # e.write_all(b"Hello World").unwrap();
150 /// # let bytes = e.finish().unwrap();
151 /// # println!("{}", decode_bufreader(bytes).unwrap());
152 /// # }
153 /// #
154 /// // Uncompresses a Zlib Encoded vector of bytes and returns a string or error
155 /// // Here &[u8] implements BufRead
156 ///
157 /// fn decode_bufreader(bytes: Vec<u8>) -> io::Result<String> {
158 ///     let mut z = ZlibDecoder::new(&bytes[..]);
159 ///     let mut s = String::new();
160 ///     z.read_to_string(&mut s)?;
161 ///     Ok(s)
162 /// }
163 /// ```
164 #[derive(Debug)]
165 pub struct ZlibDecoder<R> {
166     obj: R,
167     data: Decompress,
168 }
169 
170 impl<R: BufRead> ZlibDecoder<R> {
171     /// Creates a new decoder which will decompress data read from the given
172     /// stream.
new(r: R) -> ZlibDecoder<R>173     pub fn new(r: R) -> ZlibDecoder<R> {
174         ZlibDecoder {
175             obj: r,
176             data: Decompress::new(true),
177         }
178     }
179 
180     /// Creates a new decoder which will decompress data read from the given
181     /// stream, using the given `decompression` settings.
new_with_decompress(r: R, decompression: Decompress) -> ZlibDecoder<R>182     pub fn new_with_decompress(r: R, decompression: Decompress) -> ZlibDecoder<R> {
183         ZlibDecoder {
184             obj: r,
185             data: decompression,
186         }
187     }
188 }
189 
reset_decoder_data<R>(zlib: &mut ZlibDecoder<R>)190 pub fn reset_decoder_data<R>(zlib: &mut ZlibDecoder<R>) {
191     zlib.data = Decompress::new(true);
192 }
193 
194 impl<R> ZlibDecoder<R> {
195     /// Resets the state of this decoder entirely, swapping out the input
196     /// stream for another.
197     ///
198     /// This will reset the internal state of this decoder and replace the
199     /// input stream with the one provided, returning the previous input
200     /// stream. Future data read from this decoder will be the decompressed
201     /// version of `r`'s data.
reset(&mut self, r: R) -> R202     pub fn reset(&mut self, r: R) -> R {
203         reset_decoder_data(self);
204         mem::replace(&mut self.obj, r)
205     }
206 
207     /// Acquires a reference to the underlying stream
get_ref(&self) -> &R208     pub fn get_ref(&self) -> &R {
209         &self.obj
210     }
211 
212     /// Acquires a mutable reference to the underlying stream
213     ///
214     /// Note that mutation of the stream may result in surprising results if
215     /// this decoder is continued to be used.
get_mut(&mut self) -> &mut R216     pub fn get_mut(&mut self) -> &mut R {
217         &mut self.obj
218     }
219 
220     /// Consumes this decoder, returning the underlying reader.
into_inner(self) -> R221     pub fn into_inner(self) -> R {
222         self.obj
223     }
224 
225     /// Returns the number of bytes that the decompressor has consumed.
226     ///
227     /// Note that this will likely be smaller than what the decompressor
228     /// actually read from the underlying stream due to buffering.
total_in(&self) -> u64229     pub fn total_in(&self) -> u64 {
230         self.data.total_in()
231     }
232 
233     /// Returns the number of bytes that the decompressor has produced.
total_out(&self) -> u64234     pub fn total_out(&self) -> u64 {
235         self.data.total_out()
236     }
237 }
238 
239 impl<R: BufRead> Read for ZlibDecoder<R> {
read(&mut self, into: &mut [u8]) -> io::Result<usize>240     fn read(&mut self, into: &mut [u8]) -> io::Result<usize> {
241         zio::read(&mut self.obj, &mut self.data, into)
242     }
243 }
244 
245 impl<R: BufRead + Write> Write for ZlibDecoder<R> {
write(&mut self, buf: &[u8]) -> io::Result<usize>246     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
247         self.get_mut().write(buf)
248     }
249 
flush(&mut self) -> io::Result<()>250     fn flush(&mut self) -> io::Result<()> {
251         self.get_mut().flush()
252     }
253 }
254