Coverage Report

Created: 2026-09-01 07:45

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