]> git.proxmox.com Git - rustc.git/blame - src/vendor/flate2/src/gz/read.rs
New upstream version 1.23.0+dfsg1
[rustc.git] / src / vendor / flate2 / src / gz / read.rs
CommitLineData
ea8adc8c
XL
1use std::io::prelude::*;
2use std::io;
3
4use super::{Builder, Header};
5use Compression;
6use bufreader::BufReader;
7use 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)]
36pub struct GzEncoder<R> {
37 inner: bufread::GzEncoder<BufReader<R>>,
38}
39
40pub fn gz_encoder<R: Read>(inner: bufread::GzEncoder<BufReader<R>>)
41 -> GzEncoder<R>
42{
43 GzEncoder { inner: inner }
44}
45
46impl<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.
54 pub fn new(r: R, level: Compression) -> GzEncoder<R> {
55 Builder::new().read(r, level)
56 }
57}
58
59impl<R> GzEncoder<R> {
60 /// Acquires a reference to the underlying reader.
61 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.
69 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
74 pub fn into_inner(self) -> R {
75 self.inner.into_inner().into_inner()
76 }
77}
78
79impl<R: Read> Read for GzEncoder<R> {
80 fn read(&mut self, into: &mut [u8]) -> io::Result<usize> {
81 self.inner.read(into)
82 }
83}
84
85impl<R: Read + Write> Write for GzEncoder<R> {
86 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
87 self.get_mut().write(buf)
88 }
89
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)]
130pub struct GzDecoder<R> {
131 inner: bufread::GzDecoder<BufReader<R>>,
132}
133
134impl<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.
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
147impl<R> GzDecoder<R> {
148 /// Returns the header associated with this stream.
149 pub fn header(&self) -> &Header {
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
178impl<R: Read + Write> Write for GzDecoder<R> {
179 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
180 self.get_mut().write(buf)
181 }
182
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)]
229pub struct MultiGzDecoder<R> {
230 inner: bufread::MultiGzDecoder<BufReader<R>>,
231}
232
233impl<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.
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
247impl<R> MultiGzDecoder<R> {
248 /// Returns the current header associated with this stream.
249 pub fn header(&self) -> &Header {
250 self.inner.header()
251 }
252
253 /// Acquires a reference to the underlying reader.
254 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.
262 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.
267 pub fn into_inner(self) -> R {
268 self.inner.into_inner().into_inner()
269 }
270}
271
272impl<R: Read> Read for MultiGzDecoder<R> {
273 fn read(&mut self, into: &mut [u8]) -> io::Result<usize> {
274 self.inner.read(into)
275 }
276}
277
278impl<R: Read + Write> Write for MultiGzDecoder<R> {
279 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
280 self.get_mut().write(buf)
281 }
282
283 fn flush(&mut self) -> io::Result<()> {
284 self.get_mut().flush()
285 }
286}