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