Coverage Report

Created: 2026-09-28 07:16

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/flate2-1.1.10/src/zlib/bufread.rs
Line
Count
Source
1
use crate::io;
2
use crate::io::{BufRead, Read, Write};
3
use core::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.
45
0
    pub fn new(r: R, level: crate::Compression) -> ZlibEncoder<R> {
46
0
        ZlibEncoder {
47
0
            obj: r,
48
0
            data: Compress::new(level, true),
49
0
        }
50
0
    }
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.
54
0
    pub fn new_with_compress(r: R, compression: Compress) -> ZlibEncoder<R> {
55
0
        ZlibEncoder {
56
0
            obj: r,
57
0
            data: compression,
58
0
        }
59
0
    }
60
}
61
62
0
pub fn reset_encoder_data<R>(zlib: &mut ZlibEncoder<R>) {
63
0
    zlib.data.reset()
64
0
}
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.
74
0
    pub fn reset(&mut self, r: R) -> R {
75
0
        reset_encoder_data(self);
76
0
        mem::replace(&mut self.obj, r)
77
0
    }
78
79
    /// Acquires a reference to the underlying reader
80
0
    pub fn get_ref(&self) -> &R {
81
0
        &self.obj
82
0
    }
83
84
    /// Acquires a mutable reference to the underlying stream
85
    ///
86
    /// The underlying reader may be mutated as long as its unread input and
87
    /// current position are preserved for subsequent reads by this encoder.
88
    ///
89
    /// To process a new stream, wait for this encoder to reach EOF and use
90
    /// [`reset`](Self::reset); replacing the reader directly does not reset it.
91
0
    pub fn get_mut(&mut self) -> &mut R {
92
0
        &mut self.obj
93
0
    }
94
95
    /// Consumes this encoder, returning the underlying reader.
96
0
    pub fn into_inner(self) -> R {
97
0
        self.obj
98
0
    }
99
100
    /// Returns the number of bytes that have been read into this compressor.
101
    ///
102
    /// Note that not all bytes read from the underlying object may be accounted
103
    /// for, there may still be some active buffering.
104
0
    pub fn total_in(&self) -> u64 {
105
0
        self.data.total_in()
106
0
    }
107
108
    /// Returns the number of bytes that the compressor has produced.
109
    ///
110
    /// Note that not all bytes may have been read yet, some may still be
111
    /// buffered.
112
0
    pub fn total_out(&self) -> u64 {
113
0
        self.data.total_out()
114
0
    }
115
}
116
117
impl<R: BufRead> Read for ZlibEncoder<R> {
118
0
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
119
0
        zio::read(&mut self.obj, &mut self.data, buf)
120
0
    }
121
}
122
123
impl<R: BufRead + Write> Write for ZlibEncoder<R> {
124
0
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
125
0
        self.get_mut().write(buf)
126
0
    }
127
128
0
    fn flush(&mut self) -> io::Result<()> {
129
0
        self.get_mut().flush()
130
0
    }
