1 use std::io::prelude::*;
2 use std::io;
3 
4 use super::{Builder, Header};
5 use Compression;
6 use bufreader::BufReader;
7 use super::bufread;
8 
9 /// A gzip streaming encoder
10 ///
11 /// This structure exposes a [`Read`] interface that will read uncompressed data
12 /// from the underlying reader and expose the compressed version as a [`Read`]
13 /// interface.
14 ///
15 /// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
16 ///
17 /// # Examples
18 ///
19 /// ```
20 /// use std::io::prelude::*;
21 /// use std::io;
22 /// use flate2::Compression;
23 /// use flate2::read::GzEncoder;
24 ///
25 /// // Return a vector containing the GZ compressed version of hello world
26 ///
27 /// fn gzencode_hello_world() -> io::Result<Vec<u8>> {
28 ///     let mut ret_vec = [0;100];
29 ///     let bytestring = b"hello world";
30 ///     let mut gz = GzEncoder::new(&bytestring[..], Compression::Fast);
31 ///     let count = gz.read(&mut ret_vec)?;
32 ///     Ok(ret_vec[0..count].to_vec())
33 /// }
34 /// ```
35 #[derive(Debug)]
36 pub struct GzEncoder<R> {
37     inner: bufread::GzEncoder<BufReader<R>>,
38 }
39 
gz_encoder<R: Read>(inner: bufread::GzEncoder<BufReader<R>>) -> GzEncoder<R>40 pub fn gz_encoder<R: Read>(inner: bufread::GzEncoder<BufReader<R>>)
41     -> GzEncoder<R>
42 {
43     GzEncoder { inner: inner }
44 }
45 
46 impl<R: Read> GzEncoder<R> {
47     /// Creates a new encoder which will use the given compression level.
48     ///
49     /// The encoder is not configured specially for the emitted header. For
50     /// header configuration, see the `Builder` type.
51     ///
52     /// The data read from the stream `r` will be compressed and available
53     /// through the returned reader.
new(r: R, level: Compression) -> GzEncoder<R>54     pub fn new(r: R, level: Compression) -> GzEncoder<R> {
55         Builder::new().read(r, level)
56     }
57 }
58 
59 impl<R> GzEncoder<R> {
60     /// Acquires a reference to the underlying reader.
get_ref(&self) -> &R61     pub fn get_ref(&self) -> &R {
62         self.inner.get_ref().get_ref()
63     }
64 
65     /// Acquires a mutable reference to the underlying reader.
66     ///
67     /// Note that mutation of the reader may result in surprising results if
68     /// this encoder is continued to be used.
get_mut(&mut self) -> &mut R69     pub fn get_mut(&mut self) -> &mut R {
70         self.inner.get_mut().get_mut()
71     }
72 
73     /// Returns the underlying stream, consuming this encoder
into_inner(self) -> R74     pub fn into_inner(self) -> R {
75         self.inner.into_inner().into_inner()
76     }
77 }
78 
79 impl<R: Read> Read for GzEncoder<R> {
read(&mut self, into: &mut [u8]) -> io::Result<usize>80     fn read(&mut self, into: &mut [u8]) -> io::Result<usize> {
81         self.inner.read(into)
82     }
83 }
84 
85 impl<R: Read + Write> Write for GzEncoder<R> {
write(&mut self, buf: &[u8]) -> io::Result<usize>86     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
87         self.get_mut().write(buf)
88     }
89 
flush(&mut self) -> io::Result<()>90     fn flush(&mut self) -> io::Result<()> {
91         self.get_mut().flush()
92     }
93 }
94 
95 /// A gzip streaming decoder
96 ///
97 /// This structure exposes a [`Read`] interface that will consume compressed
98 /// data from the underlying reader and emit uncompressed data.
99 ///
100 /// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
101 ///
102 /// # Examples
103 ///
104 /// ```
105 ///
106 /// use std::io::prelude::*;
107 /// use std::io;
108 /// # use flate2::Compression;
109 /// # use flate2::write::GzEncoder;
110 /// use flate2::read::GzDecoder;
111 ///
112 /// # fn main() {
113 /// #    let mut e = GzEncoder::new(Vec::new(), Compression::Default);
114 /// #    e.write(b"Hello World").unwrap();
115 /// #    let bytes = e.finish().unwrap();
116 /// #    println!("{}", decode_reader(bytes).unwrap());
117 /// # }
118 /// #
119 /// // Uncompresses a Gz Encoded vector of bytes and returns a string or error
120 /// // Here &[u8] implements Read
121 ///
122 /// fn decode_reader(bytes: Vec<u8>) -> io::Result<String> {
123 ///    let mut gz = GzDecoder::new(&bytes[..])?;
124 ///    let mut s = String::new();
125 ///    gz.read_to_string(&mut s)?;
126 ///    Ok(s)
127 /// }
128 /// ```
129 #[derive(Debug)]
130 pub struct GzDecoder<R> {
131     inner: bufread::GzDecoder<BufReader<R>>,
132 }
133 
134 impl<R: Read> GzDecoder<R> {
135     /// Creates a new decoder from the given reader, immediately parsing the
136     /// gzip header.
137     ///
138     /// # Errors
139     ///
140     /// If an error is encountered when parsing the gzip header, an error is
141     /// returned.
new(r: R) -> io::Result<GzDecoder<R>>142     pub fn new(r: R) -> io::Result<GzDecoder<R>> {
143         bufread::GzDecoder::new(BufReader::new(r)).map(|r| GzDecoder { inner: r })
144     }
145 }
146 
147 impl<R> GzDecoder<R> {
148     /// Returns the header associated with this stream.
header(&self) -> &Header149     pub fn header(&self) -> &Header {
150         self.inner.header()
151     }
152 
153     /// Acquires a reference to the underlying reader.
get_ref(&self) -> &R154     pub fn get_ref(&self) -> &R {
155         self.inner.get_ref().get_ref()
156     }
157 
158     /// Acquires a mutable reference to the underlying stream.
159     ///
160     /// Note that mutation of the stream may result in surprising results if
161     /// this encoder is continued to be used.
get_mut(&mut self) -> &mut R162     pub fn get_mut(&mut self) -> &mut R {
163         self.inner.get_mut().get_mut()
164     }
165 
166     /// Consumes this decoder, returning the underlying reader.
into_inner(self) -> R167     pub fn into_inner(self) -> R {
168         self.inner.into_inner().into_inner()
169     }
170 }
171 
172 impl<R: Read> Read for GzDecoder<R> {
read(&mut self, into: &mut [u8]) -> io::Result<usize>173     fn read(&mut self, into: &mut [u8]) -> io::Result<usize> {
174         self.inner.read(into)
175     }
176 }
177 
178 impl<R: Read + Write> Write for GzDecoder<R> {
write(&mut self, buf: &[u8]) -> io::Result<usize>179     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
180         self.get_mut().write(buf)
181     }
182 
flush(&mut self) -> io::Result<()>183     fn flush(&mut self) -> io::Result<()> {
184         self.get_mut().flush()
185     }
186 }
187 
188 /// A gzip streaming decoder that decodes all members of a multistream
189 ///
190 /// A gzip member consists of a header, compressed data and a trailer. The [gzip
191 /// specification](https://tools.ietf.org/html/rfc1952), however, allows multiple
192 /// gzip members to be joined in a single stream.  `MultiGzDecoder` will
193 /// decode all consecutive members while `GzDecoder` will only decompress the
194 /// first gzip member. The multistream format is commonly used in bioinformatics,
195 /// for example when using the BGZF compressed data.
196 ///
197 /// This structure exposes a [`Read`] interface that will consume all gzip members
198 /// from the underlying reader and emit uncompressed data.
199 ///
200 /// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
201 ///
202 /// # Examples
203 ///
204 /// ```
205 /// use std::io::prelude::*;
206 /// use std::io;
207 /// # use flate2::Compression;
208 /// # use flate2::write::GzEncoder;
209 /// use flate2::read::MultiGzDecoder;
210 ///
211 /// # fn main() {
212 /// #    let mut e = GzEncoder::new(Vec::new(), Compression::Default);
213 /// #    e.write(b"Hello World").unwrap();
214 /// #    let bytes = e.finish().unwrap();
215 /// #    println!("{}", decode_reader(bytes).unwrap());
216 /// # }
217 /// #
218 /// // Uncompresses a Gz Encoded vector of bytes and returns a string or error
219 /// // Here &[u8] implements Read
220 ///
221 /// fn decode_reader(bytes: Vec<u8>) -> io::Result<String> {
222 ///    let mut gz = MultiGzDecoder::new(&bytes[..])?;
223 ///    let mut s = String::new();
224 ///    gz.read_to_string(&mut s)?;
225 ///    Ok(s)
226 /// }
227 /// ```
228 #[derive(Debug)]
229 pub struct MultiGzDecoder<R> {
230     inner: bufread::MultiGzDecoder<BufReader<R>>,
231 }
232 
233 impl<R: Read> MultiGzDecoder<R> {
234     /// Creates a new decoder from the given reader, immediately parsing the
235     /// (first) gzip header. If the gzip stream contains multiple members all will
236     /// be decoded.
237     ///
238     /// # Errors
239     ///
240     /// If an error is encountered when parsing the gzip header, an error is
241     /// returned.
new(r: R) -> io::Result<MultiGzDecoder<R>>242     pub fn new(r: R) -> io::Result<MultiGzDecoder<R>> {
243         bufread::MultiGzDecoder::new(BufReader::new(r)).map(|r| MultiGzDecoder { inner: r })
244     }
245 }
246 
247 impl<R> MultiGzDecoder<R> {
248     /// Returns the current header associated with this stream.
header(&self) -> &Header249     pub fn header(&self) -> &Header {
250         self.inner.header()
251     }
252 
253     /// Acquires a reference to the underlying reader.
get_ref(&self) -> &R254     pub fn get_ref(&self) -> &R {
255         self.inner.get_ref().get_ref()
256     }
257 
258     /// Acquires a mutable reference to the underlying stream.
259     ///
260     /// Note that mutation of the stream may result in surprising results if
261     /// this encoder is continued to be used.
get_mut(&mut self) -> &mut R262     pub fn get_mut(&mut self) -> &mut R {
263         self.inner.get_mut().get_mut()
264     }
265 
266     /// Consumes this decoder, returning the underlying reader.
into_inner(self) -> R267     pub fn into_inner(self) -> R {
268         self.inner.into_inner().into_inner()
269     }
270 }
271 
272 impl<R: Read> Read for MultiGzDecoder<R> {
read(&mut self, into: &mut [u8]) -> io::Result<usize>273     fn read(&mut self, into: &mut [u8]) -> io::Result<usize> {
274         self.inner.read(into)
275     }
276 }
277 
278 impl<R: Read + Write> Write for MultiGzDecoder<R> {
write(&mut self, buf: &[u8]) -> io::Result<usize>279     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
280         self.get_mut().write(buf)
281     }
282 
flush(&mut self) -> io::Result<()>283     fn flush(&mut self) -> io::Result<()> {
284         self.get_mut().flush()
285     }
286 }
287