inflate/
writer.rs

1use std::io::{Write, Error, ErrorKind};
2use std::io;
3use InflateStream;
4
5/// A DEFLATE decoder.
6///
7/// A struct implementing the `std::io::Write` trait that decompresses DEFLATE
8/// encoded data into the given writer `w`.
9///
10/// # Example
11///
12/// ```
13/// use inflate::InflateWriter;
14/// use std::io::Write;
15///
16/// let encoded = [243, 72, 205, 201, 201, 215, 81, 40, 207, 47, 202, 73, 1, 0];
17/// let mut decoder = InflateWriter::new(Vec::new());
18/// decoder.write(&encoded).unwrap();
19/// let decoded = decoder.finish().unwrap();
20/// println!("{}", std::str::from_utf8(&decoded).unwrap()); // prints "Hello, world"
21/// ```
22pub struct InflateWriter<W: Write> {
23    inflater: InflateStream,
24    writer: W
25}
26
27impl<W: Write> InflateWriter<W> {
28    pub fn new(w: W) -> InflateWriter<W> {
29        InflateWriter { inflater: InflateStream::new(), writer: w }
30    }
31
32    pub fn from_zlib(w: W) -> InflateWriter<W> {
33        InflateWriter { inflater: InflateStream::from_zlib(), writer: w }
34    }
35
36    pub fn finish(mut self) -> io::Result<W> {
37        try!(self.flush());
38        Ok(self.writer)
39    }
40}
41
42fn update<'a>(inflater: &'a mut InflateStream, buf: &[u8]) -> io::Result<(usize, &'a [u8])>  {
43    match inflater.update(buf) {
44        Ok(res) => Ok(res),
45        Err(m) => return Err(Error::new(ErrorKind::Other, m)),
46    }
47}
48impl<W: Write> Write for InflateWriter<W> {
49    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
50        let mut n = 0;
51        while n < buf.len() {
52            let (num_bytes_read, result) = try!(update(&mut self.inflater, &buf[n..]));
53            n += num_bytes_read;
54            try!(self.writer.write(result));
55        }
56        Ok(n)
57    }
58
59    fn flush(&mut self) -> io::Result<()> {
60        let (_, result) = try!(update(&mut self.inflater, &[]));
61        try!(self.writer.write(result));
62        Ok(())
63    }
64}
65
66#[cfg(test)]
67mod test {
68    use super::InflateWriter;
69    use std::io::Write;
70
71    #[test]
72    fn inflate_writer() {
73       let encoded = [243, 72, 205, 201, 201, 215, 81, 40, 207, 47, 202, 73, 1, 0];
74       let mut decoder = InflateWriter::new(Vec::new());
75       decoder.write(&encoded).unwrap();
76       let decoded = decoder.finish().unwrap();
77       assert!(String::from_utf8(decoded).unwrap() == "Hello, world");
78    }
79
80    #[test]
81    fn inflate_writer_from_zlib() {
82       let encoded = [120, 156, 243, 72, 205, 201, 201, 215, 81, 168, 202, 201, 76, 82, 4, 0, 27, 101, 4, 19];
83       let mut decoder = InflateWriter::from_zlib(Vec::new());
84       decoder.write(&encoded).unwrap();
85       let decoded = decoder.finish().unwrap();
86       assert!(String::from_utf8(decoded).unwrap() == "Hello, zlib!");
87    }
88}