131
}
132
133
/// A ZLIB decoder, or decompressor.
134
///
135
/// This structure implements a [`Read`] interface. When read from, it reads
136
/// compressed data from the underlying [`BufRead`] and provides the uncompressed data.
137
///
138
/// After reading a single member of the ZLIB data this reader will return
139
/// Ok(0) even if there are more bytes available in the underlying reader.
140
/// If you need the following bytes, call `into_inner()` after Ok(0) to
141
/// recover the underlying reader.
142
///
143
/// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
144
/// [`BufRead`]: https://doc.rust-lang.org/std/io/trait.BufRead.html
145
///
146
/// # Examples
147
///
148
/// ```
149
/// use std::io::prelude::*;
150
/// use std::io;
151
/// # use flate2::Compression;
152
/// # use flate2::write::ZlibEncoder;
153
/// use flate2::bufread::ZlibDecoder;
154
///
155
/// # fn main() {
156
/// # let mut e = ZlibEncoder::new(Vec::new(), Compression::default());
157
/// # e.write_all(b"Hello World").unwrap();
158
/// # let bytes = e.finish().unwrap();
159
/// # println!("{}", decode_bufreader(bytes).unwrap());
160
/// # }
161
/// #
162
/// // Uncompresses a Zlib Encoded vector of bytes and returns a string or error
163
/// // Here &[u8] implements BufRead
164
///
165
/// fn decode_bufreader(bytes: Vec<u8>) -> io::Result<String> {
166
///     let mut z = ZlibDecoder::new(&bytes[..]);
167
///     let mut s = String::new();
168
///     z.read_to_string(&mut s)?;
169
///     Ok(s)
170
/// }
171
/// ```
172
#[derive(Debug)]
173
pub struct ZlibDecoder<R> {
174
    obj: R,
175
    data: Decompress,
176
}
177
178
impl<R: BufRead> ZlibDecoder<R> {
179
    /// Creates a new decoder which will decompress data read from the given
180
    /// stream.
181
0
    pub fn new(r: R) -> ZlibDecoder<R> {
182
0
        ZlibDecoder {
183
0
            obj: r,
184
0
            data: Decompress::new(true),
185
0
        }
186
0
    }
187
188
    /// Creates a new decoder which will decompress data read from the given
189
    /// stream, using the given `decompression` settings.
190
0
    pub fn new_with_decompress(r: R, decompression: Decompress) -> ZlibDecoder<R> {
191
0
        ZlibDecoder {
192
0
            obj: r,
193
0
            data: decompression,
194
0
        }
195
0
    }
196
}
197
198
0
pub fn reset_decoder_data<R>(zlib: &mut ZlibDecoder<R>) {
199
0
    zlib.data.reset(true);
200
0
}
201
202
impl<R> ZlibDecoder<R> {
203
    /// Resets the state of this decoder entirely, swapping out the input
204
    /// stream for another.
205
    ///
206
    /// This will reset the internal state of this decoder and replace the
207
    /// input stream with the one provided, returning the previous input
208
    /// stream. Future data read from this decoder will be the decompressed
209
    /// version of `r`'s data.
210
0
    pub fn reset(&mut self, r: R) -> R {
211
0
        reset_decoder_data(self);
212
0
        mem::replace(&mut self.obj, r)
213
0
    }
214
215
    /// Acquires a reference to the underlying stream
216
0
    pub fn get_ref(&self) -> &R {
217
0
        &self.obj
218
0
    }
219
220
    /// Acquires a mutable reference to the underlying stream
221
    ///
222
    /// The underlying reader may be mutated as long as its unread input and
223
    /// current position are preserved for subsequent reads by this decoder.
224
    ///
225
    /// To process a new stream, wait for this decoder to reach EOF and use
226
    /// [`reset`](Self::reset); replacing the reader directly does not reset it.
227
0
    pub fn get_mut(&mut self) -> &mut R {
228
0
        &mut self.obj
229
0
    }
230
231
    /// Consumes this decoder, returning the underlying reader.
232
0
    pub fn into_inner(self) -> R {
233
0
        self.obj
234
0
    }
235
236
    /// Returns the number of bytes that the decompressor has consumed.
237
    ///
238
    /// Note that this will likely be smaller than what the decompressor
239
    /// actually read from the underlying stream due to buffering.
240
0
    pub fn total_in(&self) -> u64 {
241
0
        self.data.total_in()
242
0
    }
243
244
    /// Returns the number of bytes that the decompressor has produced.
245
0
    pub fn total_out(&self) -> u64 {
246
0
        self.data.total_out()
247
0
    }
248
}
249
250
impl<R: BufRead> Read for ZlibDecoder<R> {
251
0
    fn read(&mut self, into: &mut [u8]) -> io::Result<usize> {
252
0
        zio::read(&mut self.obj, &mut self.data, into)
253
0
    }
254
}
255
256
impl<R: BufRead + Write> Write for ZlibDecoder<R> {
257
0
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
258
0
        self.get_mut().write(buf)
259
0
    }
260
261
0
    fn flush(&mut self) -> io::Result<()> {
262
0
        self.get_mut().flush()
263
0
    }
264
}
265
266
#[cfg(test)]
267
mod test {
268
    use crate::bufread::ZlibDecoder;
269
    use crate::io::{Read, Write};
270
    use crate::zlib::write;
271
    use crate::Compression;
272
    use alloc::vec::Vec;
273
274
    // ZlibDecoder consumes one zlib archive and then returns 0 for subsequent reads, allowing any
275
    // additional data to be consumed by the caller.
276
    #[test]
277
    fn decode_extra_data() {
278
        let expected = "Hello World";
279
280
        let compressed = {
281
            let mut e = write::ZlibEncoder::new(Vec::new(), Compression::default());
282
            e.write_all(expected.as_ref()).unwrap();
283
            let mut b = e.finish().unwrap();
284
            b.push(b'x');
285
            b
286
        };
287
288
        let mut output = Vec::new();
289
        let mut decoder = ZlibDecoder::new(compressed.as_slice());
290
        let decoded_bytes = decoder.read_to_end(&mut output).unwrap();
291
        assert_eq!(decoded_bytes, output.len());
292
        let actual = core::str::from_utf8(&output).expect("String parsing error");
293
        assert_eq!(
294
            actual, expected,
295
            "after decompression we obtain the original input"
296
        );
297
298
        output.clear();
299
        assert_eq!(
300
            decoder.read(&mut output).unwrap(),
301
            0,
302
            "subsequent read of decoder returns 0, but inner reader can return additional data"
303
        );
304
        let mut reader = decoder.into_inner();
305
        assert_eq!(
306
            reader.read_to_end(&mut output).unwrap(),
307
            1,
308
            "extra data is accessible in underlying buf-read"
309
        );
310
        assert_eq!(output, b"x");
311
    }
312
}