Coverage Report

Created: 2025-07-01 06:50

/rust/registry/src/index.crates.io-6f17d22bba15001f/flate2-1.1.2/src/deflate/bufread.rs
Line
Count
Source (jump to first uncovered line)
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 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
    /// Note that mutation of the stream may result in surprising results if
82
    /// this encoder is continued to be used.
83
0
    pub fn get_mut(&mut self) -> &mut R {
84
0
        &mut self.obj
85
0
    }
86
87
    /// Consumes this encoder, returning the underlying reader.
88
0
    pub fn into_inner(self) -> R {
89
0
        self.obj
90
0
    }
91
92
    /// Returns the number of bytes that have been read into this compressor.
93
    ///
94
    /// Note that not all bytes read from the underlying object may be accounted
95
    /// for, there may still be some active buffering.
96
0
    pub fn total_in(&self) -> u64 {
97
0
        self.data.total_in()
98
0
    }
99
100
    /// Returns the number of bytes that the compressor has produced.
101
    ///
102
    /// Note that not all bytes may have been read yet, some may still be
103
    /// buffered.
104
0
    pub fn total_out(&self) -> u64 {
105
0
        self.data.total_out()
106
0
    }
107
}
108
109
impl<R: BufRead> Read for DeflateEncoder<R> {
110
0
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
111
0
        zio::read(&mut self.obj, &mut self.data, buf)
112
0
    }
113
}
114
115
impl<W: BufRead + Write> Write for DeflateEncoder<W> {
116
0
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
117
0
        self.get_mut().write(buf)
118
0
    }
119
120
0
    fn flush(&mut self) -> io::Result<()> {
121
0
        self.get_mut().flush()
122
0
    }
123
}
124
125
/// A DEFLATE decoder, or decompressor.
126
///
127
/// This structure implements a [`Read`] interface. When read from, it reads
128
/// compressed data from the underlying [`BufRead`] and provides the uncompressed data.
129
///
130
/// After reading a single member of the DEFLATE data this reader will return
131
/// Ok(0) even if there are more bytes available in the underlying reader.
132
/// If you need the following bytes, call `into_inner()` after Ok(0) to
133
/// recover the underlying reader.
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::DeflateEncoder;
145
/// use flate2::bufread::DeflateDecoder;
146
///
147
/// # fn main() {
148
/// #    let mut e = DeflateEncoder::new(Vec::new(), Compression::default());
149
/// #    e.write_all(b"Hello World").unwrap();
150
/// #    let bytes = e.finish().unwrap();
151
/// #    println!("{}", decode_reader(bytes).unwrap());
152
/// # }
153
/// // Uncompresses a Deflate Encoded vector of bytes and returns a string or error
154
/// // Here &[u8] implements Read
155
/// fn decode_reader(bytes: Vec<u8>) -> io::Result<String> {
156
///    let mut deflater = DeflateDecoder::new(&bytes[..]);
157
///    let mut s = String::new();
158
///    deflater.read_to_string(&mut s)?;
159
///    Ok(s)
160
/// }
161
/// ```
162
#[derive(Debug)]
163
pub struct DeflateDecoder<R> {
164
    obj: R,
165
    data: Decompress,
166
}
167
168
0
pub fn reset_decoder_data<R>(zlib: &mut DeflateDecoder<R>) {
169
0
    zlib.data = Decompress::new(false);
170
0
}
171
172
impl<R: BufRead> DeflateDecoder<R> {
173
    /// Creates a new decoder which will decompress data read from the given
174
    /// stream.
175
0
    pub fn new(r: R) -> DeflateDecoder<R> {
176
0
        DeflateDecoder {
177
0
            obj: r,
178
0
            data: Decompress::new(false),
179
0
        }
180
0
    }
181
}
182
183
impl<R> DeflateDecoder<R> {
184
    /// Resets the state of this decoder entirely, swapping out the input
185
    /// stream for another.
186
    ///
187
    /// This will reset the internal state of this decoder and replace the
188
    /// input stream with the one provided, returning the previous input
189
    /// stream. Future data read from this decoder will be the decompressed
190
    /// version of `r`'s data.
191
0
    pub fn reset(&mut self, r: R) -> R {
192
0
        reset_decoder_data(self);
193
0
        mem::replace(&mut self.obj, r)
194
0
    }
195
196
    /// Resets the state of this decoder's data
197
    ///
198
    /// This will reset the internal state of this decoder. It will continue
199
    /// reading from the same stream.
200
0
    pub fn reset_data(&mut self) {
201
0
        reset_decoder_data(self);
202
0
    }
203
204
    /// Acquires a reference to the underlying stream
205
0
    pub fn get_ref(&self) -> &R {
206
0
        &self.obj
207
0
    }
208
209
    /// Acquires a mutable reference to the underlying stream
210
    ///
211
    /// Note that mutation of the stream may result in surprising results if
212
    /// this decoder is continued to be used.
213
0
    pub fn get_mut(&mut self) -> &mut R {
214
0
        &mut self.obj
215
0
    }
216
217
    /// Consumes this decoder, returning the underlying reader.
218
0
    pub fn into_inner(self) -> R {
219
0
        self.obj
220
0
    }
221
222
    /// Returns the number of bytes that the decompressor has consumed.
223
    ///
224
    /// Note that this will likely be smaller than what the decompressor
225
    /// actually read from the underlying stream due to buffering.
226
0
    pub fn total_in(&self) -> u64 {
227
0
        self.data.total_in()
228
0
    }
229
230
    /// Returns the number of bytes that the decompressor has produced.
231
0
    pub fn total_out(&self) -> u64 {
232
0
        self.data.total_out()
233
0
    }
234
}
235
236
impl<R: BufRead> Read for DeflateDecoder<R> {
237
0
    fn read(&mut self, into: &mut [u8]) -> io::Result<usize> {
238
0
        zio::read(&mut self.obj, &mut self.data, into)
239
0
    }
240
}
241
242
impl<W: BufRead + Write> Write for DeflateDecoder<W> {
243
0
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
244
0
        self.get_mut().write(buf)
245
0
    }
