]>
Commit | Line | Data |
---|---|---|
ea8adc8c XL |
1 | use std::io::prelude::*; |
2 | use std::io; | |
3 | ||
4 | #[cfg(feature = "tokio")] | |
5 | use futures::Poll; | |
6 | #[cfg(feature = "tokio")] | |
7 | use tokio_io::{AsyncRead, AsyncWrite}; | |
8 | ||
9 | use zio; | |
10 | use {Compress, Decompress}; | |
11 | ||
12 | /// A DEFLATE encoder, or compressor. | |
13 | /// | |
14 | /// This structure implements a [`Write`] interface and takes a stream of | |
15 | /// uncompressed data, writing the compressed data to the wrapped writer. | |
16 | /// | |
17 | /// [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html | |
18 | /// | |
19 | /// # Examples | |
20 | /// | |
21 | /// ``` | |
22 | /// use std::io::prelude::*; | |
23 | /// use flate2::Compression; | |
24 | /// use flate2::write::DeflateEncoder; | |
25 | /// | |
26 | /// // Vec<u8> implements Write to print the compressed bytes of sample string | |
27 | /// # fn main() { | |
28 | /// | |
ff7c6d11 | 29 | /// let mut e = DeflateEncoder::new(Vec::new(), Compression::default()); |
ea8adc8c XL |
30 | /// e.write(b"Hello World").unwrap(); |
31 | /// println!("{:?}", e.finish().unwrap()); | |
32 | /// # } | |
33 | /// ``` | |
34 | #[derive(Debug)] | |
35 | pub struct DeflateEncoder<W: Write> { | |
36 | inner: zio::Writer<W, Compress>, | |
37 | } | |
38 | ||
39 | impl<W: Write> DeflateEncoder<W> { | |
40 | /// Creates a new encoder which will write compressed data to the stream | |
41 | /// given at the given compression level. | |
42 | /// | |
43 | /// When this encoder is dropped or unwrapped the final pieces of data will | |
44 | /// be flushed. | |
45 | pub fn new(w: W, level: ::Compression) -> DeflateEncoder<W> { | |
46 | DeflateEncoder { | |
47 | inner: zio::Writer::new(w, Compress::new(level, false)), | |
48 | } | |
49 | } | |
50 | ||
51 | /// Acquires a reference to the underlying writer. | |
52 | pub fn get_ref(&self) -> &W { | |
53 | self.inner.get_ref() | |
54 | } | |
55 | ||
56 | /// Acquires a mutable reference to the underlying writer. | |
57 | /// | |
58 | /// Note that mutating the output/input state of the stream may corrupt this | |
59 | /// object, so care must be taken when using this method. | |
60 | pub fn get_mut(&mut self) -> &mut W { | |
61 | self.inner.get_mut() | |
62 | } | |
63 | ||
64 | /// Resets the state of this encoder entirely, swapping out the output | |
65 | /// stream for another. | |
66 | /// | |
67 | /// This function will finish encoding the current stream into the current | |
68 | /// output stream before swapping out the two output streams. If the stream | |
69 | /// cannot be finished an error is returned. | |
70 | /// | |
71 | /// After the current stream has been finished, this will reset the internal | |
72 | /// state of this encoder and replace the output stream with the one | |
73 | /// provided, returning the previous output stream. Future data written to | |
74 | /// this encoder will be the compressed into the stream `w` provided. | |
75 | /// | |
76 | /// # Errors | |
77 | /// | |
78 | /// This function will perform I/O to complete this stream, and any I/O | |
79 | /// errors which occur will be returned from this function. | |
80 | pub fn reset(&mut self, w: W) -> io::Result<W> { | |
81 | try!(self.inner.finish()); | |
82 | self.inner.data.reset(); | |
83 | Ok(self.inner.replace(w)) | |
84 | } | |
85 | ||
86 | /// Attempt to finish this output stream, writing out final chunks of data. | |
87 | /// | |
88 | /// Note that this function can only be used once data has finished being | |
89 | /// written to the output stream. After this function is called then further | |
90 | /// calls to `write` may result in a panic. | |
91 | /// | |
92 | /// # Panics | |
93 | /// | |
94 | /// Attempts to write data to this stream may result in a panic after this | |
95 | /// function is called. | |
96 | /// | |
97 | /// # Errors | |
98 | /// | |
99 | /// This function will perform I/O to complete this stream, and any I/O | |
100 | /// errors which occur will be returned from this function. | |
101 | pub fn try_finish(&mut self) -> io::Result<()> { | |
102 | self.inner.finish() | |
103 | } | |
104 | ||
105 | /// Consumes this encoder, flushing the output stream. | |
106 | /// | |
107 | /// This will flush the underlying data stream, close off the compressed | |
108 | /// stream and, if successful, return the contained writer. | |
109 | /// | |
110 | /// Note that this function may not be suitable to call in a situation where | |
111 | /// the underlying stream is an asynchronous I/O stream. To finish a stream | |
112 | /// the `try_finish` (or `shutdown`) method should be used instead. To | |
113 | /// re-acquire ownership of a stream it is safe to call this method after | |
114 | /// `try_finish` or `shutdown` has returned `Ok`. | |
115 | /// | |
116 | /// # Errors | |
117 | /// | |
118 | /// This function will perform I/O to complete this stream, and any I/O | |
119 | /// errors which occur will be returned from this function. | |
120 | pub fn finish(mut self) -> io::Result<W> { | |
121 | try!(self.inner.finish()); | |
122 | Ok(self.inner.take_inner()) | |
123 | } | |
124 | ||
125 | /// Consumes this encoder, flushing the output stream. | |
126 | /// | |
127 | /// This will flush the underlying data stream and then return the contained | |
128 | /// writer if the flush succeeded. | |
129 | /// The compressed stream will not closed but only flushed. This | |
130 | /// means that obtained byte array can by extended by another deflated | |
131 | /// stream. To close the stream add the two bytes 0x3 and 0x0. | |
132 | /// | |
133 | /// # Errors | |
134 | /// | |
135 | /// This function will perform I/O to complete this stream, and any I/O | |
136 | /// errors which occur will be returned from this function. | |
137 | pub fn flush_finish(mut self) -> io::Result<W> { | |
138 | try!(self.inner.flush()); | |
139 | Ok(self.inner.take_inner()) | |
140 | } | |
141 | ||
142 | /// Returns the number of bytes that have been written to this compresor. | |
143 | /// | |
144 | /// Note that not all bytes written to this object may be accounted for, | |
145 | /// there may still be some active buffering. | |
146 | pub fn total_in(&self) -> u64 { | |
147 | self.inner.data.total_in() | |
148 | } | |
149 | ||
150 | /// Returns the number of bytes that the compressor has produced. | |
151 | /// | |
152 | /// Note that not all bytes may have been written yet, some may still be | |
153 | /// buffered. | |
154 | pub fn total_out(&self) -> u64 { | |
155 | self.inner.data.total_out() | |
156 | } | |
157 | } | |
158 | ||
159 | impl<W: Write> Write for DeflateEncoder<W> { | |
160 | fn write(&mut self, buf: &[u8]) -> io::Result<usize> { | |
161 | self.inner.write(buf) | |
162 | } | |
163 | ||
164 | fn flush(&mut self) -> io::Result<()> { | |
165 | self.inner.flush() | |
166 | } | |
167 | } | |
168 | ||
169 | #[cfg(feature = "tokio")] | |
170 | impl<W: AsyncWrite> AsyncWrite for DeflateEncoder<W> { | |
171 | fn shutdown(&mut self) -> Poll<(), io::Error> { | |
172 | try_nb!(self.inner.finish()); | |
173 | self.inner.get_mut().shutdown() | |
174 | } | |
175 | } | |
176 | ||
177 | impl<W: Read + Write> Read for DeflateEncoder<W> { | |
178 | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { | |
179 | self.inner.get_mut().read(buf) | |
180 | } | |
181 | } | |
182 | ||
183 | #[cfg(feature = "tokio")] | |
184 | impl<W: AsyncRead + AsyncWrite> AsyncRead for DeflateEncoder<W> {} | |
185 | ||
186 | /// A DEFLATE decoder, or decompressor. | |
187 | /// | |
188 | /// This structure implements a [`Write`] and will emit a stream of decompressed | |
189 | /// data when fed a stream of compressed data. | |
190 | /// | |
191 | /// [`Write`]: https://doc.rust-lang.org/std/io/trait.Read.html | |
192 | /// | |
193 | /// # Examples | |
194 | /// | |
195 | /// ``` | |
196 | /// use std::io::prelude::*; | |
197 | /// use std::io; | |
198 | /// # use flate2::Compression; | |
199 | /// # use flate2::write::DeflateEncoder; | |
200 | /// use flate2::write::DeflateDecoder; | |
201 | /// | |
202 | /// # fn main() { | |
ff7c6d11 | 203 | /// # let mut e = DeflateEncoder::new(Vec::new(), Compression::default()); |
ea8adc8c XL |
204 | /// # e.write(b"Hello World").unwrap(); |
205 | /// # let bytes = e.finish().unwrap(); | |
206 | /// # println!("{}", decode_writer(bytes).unwrap()); | |
207 | /// # } | |
208 | /// // Uncompresses a Deflate Encoded vector of bytes and returns a string or error | |
209 | /// // Here Vec<u8> implements Write | |
210 | /// fn decode_writer(bytes: Vec<u8>) -> io::Result<String> { | |
211 | /// let mut writer = Vec::new(); | |
212 | /// let mut deflater = DeflateDecoder::new(writer); | |
213 | /// deflater.write(&bytes[..])?; | |
214 | /// writer = deflater.finish()?; | |
215 | /// let return_string = String::from_utf8(writer).expect("String parsing error"); | |
216 | /// Ok(return_string) | |
217 | /// } | |
218 | /// ``` | |
219 | #[derive(Debug)] | |
220 | pub struct DeflateDecoder<W: Write> { | |
221 | inner: zio::Writer<W, Decompress>, | |
222 | } | |
223 | ||
224 | ||
225 | impl<W: Write> DeflateDecoder<W> { | |
226 | /// Creates a new decoder which will write uncompressed data to the stream. | |
227 | /// | |
228 | /// When this encoder is dropped or unwrapped the final pieces of data will | |
229 | /// be flushed. | |
230 | pub fn new(w: W) -> DeflateDecoder<W> { | |
231 | DeflateDecoder { | |
232 | inner: zio::Writer::new(w, Decompress::new(false)), | |
233 | } | |
234 | } | |
235 | ||
236 | /// Acquires a reference to the underlying writer. | |
237 | pub fn get_ref(&self) -> &W { | |
238 | self.inner.get_ref() | |
239 | } | |
240 | ||
241 | /// Acquires a mutable reference to the underlying writer. | |
242 | /// | |
243 | /// Note that mutating the output/input state of the stream may corrupt this | |
244 | /// object, so care must be taken when using this method. | |
245 | pub fn get_mut(&mut self) -> &mut W { | |
246 | self.inner.get_mut() | |
247 | } | |
248 | ||
249 | /// Resets the state of this decoder entirely, swapping out the output | |
250 | /// stream for another. | |
251 | /// | |
252 | /// This function will finish encoding the current stream into the current | |
253 | /// output stream before swapping out the two output streams. | |
254 | /// | |
255 | /// This will then reset the internal state of this decoder and replace the | |
256 | /// output stream with the one provided, returning the previous output | |
257 | /// stream. Future data written to this decoder will be decompressed into | |
258 | /// the output stream `w`. | |
259 | /// | |
260 | /// # Errors | |
261 | /// | |
262 | /// This function will perform I/O to finish the stream, and if that I/O | |
263 | /// returns an error then that will be returned from this function. | |
264 | pub fn reset(&mut self, w: W) -> io::Result<W> { | |
265 | try!(self.inner.finish()); | |
266 | self.inner.data = Decompress::new(false); | |
267 | Ok(self.inner.replace(w)) | |
268 | } | |
269 | ||
270 | /// Attempt to finish this output stream, writing out final chunks of data. | |
271 | /// | |
272 | /// Note that this function can only be used once data has finished being | |
273 | /// written to the output stream. After this function is called then further | |
274 | /// calls to `write` may result in a panic. | |
275 | /// | |
276 | /// # Panics | |
277 | /// | |
278 | /// Attempts to write data to this stream may result in a panic after this | |
279 | /// function is called. | |
280 | /// | |
281 | /// # Errors | |
282 | /// | |
283 | /// This function will perform I/O to finish the stream, returning any | |
284 | /// errors which happen. | |
285 | pub fn try_finish(&mut self) -> io::Result<()> { | |
286 | self.inner.finish() | |
287 | } | |
288 | ||
289 | /// Consumes this encoder, flushing the output stream. | |
290 | /// | |
291 | /// This will flush the underlying data stream and then return the contained | |
292 | /// writer if the flush succeeded. | |
293 | /// | |
294 | /// Note that this function may not be suitable to call in a situation where | |
295 | /// the underlying stream is an asynchronous I/O stream. To finish a stream | |
296 | /// the `try_finish` (or `shutdown`) method should be used instead. To | |
297 | /// re-acquire ownership of a stream it is safe to call this method after | |
298 | /// `try_finish` or `shutdown` has returned `Ok`. | |
299 | /// | |
300 | /// # Errors | |
301 | /// | |
302 | /// This function will perform I/O to complete this stream, and any I/O | |
303 | /// errors which occur will be returned from this function. | |
304 | pub fn finish(mut self) -> io::Result<W> { | |
305 | try!(self.inner.finish()); | |
306 | Ok(self.inner.take_inner()) | |
307 | } | |
308 | ||
309 | /// Returns the number of bytes that the decompressor has consumed for | |
310 | /// decompression. | |
311 | /// | |
312 | /// Note that this will likely be smaller than the number of bytes | |
313 | /// successfully written to this stream due to internal buffering. | |
314 | pub fn total_in(&self) -> u64 { | |
315 | self.inner.data.total_in() | |
316 | } | |
317 | ||
318 | /// Returns the number of bytes that the decompressor has written to its | |
319 | /// output stream. | |
320 | pub fn total_out(&self) -> u64 { | |
321 | self.inner.data.total_out() | |
322 | } | |
323 | } | |
324 | ||
325 | impl<W: Write> Write for DeflateDecoder<W> { | |
326 | fn write(&mut self, buf: &[u8]) -> io::Result<usize> { | |
327 | self.inner.write(buf) | |
328 | } | |
329 | ||
330 | fn flush(&mut self) -> io::Result<()> { | |
331 | self.inner.flush() | |
332 | } | |
333 | } | |
334 | ||
335 | #[cfg(feature = "tokio")] | |
336 | impl<W: AsyncWrite> AsyncWrite for DeflateDecoder<W> { | |
337 | fn shutdown(&mut self) -> Poll<(), io::Error> { | |
338 | try_nb!(self.inner.finish()); | |
339 | self.inner.get_mut().shutdown() | |
340 | } | |
341 | } | |
342 | ||
343 | impl<W: Read + Write> Read for DeflateDecoder<W> { | |
344 | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { | |
345 | self.inner.get_mut().read(buf) | |
346 | } | |
347 | } | |
348 | ||
349 | #[cfg(feature = "tokio")] | |
350 | impl<W: AsyncRead + AsyncWrite> AsyncRead for DeflateDecoder<W> {} |