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 crate::zio; 10 use crate::{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 /// 29 /// let mut e = DeflateEncoder::new(Vec::new(), Compression::default()); 30 /// e.write_all(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. new(w: W, level: crate::Compression) -> DeflateEncoder<W>45 pub fn new(w: W, level: crate::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. get_ref(&self) -> &W52 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. get_mut(&mut self) -> &mut W60 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. reset(&mut self, w: W) -> io::Result<W>80 pub fn reset(&mut self, w: W) -> io::Result<W> { 81 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. try_finish(&mut self) -> io::Result<()>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. finish(mut self) -> io::Result<W>120 pub fn finish(mut self) -> io::Result<W> { 121 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. flush_finish(mut self) -> io::Result<W>137 pub fn flush_finish(mut self) -> io::Result<W> { 138 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. total_in(&self) -> u64146 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. total_out(&self) -> u64154 pub fn total_out(&self) -> u64 { 155 self.inner.data.total_out() 156 } 157 } 158 159 impl<W: Write> Write for DeflateEncoder<W> { write(&mut self, buf: &[u8]) -> io::Result<usize>160 fn write(&mut self, buf: &[u8]) -> io::Result<usize> { 161 self.inner.write(buf) 162 } 163 flush(&mut self) -> io::Result<()>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> { shutdown(&mut self) -> Poll<(), io::Error>171 fn shutdown(&mut self) -> Poll<(), io::Error> { 172 self.inner.finish()?; 173 self.inner.get_mut().shutdown() 174 } 175 } 176 177 impl<W: Read + Write> Read for DeflateEncoder<W> { read(&mut self, buf: &mut [u8]) -> io::Result<usize>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() { 203 /// # let mut e = DeflateEncoder::new(Vec::new(), Compression::default()); 204 /// # e.write_all(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_all(&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 impl<W: Write> DeflateDecoder<W> { 225 /// Creates a new decoder which will write uncompressed data to the stream. 226 /// 227 /// When this encoder is dropped or unwrapped the final pieces of data will 228 /// be flushed. new(w: W) -> DeflateDecoder<W>229 pub fn new(w: W) -> DeflateDecoder<W> { 230 DeflateDecoder { 231 inner: zio::Writer::new(w, Decompress::new(false)), 232 } 233 } 234 235 /// Acquires a reference to the underlying writer. get_ref(&self) -> &W236 pub fn get_ref(&self) -> &W { 237 self.inner.get_ref() 238 } 239 240 /// Acquires a mutable reference to the underlying writer. 241 /// 242 /// Note that mutating the output/input state of the stream may corrupt this 243 /// object, so care must be taken when using this method. get_mut(&mut self) -> &mut W244 pub fn get_mut(&mut self) -> &mut W { 245 self.inner.get_mut() 246 } 247 248 /// Resets the state of this decoder entirely, swapping out the output 249 /// stream for another. 250 /// 251 /// This function will finish encoding the current stream into the current 252 /// output stream before swapping out the two output streams. 253 /// 254 /// This will then reset the internal state of this decoder and replace the 255 /// output stream with the one provided, returning the previous output 256 /// stream. Future data written to this decoder will be decompressed into 257 /// the output stream `w`. 258 /// 259 /// # Errors 260 /// 261 /// This function will perform I/O to finish the stream, and if that I/O 262 /// returns an error then that will be returned from this function. reset(&mut self, w: W) -> io::Result<W>263 pub fn reset(&mut self, w: W) -> io::Result<W> { 264 self.inner.finish()?; 265 self.inner.data = Decompress::new(false); 266 Ok(self.inner.replace(w)) 267 } 268 269 /// Attempt to finish this output stream, writing out final chunks of data. 270 /// 271 /// Note that this function can only be used once data has finished being 272 /// written to the output stream. After this function is called then further 273 /// calls to `write` may result in a panic. 274 /// 275 /// # Panics 276 /// 277 /// Attempts to write data to this stream may result in a panic after this 278 /// function is called. 279 /// 280 /// # Errors 281 /// 282 /// This function will perform I/O to finish the stream, returning any 283 /// errors which happen. try_finish(&mut self) -> io::Result<()>284 pub fn try_finish(&mut self) -> io::Result<()> { 285 self.inner.finish() 286 } 287 288 /// Consumes this encoder, flushing the output stream. 289 /// 290 /// This will flush the underlying data stream and then return the contained 291 /// writer if the flush succeeded. 292 /// 293 /// Note that this function may not be suitable to call in a situation where 294 /// the underlying stream is an asynchronous I/O stream. To finish a stream 295 /// the `try_finish` (or `shutdown`) method should be used instead. To 296 /// re-acquire ownership of a stream it is safe to call this method after 297 /// `try_finish` or `shutdown` has returned `Ok`. 298 /// 299 /// # Errors 300 /// 301 /// This function will perform I/O to complete this stream, and any I/O 302 /// errors which occur will be returned from this function. finish(mut self) -> io::Result<W>303 pub fn finish(mut self) -> io::Result<W> { 304 self.inner.finish()?; 305 Ok(self.inner.take_inner()) 306 } 307 308 /// Returns the number of bytes that the decompressor has consumed for 309 /// decompression. 310 /// 311 /// Note that this will likely be smaller than the number of bytes 312 /// successfully written to this stream due to internal buffering. total_in(&self) -> u64313 pub fn total_in(&self) -> u64 { 314 self.inner.data.total_in() 315 } 316 317 /// Returns the number of bytes that the decompressor has written to its 318 /// output stream. total_out(&self) -> u64319 pub fn total_out(&self) -> u64 { 320 self.inner.data.total_out() 321 } 322 } 323 324 impl<W: Write> Write for DeflateDecoder<W> { write(&mut self, buf: &[u8]) -> io::Result<usize>325 fn write(&mut self, buf: &[u8]) -> io::Result<usize> { 326 self.inner.write(buf) 327 } 328 flush(&mut self) -> io::Result<()>329 fn flush(&mut self) -> io::Result<()> { 330 self.inner.flush() 331 } 332 } 333 334 #[cfg(feature = "tokio")] 335 impl<W: AsyncWrite> AsyncWrite for DeflateDecoder<W> { shutdown(&mut self) -> Poll<(), io::Error>336 fn shutdown(&mut self) -> Poll<(), io::Error> { 337 self.inner.finish()?; 338 self.inner.get_mut().shutdown() 339 } 340 } 341 342 impl<W: Read + Write> Read for DeflateDecoder<W> { read(&mut self, buf: &mut [u8]) -> io::Result<usize>343 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { 344 self.inner.get_mut().read(buf) 345 } 346 } 347 348 #[cfg(feature = "tokio")] 349 impl<W: AsyncRead + AsyncWrite> AsyncRead for DeflateDecoder<W> {} 350