Coverage Report

Created: 2026-08-31 06:59

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/write.rs
Line
Count
Source
1
use crate::io;
2
use crate::io::{Read, Write};
3
4
use crate::zio;
5
use crate::{Compress, Decompress};
6
7
/// A DEFLATE encoder, or compressor.
8
///
9
/// This structure implements a [`Write`] interface and takes a stream of
10
/// uncompressed data, writing the compressed data to the wrapped writer.
11
///
12
/// [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
13
///
14
/// # Examples
15
///
16
/// ```
17
/// use std::io::prelude::*;
18
/// use flate2::Compression;
19
/// use flate2::write::DeflateEncoder;
20
///
21
/// // Vec<u8> implements Write to print the compressed bytes of sample string
22
/// # fn main() {
23
///
24
/// let mut e = DeflateEncoder::new(Vec::new(), Compression::default());
25
/// e.write_all(b"Hello World").unwrap();
26
/// println!("{:?}", e.finish().unwrap());
27
/// # }
28
/// ```
29
#[derive(Debug)]
30
pub struct DeflateEncoder<W: Write> {
31
    inner: zio::Writer<W, Compress>,
32
}
33
34
impl<W: Write> DeflateEncoder<W> {
35
    /// Creates a new encoder which will write compressed data to the stream
36
    /// given at the given compression level.
37
    ///
38
    /// When this encoder is dropped or unwrapped the final pieces of data will
39
    /// be flushed.
40
18.5k
    pub fn new(w: W, level: crate::Compression) -> DeflateEncoder<W> {
41
18.5k
        DeflateEncoder {
42
18.5k
            inner: zio::Writer::new(w, Compress::new(level, false)),
43
18.5k
        }
44
18.5k
    }
Unexecuted instantiation: <flate2::deflate::write::DeflateEncoder<_>>::new
<flate2::deflate::write::DeflateEncoder<zip::write::MaybeEncrypted<std::io::cursor::Cursor<&mut [u8]>>>>::new
Line
Count
Source
40
18.5k
    pub fn new(w: W, level: crate::Compression) -> DeflateEncoder<W> {
41
18.5k
        DeflateEncoder {
42
18.5k
            inner: zio::Writer::new(w, Compress::new(level, false)),
43
18.5k
        }
44
18.5k
    }
45
46
    /// Acquires a reference to the underlying writer.
47
0
    pub fn get_ref(&self) -> &W {
48
0
        self.inner.get_ref()
49
0
    }
50
51
    /// Acquires a mutable reference to the underlying writer.
52
    ///
53
    /// The underlying writer may be mutated or replaced as long as this
54
    /// preserves the bytes and ordering of the logical output stream.
55
    /// Concatenate output from each writer to reconstruct the complete stream.
56
    ///
57
    /// Replacing the writer does not require [`flush`](Write::flush). Call it
58
    /// first when all input accepted so far must be decodable without output
59
    /// from later writes. This inserts a sync-flush point and changes the output
60
    /// bitstream. This is useful before applying [`std::mem::take`] to
61
    /// [`get_mut`](Self::get_mut) when forwarding the stream incrementally.
62
    ///
63
    /// To start a new stream, use [`reset`](Self::reset); replacing the writer
64
    /// does not reset this encoder.
65
0
    pub fn get_mut(&mut self) -> &mut W {
66
0
        self.inner.get_mut()
67
0
    }
68
69
    /// Resets the state of this encoder entirely, swapping out the output
70
    /// stream for another.
71
    ///
72
    /// This function will finish encoding the current stream into the current
73
    /// output stream before swapping out the two output streams. If the stream
74
    /// cannot be finished an error is returned.
75
    ///
76
    /// After the current stream has been finished, this will reset the internal
77
    /// state of this encoder and replace the output stream with the one
78
    /// provided, returning the previous output stream. Future data written to
79
    /// this encoder will be the compressed into the stream `w` provided.
80
    ///
81
    /// # Errors
82
    ///
83
    /// This function will perform I/O to complete this stream, and any I/O
84
    /// errors which occur will be returned from this function.
85
0
    pub fn reset(&mut self, w: W) -> io::Result<W> {
86
0
        self.inner.finish()?;
87
0
        self.inner.data.reset();
88
0
        Ok(self.inner.replace(w))
89
0
    }
90
91
    /// Attempt to finish this output stream, writing out final chunks of data.
92
    ///
93
    /// Note that this function can only be used once data has finished being
94
    /// written to the output stream. After this function is called then further
95
    /// calls to `write` may result in a panic.
96
    ///
97
    /// # Panics
98
    ///
99
    /// Attempts to write data to this stream may result in a panic after this
100
    /// function is called.
101
    ///
102
    /// # Errors
103
    ///
104
    /// This function will perform I/O to complete this stream, and any I/O
105
    /// errors which occur will be returned from this function.
106
0
    pub fn try_finish(&mut self) -> io::Result<()> {
107
0
        self.inner.finish()
108
0
    }
109
110
    /// Consumes this encoder, flushing the output stream.
111
    ///
112
    /// This will flush the underlying data stream, close off the compressed
113
    /// stream and, if successful, return the contained writer.
114
    ///
115
    /// Note that this function may not be suitable to call in a situation where
116
    /// the underlying stream is an asynchronous I/O stream. To finish a stream
117
    /// the `try_finish` (or `shutdown`) method should be used instead. To
118
    /// re-acquire ownership of a stream it is safe to call this method after
119
    /// `try_finish` or `shutdown` has returned `Ok`.
120
    ///
121
    /// # Errors
122
    ///
123
    /// This function will perform I/O to complete this stream, and any I/O
124
    /// errors which occur will be returned from this function.
125
18.5k
    pub fn finish(mut self) -> io::Result<W> {
126
18.5k
        self.inner.finish()?;
127
18.5k
        Ok(self.inner.take_inner())
128
18.5k
    }
Unexecuted instantiation: <flate2::deflate::write::DeflateEncoder<_>>::finish
<flate2::deflate::write::DeflateEncoder<zip::write::MaybeEncrypted<std::io::cursor::Cursor<&mut [u8]>>>>::finish
Line
Count
Source
125
18.5k
    pub fn finish(mut self) -> io::Result<W> {
126
18.5k
        self.inner.finish()?;
127
18.5k
        Ok(self.inner.take_inner())
128
18.5k
    }
129
130
    /// Consumes this encoder, flushing the output stream.
131
    ///
132
    /// This will flush the underlying data stream and then return the contained
133
    /// writer if the flush succeeded.
134
    /// The compressed stream will not closed but only flushed. This
135
    /// means that obtained byte array can by extended by another deflated
136
    /// stream. To close the stream add the two bytes 0x3 and 0x0.
137
    ///
138
    /// # Errors
139
    ///
140
    /// This function will perform I/O to complete this stream, and any I/O
141
    /// errors which occur will be returned from this function.
142
0
    pub fn flush_finish(mut self) -> io::Result<W> {
143
0
        self.inner.flush()?;
144
0
        Ok(self.inner.take_inner())
145
0
    }
146
147
    /// Returns the number of bytes that have been written to this compressor.
148
    ///
149
    /// Note that not all bytes written to this object may be accounted for,
150
    /// there may still be some active buffering.
151
0
    pub fn total_in(&self) -> u64 {
152
0
        self.inner.data.total_in()
153
0
    }
154
155
    /// Returns the number of bytes that the compressor has produced.
156
    ///
157
    /// Note that not all bytes may have been written yet, some may still be
158
    /// buffered.
159
0
    pub fn total_out(&self) -> u64 {
160
0
        self.inner.data.total_out()
161
0
    }
162
}
163
164
impl<W: Write> Write for DeflateEncoder<W> {
165
18.5k
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
166
18.5k
        self.inner.write(buf)
167
18.5k
    }
