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