Coverage Report

Created: 2025-07-18 06:49

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