Unexecuted instantiation: <flate2::deflate::write::DeflateEncoder<_> as std::io::Write>::write
<flate2::deflate::write::DeflateEncoder<zip::write::MaybeEncrypted<std::io::cursor::Cursor<&mut [u8]>>> as std::io::Write>::write
Line
Count
Source
165
18.5k
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
166
18.5k
        self.inner.write(buf)
167
18.5k
    }
168
169
0
    fn flush(&mut self) -> io::Result<()> {
170
0
        self.inner.flush()
171
0
    }
Unexecuted instantiation: <flate2::deflate::write::DeflateEncoder<_> as std::io::Write>::flush
Unexecuted instantiation: <flate2::deflate::write::DeflateEncoder<zip::write::MaybeEncrypted<std::io::cursor::Cursor<&mut [u8]>>> as std::io::Write>::flush
172
}
173
174
impl<W: Read + Write> Read for DeflateEncoder<W> {
175
0
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
176
0
        self.inner.get_mut().read(buf)
177
0
    }
178
}
179
180
/// A DEFLATE decoder, or decompressor.
181
///
182
/// This structure implements a [`Write`] and will emit a stream of decompressed
183
/// data when fed a stream of compressed data.
184
///
185
/// After decoding a single member of the DEFLATE data this writer will return the number of bytes up to
186
/// to the end of the DEFLATE member and subsequent writes will return Ok(0) allowing the caller to
187
/// handle any data following the DEFLATE member.
188
///
189
/// [`Write`]: https://doc.rust-lang.org/std/io/trait.Read.html
190
///
191
/// # Examples
192
///
193
/// ```
194
/// use std::io::prelude::*;
195
/// use std::io;
196
/// # use flate2::Compression;
197
/// # use flate2::write::DeflateEncoder;
198
/// use flate2::write::DeflateDecoder;
199
///
200
/// # fn main() {
201
/// #    let mut e = DeflateEncoder::new(Vec::new(), Compression::default());
202
/// #    e.write_all(b"Hello World").unwrap();
203
/// #    let bytes = e.finish().unwrap();
204
/// #    println!("{}", decode_writer(bytes).unwrap());
205
/// # }
206
/// // Uncompresses a Deflate Encoded vector of bytes and returns a string or error
207
/// // Here Vec<u8> implements Write
208
/// fn decode_writer(bytes: Vec<u8>) -> io::Result<String> {
209
///    let mut writer = Vec::new();
210
///    let mut deflater = DeflateDecoder::new(writer);
211
///    deflater.write_all(&bytes[..])?;
212
///    writer = deflater.finish()?;
213
///    let return_string = String::from_utf8(writer).expect("String parsing error");
214
///    Ok(return_string)
215
/// }
216
/// ```
217
#[derive(Debug)]
218
pub struct DeflateDecoder<W: Write> {
219
    inner: zio::Writer<W, Decompress>,
220
}
221
222
impl<W: Write> DeflateDecoder<W> {
223
    /// Creates a new decoder which will write uncompressed data to the stream.
224
    ///
225
    /// When this encoder is dropped or unwrapped the final pieces of data will
226
    /// be flushed.
227
0
    pub fn new(w: W) -> DeflateDecoder<W> {
228
0
        DeflateDecoder {
229
0
            inner: zio::Writer::new(w, Decompress::new(false)),
230
0
        }
231
0
    }
232
233
    /// Acquires a reference to the underlying writer.
234
0
    pub fn get_ref(&self) -> &W {
235
0
        self.inner.get_ref()
236
0
    }
237
238
    /// Acquires a mutable reference to the underlying writer.
239
    ///
240
    /// The underlying writer may be mutated or replaced as long as this
241
    /// preserves the bytes and ordering of the logical output stream.
242
    /// Concatenate output from each writer to reconstruct the complete stream.
243
    ///
244
    /// Replacing the writer does not require [`flush`](Write::flush). Call it
245
    /// first to write all decompressed output currently available to the
246
    /// current writer. This is useful before applying [`std::mem::take`] to
247
    /// [`get_mut`](Self::get_mut) when forwarding output incrementally.
248
    ///
249
    /// To start a new stream, use [`reset`](Self::reset); replacing the writer
250
    /// does not reset this decoder.
251
0
    pub fn get_mut(&mut self) -> &mut W {
252
0
        self.inner.get_mut()
253
0
    }
254
255
    /// Resets the state of this decoder entirely, swapping out the output
256
    /// stream for another.
257
    ///
258
    /// This function will finish encoding the current stream into the current
259
    /// output stream before swapping out the two output streams.
260
    ///
261
    /// This will then reset the internal state of this decoder and replace the
262
    /// output stream with the one provided, returning the previous output
263
    /// stream. Future data written to this decoder will be decompressed into
264
    /// the output stream `w`.
265
    ///
266
    /// # Errors
267
    ///
268
    /// This function will perform I/O to finish the stream, and if that I/O
269
    /// returns an error then that will be returned from this function.
270
0
    pub fn reset(&mut self, w: W) -> io::Result<W> {
271
0
        self.inner.finish()?;
272
0
        self.inner.data = Decompress::new(false);
273
0
        Ok(self.inner.replace(w))
274
0
    }
275
276
    /// Attempt to finish this output stream, writing out final chunks of data.
277
    ///
278
    /// Note that this function can only be used once data has finished being
279
    /// written to the output stream. After this function is called then further
280
    /// calls to `write` may result in a panic.
281
    ///
282
    /// # Panics
283
    ///
284
    /// Attempts to write data to this stream may result in a panic after this
285
    /// function is called.
286
    ///
287
    /// # Errors
288
    ///
289
    /// This function will perform I/O to finish the stream, returning any
290
    /// errors which happen.
291
0
    pub fn try_finish(&mut self) -> io::Result<()> {
292
0
        self.inner.finish()
293
0
    }
294
295
    /// Consumes this encoder, flushing the output stream.
296
    ///
297
    /// This will flush the underlying data stream and then return the contained
298
    /// writer if the flush succeeded.
299
    ///
300
    /// Note that this function may not be suitable to call in a situation where
301
    /// the underlying stream is an asynchronous I/O stream. To finish a stream
302
    /// the `try_finish` (or `shutdown`) method should be used instead. To
303
    /// re-acquire ownership of a stream it is safe to call this method after
304
    /// `try_finish` or `shutdown` has returned `Ok`.
305
    ///
306
    /// # Errors
307
    ///
308
    /// This function will perform I/O to complete this stream, and any I/O
309
    /// errors which occur will be returned from this function.
310
0
    pub fn finish(mut self) -> io::Result<W> {
311
0
        self.inner.finish()?;
312
0
        Ok(self.inner.take_inner())
313
0
    }
314
315
    /// Returns the number of bytes that the decompressor has consumed for
316
    /// decompression.
317
    ///
318
    /// Note that this will likely be smaller than the number of bytes
319
    /// successfully written to this stream due to internal buffering.
320
0
    pub fn total_in(&self) -> u64 {
321
0
        self.inner.data.total_in()
322
0
    }
323
324
    /// Returns the number of bytes that the decompressor has written to its
325
    /// output stream.
326
0
    pub fn total_out(&self) -> u64 {
327
0
        self.inner.data.total_out()
328
0
    }
329
}
330
331
impl<W: Write> Write for DeflateDecoder<W> {
332
0
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
333
0
        self.inner.write(buf)
334
0
    }
