inflate/
reader.rs

1use std::io::{self, BufRead, Read, BufReader, Error, ErrorKind, Write};
2use std::{cmp,mem};
3
4use super::InflateStream;
5
6/// Workaround for lack of copy_from_slice on pre-1.9 rust.
7#[inline]
8fn copy_from_slice(mut to: &mut [u8], from: &[u8]) {
9    assert_eq!(to.len(), from.len());
10    to.write_all(from).unwrap();
11}
12
13/// A DEFLATE decoder/decompressor.
14///
15/// This structure implements a `Read` interface and takes a stream
16/// of compressed data that implements the `BufRead` trait as input,
17/// providing the decompressed data when read from.
18///
19/// # Example
20/// ```
21/// use std::io::Read;
22/// use inflate::DeflateDecoderBuf;
23///
24/// const TEST_STRING: &'static str = "Hello, world";
25/// let encoded = vec![243, 72, 205, 201, 201, 215, 81, 40, 207, 47, 202, 73, 1, 0];
26/// let mut decoder = DeflateDecoderBuf::new(&encoded[..]);
27/// let mut output = Vec::new();
28/// let status = decoder.read_to_end(&mut output);
29/// # let _ = status;
30/// assert_eq!(String::from_utf8(output).unwrap(), TEST_STRING);
31/// ```
32pub struct DeflateDecoderBuf<R> {
33    /// The inner reader instance
34    reader: R,
35    /// The raw decompressor
36    decompressor: InflateStream,
37    /// How many bytes of the decompressor's output buffer still need to be output.
38    pending_output_bytes: usize,
39    /// Total number of bytes read from the underlying reader.
40    total_in: u64,
41    /// Total number of bytes written in `read` calls.
42    total_out: u64,
43}
44
45impl<R: BufRead> DeflateDecoderBuf<R> {
46    /// Create a new `Deflatedecoderbuf` to read from a raw deflate stream.
47    pub fn new(reader: R) -> DeflateDecoderBuf<R> {
48        DeflateDecoderBuf {
49            reader: reader,
50            decompressor: InflateStream::new(),
51            pending_output_bytes: 0,
52            total_in: 0,
53            total_out: 0,
54        }
55    }
56
57    /// Create a new `DeflateDecoderbuf` that reads from a zlib wrapped deflate stream.
58    pub fn from_zlib(reader: R) -> DeflateDecoderBuf<R> {
59        DeflateDecoderBuf {
60            reader: reader,
61            decompressor: InflateStream::from_zlib(),
62            pending_output_bytes: 0,
63            total_in: 0,
64            total_out: 0,
65        }
66    }
67
68    /// Create a new `DeflateDecoderbuf` that reads from a zlib wrapped deflate stream.
69    /// without calculating and validating the checksum.
70    pub fn from_zlib_no_checksum(reader: R) -> DeflateDecoderBuf<R> {
71        DeflateDecoderBuf {
72            reader: reader,
73            decompressor: InflateStream::from_zlib_no_checksum(),
74            pending_output_bytes: 0,
75            total_in: 0,
76            total_out: 0,
77        }
78    }
79}
80
81impl<R> DeflateDecoderBuf<R> {
82    /// Resets the decompressor, and replaces the current inner `BufRead` instance by `r`.
83    /// without doing any extra reallocations.
84    ///
85    /// Note that this function doesn't ensure that all data has been output.
86    #[inline]
87    pub fn reset(&mut self, r: R) -> R {
88        self.decompressor.reset();
89        mem::replace(&mut self.reader, r)
90    }
91
92    /// Resets the decoder, but continue to read from the same reader.
93    ///
94    /// Note that this function doesn't ensure that all data has been output.
95    #[inline]
96    pub fn reset_data(&mut self) {
97        self.decompressor.reset()
98    }
99
100    /// Returns a reference to the underlying `BufRead` instance.
101    #[inline]
102    pub fn get_ref(&self) -> &R {
103        &self.reader
104    }
105
106    /// Returns a mutable reference to the underlying `BufRead` instance.
107    ///
108    /// Note that mutation of the reader may cause surprising results if the decoder is going to
109    /// keep being used.
110    #[inline]
111    pub fn get_mut(&mut self) -> &mut R {
112        &mut self.reader
113    }
114
115    /// Drops the decoder and return the inner `BufRead` instance.
116    ///
117    /// Note that this function doesn't ensure that all data has been output.
118    #[inline]
119    pub fn into_inner(self) -> R {
120        self.reader
121    }
122
123    /// Returns the total bytes read from the underlying `BufRead` instance.
124    #[inline]
125    pub fn total_in(&self) -> u64 {
126        self.total_in
127    }
128
129    /// Returns the total number of bytes output from this decoder.
130    #[inline]
131    pub fn total_out(&self) -> u64 {
132        self.total_out
133    }
134
135    /// Returns the calculated checksum value of the currently decoded data.
136    ///
137    /// Will return 0 for cases where the checksum is not validated.
138    #[inline]
139    pub fn current_checksum(&self) -> u32 {
140        self.decompressor.current_checksum()
141    }
142}
143
144impl<R: BufRead> Read for DeflateDecoderBuf<R> {
145    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
146        let mut bytes_out = 0;
147        // If there is still data left to ouput from the last call to `update()`, that needs to be
148        // output first
149        if self.pending_output_bytes != 0 {
150            // Get the part of the buffer that has not been output yet.
151            // The decompressor sets `pos` to 0 when it reaches the end of it's internal buffer,
152            // so we have to check for that.
153            let start = if self.decompressor.pos != 0 {
154                self.decompressor.pos as usize - self.pending_output_bytes
155            } else {
156                self.decompressor.buffer.len() - self.pending_output_bytes
157            };
158
159            // Copy as much decompressed as possible to buf.
160            let bytes_to_copy = cmp::min(buf.len(), self.pending_output_bytes);
161            let pending_data =
162                &self.decompressor.buffer[start..
163                                          start + bytes_to_copy];
164            copy_from_slice(&mut buf[..bytes_to_copy],pending_data);
165            bytes_out += bytes_to_copy;
166            // This won't underflow since `bytes_to_copy` will be at most
167            // the same value as `pending_output_bytes`.
168            self.pending_output_bytes -= bytes_to_copy;
169            if self.pending_output_bytes != 0 {
170                self.total_out += bytes_out as u64;
171                // If there is still decompressed data left that didn't
172                // fit in `buf`, return what we read.
173                return Ok(bytes_out);
174            }
175        }
176
177        // There is space in `buf` for more data, so try to read more.
178        let (input_bytes_read, remaining_bytes) = {
179            self.pending_output_bytes = 0;
180            let input = try!(self.reader.fill_buf());
181            if input.len() == 0 {
182                self.total_out += bytes_out as u64;
183                //If there is nothing more to read, return.
184                return Ok(bytes_out);
185            }
186            let (input_bytes_read, data) =
187                match self.decompressor.update(&input) {
188                    Ok(res) => res,
189                    Err(m) => return Err(Error::new(ErrorKind::Other, m))
190                };
191
192            // Space left in `buf`
193            let space_left = buf.len() - bytes_out;
194            let bytes_to_copy = cmp::min(space_left, data.len());
195
196            copy_from_slice(&mut buf[bytes_out..bytes_out + bytes_to_copy], &data[..bytes_to_copy]);
197
198            bytes_out += bytes_to_copy;
199
200            // Can't underflow as bytes_to_copy is bounded by data.len().
201            (input_bytes_read, data.len() - bytes_to_copy)
202
203        };
204
205        self.pending_output_bytes += remaining_bytes;
206        self.total_in += input_bytes_read as u64;
207        self.total_out += bytes_out as u64;
208        self.reader.consume(input_bytes_read);
209
210        Ok(bytes_out)
211    }
212}
213
214
215
216/// A DEFLATE decoder/decompressor.
217///
218/// This structure implements a `Read` interface and takes a stream of compressed data that
219/// implements the `Read` trait as input,
220/// provoding the decompressed data when read from.
221/// # Example
222/// ```
223/// use std::io::Read;
224/// use inflate::DeflateDecoder;
225/// const TEST_STRING: &'static str = "Hello, world";
226/// let encoded = vec![243, 72, 205, 201, 201, 215, 81, 40, 207, 47, 202, 73, 1, 0];
227/// let mut decoder = DeflateDecoder::new(&encoded[..]);
228/// let mut output = Vec::new();
229/// let status = decoder.read_to_end(&mut output);
230/// # let _ = status;
231/// assert_eq!(String::from_utf8(output).unwrap(), TEST_STRING);
232/// ```
233pub struct DeflateDecoder<R> {
234    /// Inner DeflateDecoderBuf, with R wrapped in a `BufReader`.
235    inner: DeflateDecoderBuf<BufReader<R>>
236}
237
238impl<R: Read> DeflateDecoder<R> {
239    /// Create a new `Deflatedecoderbuf` to read from a raw deflate stream.
240    pub fn new(reader: R) -> DeflateDecoder<R> {
241        DeflateDecoder {
242            inner: DeflateDecoderBuf::new(BufReader::new(reader))
243        }
244    }
245
246    /// Create a new `DeflateDecoderbuf` that reads from a zlib wrapped deflate stream.
247    pub fn from_zlib(reader: R) -> DeflateDecoder<R> {
248        DeflateDecoder {
249            inner: DeflateDecoderBuf::from_zlib(BufReader::new(reader))
250        }
251    }
252
253    /// Create a new `DeflateDecoderbuf` that reads from a zlib wrapped deflate stream.
254    /// without calculating and validating the checksum.
255    pub fn from_zlib_no_checksum(reader: R) -> DeflateDecoder<R> {
256        DeflateDecoder {
257            inner: DeflateDecoderBuf::from_zlib_no_checksum(BufReader::new(reader))
258        }
259    }
260
261    /// Resets the decompressor, and replaces the current inner `BufRead` instance by `r`.
262    /// without doing any extra reallocations.
263    ///
264    /// Note that this function doesn't ensure that all data has been output.
265    #[inline]
266    pub fn reset(&mut self, r: R) -> R {
267        self.inner.reset(BufReader::new(r)).into_inner()
268    }
269
270    /// Returns a reference to the underlying reader.
271    #[inline]
272    pub fn get_ref(&self) -> &R {
273        self.inner.get_ref().get_ref()
274    }
275
276    /// Returns a mutable reference to the underlying reader.
277    ///
278    /// Note that mutation of the reader may cause surprising results if the decoder is going to
279    /// keep being used.
280    #[inline]
281    pub fn get_mut(&mut self) -> &mut R {
282        self.inner.get_mut().get_mut()
283    }
284
285    /// Returns the total number of bytes output from this decoder.
286    #[inline]
287    pub fn into_inner(self) -> R {
288        self.inner.into_inner().into_inner()
289    }
290}
291
292impl<R> DeflateDecoder<R> {
293    /// Resets the decoder, but continue to read from the same reader.
294    ///
295    /// Note that this function doesn't ensure that all data has been output.
296    #[inline]
297    pub fn reset_data(&mut self) {
298        self.inner.reset_data()
299    }
300
301    /// Returns the total bytes read from the underlying reader.
302    #[inline]
303    pub fn total_in(&self) -> u64 {
304        self.inner.total_in
305    }
306
307    /// Returns the total number of bytes output from this decoder.
308    #[inline]
309    pub fn total_out(&self) -> u64 {
310        self.inner.total_out
311    }
312
313    /// Returns the calculated checksum value of the currently decoded data.
314    ///
315    /// Will return 0 for cases where the checksum is not validated.
316    #[inline]
317    pub fn current_checksum(&self) -> u32 {
318        self.inner.current_checksum()
319    }
320}
321
322impl<R: Read> Read for DeflateDecoder<R> {
323    #[inline]
324    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
325        self.inner.read(buf)
326    }
327}
328
329#[cfg(test)]
330mod test {
331    use super::{DeflateDecoder};
332    use std::io::Read;
333
334    #[test]
335    fn deflate_reader() {
336        const TEST_STRING: &'static str = "Hello, world";
337        let encoded = vec![243, 72, 205, 201, 201, 215, 81, 40, 207, 47, 202, 73, 1, 0];
338        let mut decoder = DeflateDecoder::new(&encoded[..]);
339        let mut output = Vec::new();
340        decoder.read_to_end(&mut output).unwrap();
341        assert_eq!(String::from_utf8(output).unwrap(), TEST_STRING);
342        assert_eq!(decoder.total_in(), encoded.len() as u64);
343        assert_eq!(decoder.total_out(), TEST_STRING.len() as u64);
344    }
345
346    #[test]
347    fn zlib_reader() {
348        const TEST_STRING: &'static str = "Hello, zlib!";
349        let encoded = vec![120, 156, 243, 72, 205, 201, 201, 215, 81, 168, 202, 201,
350                       76, 82, 4, 0, 27, 101, 4, 19];
351        let mut decoder = DeflateDecoder::from_zlib(&encoded[..]);
352        let mut output = Vec::new();
353        decoder.read_to_end(&mut output).unwrap();
354        assert_eq!(String::from_utf8(output).unwrap(), TEST_STRING);
355        assert_eq!(decoder.total_in(), encoded.len() as u64);
356        assert_eq!(decoder.total_out(), TEST_STRING.len() as u64);
357    }
358}