flate2/gz/
read.rs

1use std::io;
2use std::io::prelude::*;
3
4#[cfg(feature = "tokio")]
5use futures::Poll;
6#[cfg(feature = "tokio")]
7use tokio_io::{AsyncRead, AsyncWrite};
8
9use super::bufread;
10use super::{GzBuilder, GzHeader};
11use crate::bufreader::BufReader;
12use 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)]
41pub struct GzEncoder<R> {
42    inner: bufread::GzEncoder<BufReader<R>>,
43}
44
45pub fn gz_encoder<R: Read>(inner: bufread::GzEncoder<BufReader<R>>) -> GzEncoder<R> {
46    GzEncoder { inner: inner }
47}
48
49impl<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.
57    pub fn new(r: R, level: Compression) -> GzEncoder<R> {
58        GzBuilder::new().read(r, level)
59    }
60}
61
62impl<R> GzEncoder<R> {
63    /// Acquires a reference to the underlying reader.
64    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.
72    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
77    pub fn into_inner(self) -> R {
78        self.inner.into_inner().into_inner()
79    }
80}
81
82impl<R: Read> Read for GzEncoder<R> {
83    fn read(&mut self, into: &mut [u8]) -> io::Result<usize> {
84        self.inner.read(into)
85    }
86}
87
88impl<R: Read + Write> Write for GzEncoder<R> {
89    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
90        self.get_mut().write(buf)
91    }
92
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)]
133pub struct GzDecoder<R> {
134    inner: bufread::GzDecoder<BufReader<R>>,
135}
136
137impl<R: Read> GzDecoder<R> {
138    /// Creates a new decoder from the given reader, immediately parsing the
139    /// gzip header.
140    pub fn new(r: R) -> GzDecoder<R> {
141        GzDecoder {
142            inner: bufread::GzDecoder::new(BufReader::new(r)),
143        }
144    }
145}
146
147impl<R> GzDecoder<R> {
148    /// Returns the header associated with this stream, if it was valid.
149    pub fn header(&self) -> Option<&GzHeader> {
150        self.inner.header()
151    }
152
153    /// Acquires a reference to the underlying reader.
154    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.
162    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.
167    pub fn into_inner(self) -> R {
168        self.inner.into_inner().into_inner()
169    }
170}
171
172impl<R: Read> Read for GzDecoder<R> {
173    fn read(&mut self, into: &mut [u8]) -> io::Result<usize> {
174        self.inner.read(into)
175    }
176}
177
178#[cfg(feature = "tokio")]
179impl<R: AsyncRead> AsyncRead for GzDecoder<R> {}
180
181impl<R: Read + Write> Write for GzDecoder<R> {
182    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
183        self.get_mut().write(buf)
184    }
185
186    fn flush(&mut self) -> io::Result<()> {
187        self.get_mut().flush()
188    }
189}
190
191#[cfg(feature = "tokio")]
192impl<R: AsyncWrite + AsyncRead> AsyncWrite for GzDecoder<R> {
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)]
239pub struct MultiGzDecoder<R> {
240    inner: bufread::MultiGzDecoder<BufReader<R>>,
241}
242
243impl<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.
247    pub fn new(r: R) -> MultiGzDecoder<R> {
248        MultiGzDecoder {
249            inner: bufread::MultiGzDecoder::new(BufReader::new(r)),
250        }
251    }
252}
253
254impl<R> MultiGzDecoder<R> {
255    /// Returns the current header associated with this stream, if it's valid.
256    pub fn header(&self) -> Option<&GzHeader> {
257        self.inner.header()
258    }
259
260    /// Acquires a reference to the underlying reader.
261    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.
269    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.
274    pub fn into_inner(self) -> R {
275        self.inner.into_inner().into_inner()
276    }
277}
278
279impl<R: Read> Read for MultiGzDecoder<R> {
280    fn read(&mut self, into: &mut [u8]) -> io::Result<usize> {
281        self.inner.read(into)
282    }
283}
284
285#[cfg(feature = "tokio")]
286impl<R: AsyncRead> AsyncRead for MultiGzDecoder<R> {}
287
288impl<R: Read + Write> Write for MultiGzDecoder<R> {
289    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
290        self.get_mut().write(buf)
291    }
292
293    fn flush(&mut self) -> io::Result<()> {
294        self.get_mut().flush()
295    }
296}
297
298#[cfg(feature = "tokio")]
299impl<R: AsyncWrite + AsyncRead> AsyncWrite for MultiGzDecoder<R> {
300    fn shutdown(&mut self) -> Poll<(), io::Error> {
301        self.get_mut().shutdown()
302    }
303}