335
336
0
    fn flush(&mut self) -> io::Result<()> {
337
0
        self.inner.flush()
338
0
    }
339
}
340
341
impl<W: Read + Write> Read for DeflateDecoder<W> {
342
0
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
343
0
        self.inner.get_mut().read(buf)
344
0
    }
345
}
346
347
#[cfg(test)]
348
mod tests {
349
    use super::*;
350
    use crate::Compression;
351
    use alloc::string::String;
352
    use alloc::vec::Vec;
353
354
    const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
355
        Hello World Hello World Hello World Hello World Hello World \
356
        Hello World Hello World Hello World Hello World Hello World \
357
        Hello World Hello World Hello World Hello World Hello World \
358
        Hello World Hello World Hello World Hello World Hello World";
359
360
    // DeflateDecoder consumes one zlib archive and then returns 0 for subsequent writes, allowing any
361
    // additional data to be consumed by the caller.
362
    #[test]
363
    fn decode_extra_data() {
364
        let compressed = {
365
            let mut e = DeflateEncoder::new(Vec::new(), Compression::default());
366
            e.write_all(STR.as_ref()).unwrap();
367
            let mut b = e.finish().unwrap();
368
            b.push(b'x');
369
            b
370
        };
371
372
        let mut writer = Vec::new();
373
        let mut decoder = DeflateDecoder::new(writer);
374
        let mut consumed_bytes = 0;
375
        loop {
376
            let n = decoder.write(&compressed[consumed_bytes..]).unwrap();
377
            if n == 0 {
378
                break;
379
            }
380
            consumed_bytes += n;
381
        }
382
        writer = decoder.finish().unwrap();
383
        let actual = String::from_utf8(writer).expect("String parsing error");
384
        assert_eq!(actual, STR);
385
        assert_eq!(&compressed[consumed_bytes..], b"x");
386
    }
387
}