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 ZLIB 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::ZlibEncoder; 25 /// 26 /// // Vec<u8> implements Write, assigning the compressed bytes of sample string 27 /// 28 /// # fn zlib_encoding() -> std::io::Result<()> { 29 /// let mut e = ZlibEncoder::new(Vec::new(), Compression::default()); 30 /// e.write_all(b"Hello World")?; 31 /// let compressed = e.finish()?; 32 /// # Ok(()) 33 /// # } 34 /// ``` 35 #[derive(Debug)] 36 pub struct ZlibEncoder<W: Write> { 37 inner: zio::Writer<W, Compress>, 38 } 39 40 impl<W: Write> ZlibEncoder<W> { 41 /// Creates a new encoder which will write compressed data to the stream 42 /// given at the given compression level. 43 /// 44 /// When this encoder is dropped or unwrapped the final pieces of data will 45 /// be flushed. new(w: W, level: crate::Compression) -> ZlibEncoder<W>46 pub fn new(w: W, level: crate::Compression) -> ZlibEncoder<W> { 47 ZlibEncoder { 48 inner: zio::Writer::new(w, Compress::new(level, true)), 49 } 50 } 51 52 /// Acquires a reference to the underlying writer. get_ref(&self) -> &W53 pub fn get_ref(&self) -> &W { 54 self.inner.get_ref() 55 } 56 57 /// Acquires a mutable reference to the underlying writer. 58 /// 59 /// Note that mutating the output/input state of the stream may corrupt this 60 /// object, so care must be taken when using this method. get_mut(&mut self) -> &mut W61 pub fn get_mut(&mut self) -> &mut W { 62 self.inner.get_mut() 63 } 64 65 /// Resets the state of this encoder entirely, swapping out the output 66 /// stream for another. 67 /// 68 /// This function will finish encoding the current stream into the current 69 /// output stream before swapping out the two output streams. 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 ZlibEncoder<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 ZlibEncoder<W> { shutdown(&mut self) -> Poll<(), io::Error>171 fn shutdown(&mut self) -> Poll<(), io::Error> { 172 self.try_finish()?; 173 self.get_mut().shutdown() 174 } 175 } 176 177 impl<W: Read + Write> Read for ZlibEncoder<W> { read(&mut self, buf: &mut [u8]) -> io::Result<usize>178 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { 179 self.get_mut().read(buf) 180 } 181 } 182 183 #[cfg(feature = "tokio")] 184 impl<W: AsyncRead + AsyncWrite> AsyncRead for ZlibEncoder<W> {} 185 186 /// A ZLIB 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.Write.html 192 /// 193 /// # Examples 194 /// 195 /// ``` 196 /// use std::io::prelude::*; 197 /// use std::io; 198 /// # use flate2::Compression; 199 /// # use flate2::write::ZlibEncoder; 200 /// use flate2::write::ZlibDecoder; 201 /// 202 /// # fn main() { 203 /// # let mut e = ZlibEncoder::new(Vec::new(), Compression::default()); 204 /// # e.write_all(b"Hello World").unwrap(); 205 /// # let bytes = e.finish().unwrap(); 206 /// # println!("{}", decode_reader(bytes).unwrap()); 207 /// # } 208 /// # 209 /// // Uncompresses a Zlib Encoded vector of bytes and returns a string or error 210 /// // Here Vec<u8> implements Write 211 /// 212 /// fn decode_reader(bytes: Vec<u8>) -> io::Result<String> { 213 /// let mut writer = Vec::new(); 214 /// let mut z = ZlibDecoder::new(writer); 215 /// z.write_all(&bytes[..])?; 216 /// writer = z.finish()?; 217 /// let return_string = String::from_utf8(writer).expect("String parsing error"); 218 /// Ok(return_string) 219 /// } 220 /// ``` 221 #[derive(Debug)] 222 pub struct ZlibDecoder<W: Write> { 223 inner: zio::Writer<W, Decompress>, 224 } 225 226 impl<W: Write> ZlibDecoder<W> { 227 /// Creates a new decoder which will write uncompressed data to the stream. 228 /// 229 /// When this decoder is dropped or unwrapped the final pieces of data will 230 /// be flushed. new(w: W) -> ZlibDecoder<W>231 pub fn new(w: W) -> ZlibDecoder<W> { 232 ZlibDecoder { 233 inner: zio::Writer::new(w, Decompress::new(true)), 234 } 235 } 236 237 /// Acquires a reference to the underlying writer. get_ref(&self) -> &W238 pub fn get_ref(&self) -> &W { 239 self.inner.get_ref() 240 } 241 242 /// Acquires a mutable reference to the underlying writer. 243 /// 244 /// Note that mutating the output/input state of the stream may corrupt this 245 /// object, so care must be taken when using this method. get_mut(&mut self) -> &mut W246 pub fn get_mut(&mut self) -> &mut W { 247 self.inner.get_mut() 248 } 249 250 /// Resets the state of this decoder entirely, swapping out the output 251 /// stream for another. 252 /// 253 /// This will reset the internal state of this decoder and replace the 254 /// output stream with the one provided, returning the previous output 255 /// stream. Future data written to this decoder will be decompressed into 256 /// the output stream `w`. 257 /// 258 /// # Errors 259 /// 260 /// This function will perform I/O to complete this stream, and any I/O 261 /// errors which occur will be returned from this function. reset(&mut self, w: W) -> io::Result<W>262 pub fn reset(&mut self, w: W) -> io::Result<W> { 263 self.inner.finish()?; 264 self.inner.data = Decompress::new(true); 265 Ok(self.inner.replace(w)) 266 } 267 268 /// Attempt to finish this output stream, writing out final chunks of data. 269 /// 270 /// Note that this function can only be used once data has finished being 271 /// written to the output stream. After this function is called then further 272 /// calls to `write` may result in a panic. 273 /// 274 /// # Panics 275 /// 276 /// Attempts to write data to this stream may result in a panic after this 277 /// function is called. 278 /// 279 /// # Errors 280 /// 281 /// This function will perform I/O to complete this stream, and any I/O 282 /// errors which occur will be returned from this function. try_finish(&mut self) -> io::Result<()>283 pub fn try_finish(&mut self) -> io::Result<()> { 284 self.inner.finish() 285 } 286 287 /// Consumes this encoder, flushing the output stream. 288 /// 289 /// This will flush the underlying data stream and then return the contained 290 /// writer if the flush succeeded. 291 /// 292 /// Note that this function may not be suitable to call in a situation where 293 /// the underlying stream is an asynchronous I/O stream. To finish a stream 294 /// the `try_finish` (or `shutdown`) method should be used instead. To 295 /// re-acquire ownership of a stream it is safe to call this method after 296 /// `try_finish` or `shutdown` has returned `Ok`. 297 /// 298 /// # Errors 299 /// 300 /// This function will perform I/O to complete this stream, and any I/O 301 /// errors which occur will be returned from this function. finish(mut self) -> io::Result<W>302 pub fn finish(mut self) -> io::Result<W> { 303 self.inner.finish()?; 304 Ok(self.inner.take_inner()) 305 } 306 307 /// Returns the number of bytes that the decompressor has consumed for 308 /// decompression. 309 /// 310 /// Note that this will likely be smaller than the number of bytes 311 /// successfully written to this stream due to internal buffering. total_in(&self) -> u64312 pub fn total_in(&self) -> u64 { 313 self.inner.data.total_in() 314 } 315 316 /// Returns the number of bytes that the decompressor has written to its 317 /// output stream. total_out(&self) -> u64318 pub fn total_out(&self) -> u64 { 319 self.inner.data.total_out() 320 } 321 } 322 323 impl<W: Write> Write for ZlibDecoder<W> { write(&mut self, buf: &[u8]) -> io::Result<usize>324 fn write(&mut self, buf: &[u8]) -> io::Result<usize> { 325 self.inner.write(buf) 326 } 327 flush(&mut self) -> io::Result<()>328 fn flush(&mut self) -> io::Result<()> { 329 self.inner.flush() 330 } 331 } 332 333 #[cfg(feature = "tokio")] 334 impl<W: AsyncWrite> AsyncWrite for ZlibDecoder<W> { shutdown(&mut self) -> Poll<(), io::Error>335 fn shutdown(&mut self) -> Poll<(), io::Error> { 336 self.inner.finish()?; 337 self.inner.get_mut().shutdown() 338 } 339 } 340 341 impl<W: Read + Write> Read for ZlibDecoder<W> { read(&mut self, buf: &mut [u8]) -> io::Result<usize>342 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { 343 self.inner.get_mut().read(buf) 344 } 345 } 346 347 #[cfg(feature = "tokio")] 348 impl<W: AsyncRead + AsyncWrite> AsyncRead for ZlibDecoder<W> {} 349