246
247
0
    fn flush(&mut self) -> io::Result<()> {
248
0
        self.get_mut().flush()
249
0
    }
250
}
251
252
#[cfg(test)]
253
mod test {
254
    use crate::bufread::DeflateDecoder;
255
    use crate::deflate::write;
256
    use crate::Compression;
257
    use std::io::{Read, Write};
258
259
    // DeflateDecoder consumes one deflate archive and then returns 0 for subsequent reads, allowing any
260
    // additional data to be consumed by the caller.
261
    #[test]
262
    fn decode_extra_data() {
263
        let expected = "Hello World";
264
265
        let compressed = {
266
            let mut e = write::DeflateEncoder::new(Vec::new(), Compression::default());
267
            e.write(expected.as_ref()).unwrap();
268
            let mut b = e.finish().unwrap();
269
            b.push(b'x');
270
            b
271
        };
272
273
        let mut output = Vec::new();
274
        let mut decoder = DeflateDecoder::new(compressed.as_slice());
275
        let decoded_bytes = decoder.read_to_end(&mut output).unwrap();
276
        assert_eq!(decoded_bytes, output.len());
277
        let actual = std::str::from_utf8(&output).expect("String parsing error");
278
        assert_eq!(
279
            actual, expected,
280
            "after decompression we obtain the original input"
281
        );
282
283
        output.clear();
284
        assert_eq!(
285
            decoder.read(&mut output).unwrap(),
286
            0,
287
            "subsequent read of decoder returns 0, but inner reader can return additional data"
288
        );
289
        let mut reader = decoder.into_inner();
290
        assert_eq!(
291
            reader.read_to_end(&mut output).unwrap(),
292
            1,
293
            "extra data is accessible in underlying buf-read"
294
        );
295
        assert_eq!(output, b"x");
296
    }
297
}