Skip to main content

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}