buffered_reader/
decompress_deflate.rs

1use std::io;
2use std::fmt;
3
4use flate2::read::DeflateDecoder;
5use flate2::read::ZlibDecoder;
6
7use super::*;
8
9/// Decompresses the underlying `BufferedReader` using the deflate
10/// algorithm.
11#[derive(Debug)]
12pub struct Deflate<R: BufferedReader<C>, C: fmt::Debug + Sync + Send> {
13    reader: Generic<DeflateDecoder<R>, C>,
14}
15
16assert_send_and_sync!(Deflate<R, C>
17                      where R: BufferedReader<C>,
18                            C: fmt::Debug);
19
20impl <R: BufferedReader<()>> Deflate<R, ()> {
21    /// Instantiates a new deflate decompression reader.
22    ///
23    /// `reader` is the source to wrap.
24    pub fn new(reader: R) -> Self {
25        Self::with_cookie(reader, ())
26    }
27}
28
29impl <R: BufferedReader<C>, C: fmt::Debug + Sync + Send> Deflate<R, C> {
30    /// Like [`Self::new`], but uses a cookie.
31    ///
32    /// The cookie can be retrieved using the [`BufferedReader::cookie_ref`] and
33    /// [`BufferedReader::cookie_mut`] methods, and set using the [`BufferedReader::cookie_set`] method.
34    pub fn with_cookie(reader: R, cookie: C) -> Self {
35        Deflate {
36            reader: Generic::with_cookie(
37                DeflateDecoder::new(reader), None, cookie),
38        }
39    }
40}
41
42impl<R: BufferedReader<C>, C: fmt::Debug + Sync + Send> io::Read for Deflate<R, C> {
43    fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
44        self.reader.read(buf)
45    }
46}
47
48impl<R: BufferedReader<C>, C: fmt::Debug + Sync + Send> fmt::Display for Deflate<R, C> {
49    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
50        f.debug_struct("Deflate").finish()
51    }
52}
53
54impl<R: BufferedReader<C>, C: fmt::Debug + Send + Sync> BufferedReader<C>
55        for Deflate<R, C> {
56    fn buffer(&self) -> &[u8] {
57        self.reader.buffer()
58    }
59
60    fn data(&mut self, amount: usize) -> Result<&[u8], io::Error> {
61        self.reader.data(amount)
62    }
63
64    fn data_hard(&mut self, amount: usize) -> Result<&[u8], io::Error> {
65        self.reader.data_hard(amount)
66    }
67
68    fn data_eof(&mut self) -> Result<&[u8], io::Error> {
69        self.reader.data_eof()
70    }
71
72    fn consume(&mut self, amount: usize) -> &[u8] {
73        self.reader.consume(amount)
74    }
75
76    fn data_consume(&mut self, amount: usize)
77                    -> Result<&[u8], io::Error> {
78        self.reader.data_consume(amount)
79    }
80
81    fn data_consume_hard(&mut self, amount: usize) -> Result<&[u8], io::Error> {
82        self.reader.data_consume_hard(amount)
83    }
84
85    fn read_be_u16(&mut self) -> Result<u16, io::Error> {
86        self.reader.read_be_u16()
87    }
88
89    fn read_be_u32(&mut self) -> Result<u32, io::Error> {
90        self.reader.read_be_u32()
91    }
92
93    fn steal(&mut self, amount: usize) -> Result<Vec<u8>, io::Error> {
94        self.reader.steal(amount)
95    }
96
97    fn steal_eof(&mut self) -> Result<Vec<u8>, io::Error> {
98        self.reader.steal_eof()
99    }
100
101    fn get_mut(&mut self) -> Option<&mut dyn BufferedReader<C>> {
102        Some(self.reader.reader_mut().get_mut())
103    }
104
105    fn get_ref(&self) -> Option<&dyn BufferedReader<C>> {
106        Some(self.reader.reader_ref().get_ref())
107    }
108
109    fn into_inner<'b>(self: Box<Self>)
110            -> Option<Box<dyn BufferedReader<C> + 'b>> where Self: 'b {
111        // Strip the outer box.
112        Some(self.reader.into_reader().into_inner().into_boxed())
113    }
114
115    fn cookie_set(&mut self, cookie: C) -> C {
116        self.reader.cookie_set(cookie)
117    }
118
119    fn cookie_ref(&self) -> &C {
120        self.reader.cookie_ref()
121    }
122
123    fn cookie_mut(&mut self) -> &mut C {
124        self.reader.cookie_mut()
125    }
126}
127
128/// Decompresses the underlying `BufferedReader` using the zlib
129/// algorithm.
130pub struct Zlib<R: BufferedReader<C>, C: fmt::Debug + Sync + Send> {
131    reader: Generic<ZlibDecoder<R>, C>,
132}
133
134assert_send_and_sync!(Zlib<R, C>
135                      where R: BufferedReader<C>,
136                            C: fmt::Debug);
137
138impl <R: BufferedReader<()>> Zlib<R, ()> {
139    /// Instantiates a new zlib decompression reader.
140    ///
141    /// `reader` is the source to wrap.
142    pub fn new(reader: R) -> Self {
143        Self::with_cookie(reader, ())
144    }
145}
146
147impl <R: BufferedReader<C>, C: fmt::Debug + Sync + Send> Zlib<R, C> {
148    /// Like [`Self::new`], but uses a cookie.
149    ///
150    /// The cookie can be retrieved using the [`BufferedReader::cookie_ref`] and
151    /// [`BufferedReader::cookie_mut`] methods, and set using the [`BufferedReader::cookie_set`] method.
152    pub fn with_cookie(reader: R, cookie: C) -> Self {
153        Zlib {
154            reader: Generic::with_cookie(
155                ZlibDecoder::new(reader), None, cookie),
156        }
157    }
158}
159
160impl<R: BufferedReader<C>, C: fmt::Debug + Sync + Send> io::Read for Zlib<R, C> {
161    fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
162        self.reader.read(buf)
163    }
164}
165
166impl<R: BufferedReader<C>, C: fmt::Debug + Sync + Send> fmt::Display for Zlib<R, C> {
167    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
168        write!(f, "Zlib")
169    }
170}
171
172impl<R: BufferedReader<C>, C: fmt::Debug + Sync + Send> fmt::Debug for Zlib<R, C> {
173    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
174        f.debug_struct("Zlib")
175            .field("reader", &self.get_ref().unwrap())
176            .finish()
177    }
178}
179
180impl<R: BufferedReader<C>, C: fmt::Debug + Send + Sync> BufferedReader<C>
181        for Zlib<R, C> {
182    fn buffer(&self) -> &[u8] {
183        self.reader.buffer()
184    }
185
186    fn data(&mut self, amount: usize) -> Result<&[u8], io::Error> {
187        self.reader.data(amount)
188    }
189
190    fn data_hard(&mut self, amount: usize) -> Result<&[u8], io::Error> {
191        self.reader.data_hard(amount)
192    }
193
194    fn data_eof(&mut self) -> Result<&[u8], io::Error> {
195        self.reader.data_eof()
196    }
197
198    fn consume(&mut self, amount: usize) -> &[u8] {
199        self.reader.consume(amount)
200    }
201
202    fn data_consume(&mut self, amount: usize)
203                    -> Result<&[u8], io::Error> {
204        self.reader.data_consume(amount)
205    }
206
207    fn data_consume_hard(&mut self, amount: usize) -> Result<&[u8], io::Error> {
208        self.reader.data_consume_hard(amount)
209    }
210
211    fn read_be_u16(&mut self) -> Result<u16, io::Error> {
212        self.reader.read_be_u16()
213    }
214
215    fn read_be_u32(&mut self) -> Result<u32, io::Error> {
216        self.reader.read_be_u32()
217    }
218
219    fn steal(&mut self, amount: usize) -> Result<Vec<u8>, io::Error> {
220        self.reader.steal(amount)
221    }
222
223    fn steal_eof(&mut self) -> Result<Vec<u8>, io::Error> {
224        self.reader.steal_eof()
225    }
226
227    fn get_mut(&mut self) -> Option<&mut dyn BufferedReader<C>> {
228        Some(self.reader.reader_mut().get_mut())
229    }
230
231    fn get_ref(&self) -> Option<&dyn BufferedReader<C>> {
232        Some(self.reader.reader_ref().get_ref())
233    }
234
235    fn into_inner<'b>(self: Box<Self>)
236            -> Option<Box<dyn BufferedReader<C> + 'b>> where Self: 'b {
237        // Strip the outer box.
238        Some(self.reader.into_reader().into_inner().into_boxed())
239    }
240
241    fn cookie_set(&mut self, cookie: C) -> C {
242        self.reader.cookie_set(cookie)
243    }
244
245    fn cookie_ref(&self) -> &C {
246        self.reader.cookie_ref()
247    }
248
249    fn cookie_mut(&mut self) -> &mut C {
250        self.reader.cookie_mut()
251    }
252}
253
254#[cfg(test)]
255mod test {
256    use super::*;
257
258    // Test that buffer() returns the same data as data().
259    #[test]
260    fn buffer_test() {
261        use flate2::write::DeflateEncoder;
262        use flate2::Compression;
263        use std::io::prelude::*;
264
265        // Test vector.
266        let size = 10 * default_buf_size();
267        let mut input_raw = Vec::with_capacity(size);
268        let mut v = 0u8;
269        for _ in 0..size {
270            input_raw.push(v);
271            if v == std::u8::MAX {
272                v = 0;
273            } else {
274                v += 1;
275            }
276        }
277
278        // Compress the raw input.
279        let mut input = Vec::new();
280        {
281            let mut encoder =
282                DeflateEncoder::new(&mut input, Compression::default());
283            encoder.write(&input_raw[..]).unwrap();
284            encoder.try_finish().unwrap();
285        }
286
287        let mut reader = Deflate::new(
288            Generic::new(&input[..], None));
289
290        // Gather some stats to make it easier to figure out whether
291        // this test is working.
292        let stats_count =  2 * default_buf_size();
293        let mut stats = vec![0usize; stats_count];
294
295        for i in 0..input_raw.len() {
296            let data = reader.data(default_buf_size() + 1).unwrap().to_vec();
297            assert!(!data.is_empty());
298            assert_eq!(data, reader.buffer());
299            // And, we may as well check to make sure we read the
300            // right data.
301            assert_eq!(data, &input_raw[i..i+data.len()]);
302
303            stats[cmp::min(data.len(), stats_count - 1)] += 1;
304
305            // Consume one byte and see what happens.
306            reader.consume(1);
307        }
308
309        if false {
310            for i in 0..stats.len() {
311                if stats[i] > 0 {
312                    if i == stats.len() - 1 {
313                        eprint!(">=");
314                    }
315                    eprintln!("{}: {}", i, stats[i]);
316                }
317            }
318        }
319    }
320}