Skip to main content

flate2_expose/deflate/
bufread.rs

1use std::io;
2use std::io::prelude::*;
3use std::mem;
4
5use crate::zio;
6use crate::{Compress, Decompress};
7
8/// A DEFLATE encoder, or compressor.
9///
10/// This structure consumes a [`BufRead`] interface, reading uncompressed data
11/// from the underlying reader, and emitting compressed data.
12///
13/// [`BufRead`]: https://doc.rust-lang.org/std/io/trait.BufRead.html
14///
15/// # Examples
16///
17/// ```
18/// use std::io::prelude::*;
19/// use std::io;
20/// use flate2_expose::Compression;
21/// use flate2_expose::bufread::DeflateEncoder;
22/// use std::fs::File;
23/// use std::io::BufReader;
24///
25/// # fn main() {
26/// #    println!("{:?}", open_hello_world().unwrap());
27/// # }
28/// #
29/// // Opens sample file, compresses the contents and returns a Vector
30/// fn open_hello_world() -> io::Result<Vec<u8>> {
31///    let f = File::open("examples/hello_world.txt")?;
32///    let b = BufReader::new(f);
33///    let mut deflater = DeflateEncoder::new(b, Compression::fast());
34///    let mut buffer = Vec::new();
35///    deflater.read_to_end(&mut buffer)?;
36///    Ok(buffer)
37/// }
38/// ```
39#[derive(Debug)]
40pub struct DeflateEncoder<R> {
41    obj: R,
42    data: Compress,
43}
44
45impl<R: BufRead> DeflateEncoder<R> {
46    /// Creates a new encoder which will read uncompressed data from the given
47    /// stream and emit the compressed stream.
48    pub fn new(r: R, level: crate::Compression) -> DeflateEncoder<R> {
49        DeflateEncoder {
50            obj: r,
51            data: Compress::new(level, false),
52        }
53    }
54}
55
56pub fn reset_encoder_data<R>(zlib: &mut DeflateEncoder<R>) {
57    zlib.data.reset();
58}
59
60impl<R> DeflateEncoder<R> {
61    /// Resets the state of this encoder entirely, swapping out the input
62    /// stream for another.
63    ///
64    /// This function will reset the internal state of this encoder and replace
65    /// the input stream with the one provided, returning the previous input
66    /// stream. Future data read from this encoder will be the compressed
67    /// version of `r`'s data.
68    pub fn reset(&mut self, r: R) -> R {
69        reset_encoder_data(self);
70        mem::replace(&mut self.obj, r)
71    }
72
73    /// Acquires a reference to the underlying reader
74    pub fn get_ref(&self) -> &R {
75        &self.obj
76    }
77
78    /// Acquires a mutable reference to the underlying stream
79    ///
80    /// Note that mutation of the stream may result in surprising results if
81    /// this encoder is continued to be used.
82    pub fn get_mut(&mut self) -> &mut R {
83        &mut self.obj
84    }
85
86    /// Consumes this encoder, returning the underlying reader.
87    pub fn into_inner(self) -> R {
88        self.obj
89    }
90
91    /// Returns the number of bytes that have been read into this compressor.
92    ///
93    /// Note that not all bytes read from the underlying object may be accounted
94    /// for, there may still be some active buffering.
95    pub fn total_in(&self) -> u64 {
96        self.data.total_in()
97    }
98
99    /// Returns the number of bytes that the compressor has produced.
100    ///
101    /// Note that not all bytes may have been read yet, some may still be
102    /// buffered.
103    pub fn total_out(&self) -> u64 {
104        self.data.total_out()
105    }
106}
107
108impl<R: BufRead> Read for DeflateEncoder<R> {
109    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
110        zio::read(&mut self.obj, &mut self.data, buf)
111    }
112}
113
114impl<W: BufRead + Write> Write for DeflateEncoder<W> {
115    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
116        self.get_mut().write(buf)
117    }
118
119    fn flush(&mut self) -> io::Result<()> {
120        self.get_mut().flush()
121    }
122}
123
124/// A DEFLATE decoder, or decompressor.
125///
126/// This structure consumes a [`BufRead`] interface, reading compressed data
127/// from the underlying reader, and emitting uncompressed data.
128///
129/// [`BufRead`]: https://doc.rust-lang.org/std/io/trait.BufRead.html
130///
131/// # Examples
132///
133/// ```
134/// use std::io::prelude::*;
135/// use std::io;
136/// # use flate2_expose::Compression;
137/// # use flate2_expose::write::DeflateEncoder;
138/// use flate2_expose::bufread::DeflateDecoder;
139///
140/// # fn main() {
141/// #    let mut e = DeflateEncoder::new(Vec::new(), Compression::default());
142/// #    e.write_all(b"Hello World").unwrap();
143/// #    let bytes = e.finish().unwrap();
144/// #    println!("{}", decode_reader(bytes).unwrap());
145/// # }
146/// // Uncompresses a Deflate Encoded vector of bytes and returns a string or error
147/// // Here &[u8] implements Read
148/// fn decode_reader(bytes: Vec<u8>) -> io::Result<String> {
149///    let mut deflater = DeflateDecoder::new(&bytes[..]);
150///    let mut s = String::new();
151///    deflater.read_to_string(&mut s)?;
152///    Ok(s)
153/// }
154/// ```
155#[derive(Debug)]
156pub struct DeflateDecoder<R> {
157    obj: R,
158    data: Decompress,
159}
160
161pub fn reset_decoder_data<R>(zlib: &mut DeflateDecoder<R>) {
162    zlib.data = Decompress::new(false);
163}
164
165impl<R: BufRead> DeflateDecoder<R> {
166    /// Creates a new decoder which will decompress data read from the given
167    /// stream.
168    pub fn new(r: R) -> DeflateDecoder<R> {
169        DeflateDecoder {
170            obj: r,
171            data: Decompress::new(false),
172        }
173    }
174}
175
176impl<R> DeflateDecoder<R> {
177    /// Resets the state of this decoder entirely, swapping out the input
178    /// stream for another.
179    ///
180    /// This will reset the internal state of this decoder and replace the
181    /// input stream with the one provided, returning the previous input
182    /// stream. Future data read from this decoder will be the decompressed
183    /// version of `r`'s data.
184    pub fn reset(&mut self, r: R) -> R {
185        reset_decoder_data(self);
186        mem::replace(&mut self.obj, r)
187    }
188
189    /// Resets the state of this decoder's data
190    ///
191    /// This will reset the internal state of this decoder. It will continue
192    /// reading from the same stream.
193    pub fn reset_data(&mut self) {
194        reset_decoder_data(self);
195    }
196
197    /// Acquires a reference to the underlying stream
198    pub fn get_ref(&self) -> &R {
199        &self.obj
200    }
201
202    /// Acquires a mutable reference to the underlying stream
203    ///
204    /// Note that mutation of the stream may result in surprising results if
205    /// this encoder is continued to be used.
206    pub fn get_mut(&mut self) -> &mut R {
207        &mut self.obj
208    }
209
210    /// Consumes this decoder, returning the underlying reader.
211    pub fn into_inner(self) -> R {
212        self.obj
213    }
214
215    /// Returns the number of bytes that the decompressor has consumed.
216    ///
217    /// Note that this will likely be smaller than what the decompressor
218    /// actually read from the underlying stream due to buffering.
219    pub fn total_in(&self) -> u64 {
220        self.data.total_in()
221    }
222
223    /// Returns the number of bytes that the decompressor has produced.
224    pub fn total_out(&self) -> u64 {
225        self.data.total_out()
226    }
227}
228
229impl<R: BufRead> Read for DeflateDecoder<R> {
230    fn read(&mut self, into: &mut [u8]) -> io::Result<usize> {
231        zio::read(&mut self.obj, &mut self.data, into)
232    }
233}
234
235impl<W: BufRead + Write> Write for DeflateDecoder<W> {
236    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
237        self.get_mut().write(buf)
238    }
239
240    fn flush(&mut self) -> io::Result<()> {
241        self.get_mut().flush()
242    }
243}