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