| use std::io; |
| use std::io::Read; |
| use std::cmp; |
| use std::ptr; |
| use byteorder::ReadBytesExt; |
| use byteorder::LittleEndian; |
| |
| use lz77; |
| use util; |
| use deflate::symbol::{self, HuffmanCodec}; |
| use non_blocking::transaction::TransactionalBitReader; |
| |
| /// DEFLATE decoder which supports non-blocking I/O. |
| #[derive(Debug)] |
| pub struct Decoder<R> { |
| state: DecoderState, |
| eos: bool, |
| bit_reader: TransactionalBitReader<R>, |
| block_decoder: BlockDecoder, |
| } |
| impl<R: Read> Decoder<R> { |
| /// Makes a new decoder instance. |
| /// |
| /// `inner` is to be decoded DEFLATE stream. |
| /// |
| /// # Examples |
| /// ``` |
| /// use std::io::{Cursor, Read}; |
| /// use libflate::non_blocking::deflate::Decoder; |
| /// |
| /// let encoded_data = [243, 72, 205, 201, 201, 87, 8, 207, 47, 202, 73, 81, 4, 0]; |
| /// let mut decoder = Decoder::new(&encoded_data[..]); |
| /// let mut buf = Vec::new(); |
| /// decoder.read_to_end(&mut buf).unwrap(); |
| /// |
| /// assert_eq!(buf, b"Hello World!"); |
| /// ``` |
| pub fn new(inner: R) -> Self { |
| Decoder { |
| state: DecoderState::ReadBlockHeader, |
| eos: false, |
| bit_reader: TransactionalBitReader::new(inner), |
| block_decoder: BlockDecoder::new(), |
| } |
| } |
| |
| /// Returns the immutable reference to the inner stream. |
| pub fn as_inner_ref(&self) -> &R { |
| self.bit_reader.as_inner_ref() |
| } |
| |
| /// Returns the mutable reference to the inner stream. |
| pub fn as_inner_mut(&mut self) -> &mut R { |
| self.bit_reader.as_inner_mut() |
| } |
| |
| /// Unwraps this `Decoder`, returning the underlying reader. |
| /// |
| /// # Examples |
| /// ``` |
| /// use std::io::Cursor; |
| /// use libflate::non_blocking::deflate::Decoder; |
| /// |
| /// let encoded_data = [243, 72, 205, 201, 201, 87, 8, 207, 47, 202, 73, 81, 4, 0]; |
| /// let decoder = Decoder::new(Cursor::new(&encoded_data)); |
| /// assert_eq!(decoder.into_inner().into_inner(), &encoded_data); |
| /// ``` |
| pub fn into_inner(self) -> R { |
| self.bit_reader.into_inner() |
| } |
| |
| pub(crate) fn bit_reader_mut(&mut self) -> &mut TransactionalBitReader<R> { |
| &mut self.bit_reader |
| } |
| } |
| impl<R: Read> Read for Decoder<R> { |
| fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |
| let mut read_size; |
| loop { |
| let next = match self.state { |
| DecoderState::ReadBlockHeader => { |
| let (bfinal, btype) = self.bit_reader.transaction(|r| { |
| let bfinal = r.read_bit()?; |
| let btype = r.read_bits(2)?; |
| Ok((bfinal, btype)) |
| })?; |
| self.eos = bfinal; |
| self.block_decoder.enter_new_block(); |
| match btype { |
| 0b00 => DecoderState::ReadNonCompressedBlockLen, |
| 0b01 => DecoderState::LoadFixedHuffmanCode, |
| 0b10 => DecoderState::LoadDynamicHuffmanCode, |
| 0b11 => { |
| return Err(invalid_data_error!( |
| "btype 0x11 of DEFLATE is reserved(error) value" |
| )) |
| } |
| _ => unreachable!(), |
| } |
| } |
| DecoderState::ReadNonCompressedBlockLen => { |
| let len = self.bit_reader.transaction(|r| { |
| r.reset(); |
| let len = r.as_inner_mut().read_u16::<LittleEndian>()?; |
| let nlen = r.as_inner_mut().read_u16::<LittleEndian>()?; |
| if !len != nlen { |
| Err(invalid_data_error!( |
| "LEN={} is not the one's complement of NLEN={}", |
| len, |
| nlen |
| )) |
| } else { |
| Ok(len) |
| } |
| })?; |
| self.block_decoder.buffer.reserve(len as usize); |
| DecoderState::ReadNonCompressedBlock { len } |
| } |
| DecoderState::ReadNonCompressedBlock { len: 0 } => { |
| if self.eos { |
| read_size = 0; |
| break; |
| } else { |
| DecoderState::ReadBlockHeader |
| } |
| } |
| DecoderState::ReadNonCompressedBlock { ref mut len } => { |
| let buf_len = buf.len(); |
| let buf = &mut buf[..cmp::min(buf_len, *len as usize)]; |
| read_size = self.bit_reader.as_inner_mut().read(buf)?; |
| |
| self.block_decoder.buffer.extend(&buf[..read_size]); |
| *len -= read_size as u16; |
| break; |
| } |
| DecoderState::LoadFixedHuffmanCode => { |
| let symbol_decoder = self.bit_reader.transaction( |
| |r| symbol::FixedHuffmanCodec.load(r), |
| )?; |
| DecoderState::DecodeBlock(symbol_decoder) |
| } |
| DecoderState::LoadDynamicHuffmanCode => { |
| let symbol_decoder = self.bit_reader.transaction( |
| |r| symbol::DynamicHuffmanCodec.load(r), |
| )?; |
| DecoderState::DecodeBlock(symbol_decoder) |
| } |
| DecoderState::DecodeBlock(ref mut symbol_decoder) => { |
| self.block_decoder.decode( |
| &mut self.bit_reader, |
| symbol_decoder, |
| )?; |
| read_size = self.block_decoder.read(buf)?; |
| if read_size == 0 && !buf.is_empty() && !self.eos { |
| DecoderState::ReadBlockHeader |
| } else { |
| break; |
| } |
| } |
| }; |
| self.state = next; |
| } |
| Ok(read_size) |
| } |
| } |
| |
| #[derive(Debug)] |
| enum DecoderState { |
| ReadBlockHeader, |
| ReadNonCompressedBlockLen, |
| ReadNonCompressedBlock { len: u16 }, |
| LoadFixedHuffmanCode, |
| LoadDynamicHuffmanCode, |
| DecodeBlock(symbol::Decoder), |
| } |
| |
| #[derive(Debug)] |
| struct BlockDecoder { |
| buffer: Vec<u8>, |
| offset: usize, |
| eob: bool, |
| } |
| impl BlockDecoder { |
| pub fn new() -> Self { |
| BlockDecoder { |
| buffer: Vec::new(), |
| offset: 0, |
| eob: false, |
| } |
| } |
| pub fn enter_new_block(&mut self) { |
| self.eob = false; |
| self.truncate_old_buffer(); |
| } |
| pub fn decode<R: Read>( |
| &mut self, |
| bit_reader: &mut TransactionalBitReader<R>, |
| symbol_decoder: &mut symbol::Decoder, |
| ) -> io::Result<()> { |
| if self.eob { |
| return Ok(()); |
| } |
| while let Some(s) = self.decode_symbol(bit_reader, symbol_decoder)? { |
| match s { |
| symbol::Symbol::Literal(b) => { |
| self.buffer.push(b); |
| } |
| symbol::Symbol::Share { length, distance } => { |
| if self.buffer.len() < distance as usize { |
| return Err(invalid_data_error!( |
| "Too long backword reference: buffer.len={}, distance={}", |
| self.buffer.len(), |
| distance |
| )); |
| } |
| let old_len = self.buffer.len(); |
| self.buffer.reserve(length as usize); |
| unsafe { |
| self.buffer.set_len(old_len + length as usize); |
| let start = old_len - distance as usize; |
| let ptr = self.buffer.as_mut_ptr(); |
| util::ptr_copy( |
| ptr.offset(start as isize), |
| ptr.offset(old_len as isize), |
| length as usize, |
| length > distance, |
| ); |
| } |
| } |
| symbol::Symbol::EndOfBlock => { |
| self.eob = true; |
| break; |
| } |
| } |
| } |
| Ok(()) |
| } |
| fn truncate_old_buffer(&mut self) { |
| if self.buffer.len() > lz77::MAX_DISTANCE as usize * 4 { |
| let new_len = lz77::MAX_DISTANCE as usize; |
| unsafe { |
| let ptr = self.buffer.as_mut_ptr(); |
| let src = ptr.offset((self.buffer.len() - new_len) as isize); |
| ptr::copy_nonoverlapping(src, ptr, new_len); |
| } |
| self.buffer.truncate(new_len); |
| self.offset = new_len; |
| } |
| } |
| fn decode_symbol<R: Read>( |
| &mut self, |
| bit_reader: &mut TransactionalBitReader<R>, |
| symbol_decoder: &mut symbol::Decoder, |
| ) -> io::Result<Option<symbol::Symbol>> { |
| let result = bit_reader.transaction(|bit_reader| { |
| let s = symbol_decoder.decode_unchecked(bit_reader); |
| bit_reader.check_last_error().map(|()| s) |
| }); |
| match result { |
| Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => Ok(None), |
| Err(e) => Err(e), |
| Ok(s) => Ok(Some(s)), |
| } |
| } |
| } |
| impl Read for BlockDecoder { |
| fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |
| if self.offset < self.buffer.len() { |
| let copy_size = cmp::min(buf.len(), self.buffer.len() - self.offset); |
| buf[..copy_size].copy_from_slice(&self.buffer[self.offset..][..copy_size]); |
| self.offset += copy_size; |
| Ok(copy_size) |
| } else if self.eob { |
| Ok(0) |
| } else { |
| Err(io::Error::new(io::ErrorKind::WouldBlock, "Would block")) |
| } |
| } |
| } |
| |
| #[cfg(test)] |
| mod test { |
| use std::io::{self, Read}; |
| use deflate::{Encoder, EncodeOptions}; |
| use util::{nb_read_to_end, WouldBlockReader}; |
| use super::*; |
| |
| #[test] |
| fn it_works() { |
| let mut encoder = Encoder::new(Vec::new()); |
| io::copy(&mut &b"Hello World!"[..], &mut encoder).unwrap(); |
| let encoded_data = encoder.finish().into_result().unwrap(); |
| |
| let mut decoder = Decoder::new(&encoded_data[..]); |
| let mut decoded_data = Vec::new(); |
| decoder.read_to_end(&mut decoded_data).unwrap(); |
| |
| assert_eq!(decoded_data, b"Hello World!"); |
| } |
| |
| #[test] |
| fn non_blocking_io_works() { |
| let mut encoder = Encoder::new(Vec::new()); |
| io::copy(&mut &b"Hello World!"[..], &mut encoder).unwrap(); |
| let encoded_data = encoder.finish().into_result().unwrap(); |
| |
| let decoder = Decoder::new(WouldBlockReader::new(&encoded_data[..])); |
| let decoded_data = nb_read_to_end(decoder).unwrap(); |
| |
| assert_eq!(decoded_data, b"Hello World!"); |
| } |
| |
| #[test] |
| fn non_compressed_non_blocking_io_works() { |
| let mut encoder = Encoder::with_options(Vec::new(), EncodeOptions::new().no_compression()); |
| io::copy(&mut &b"Hello World!"[..], &mut encoder).unwrap(); |
| let encoded_data = encoder.finish().into_result().unwrap(); |
| |
| let decoder = Decoder::new(WouldBlockReader::new(&encoded_data[..])); |
| let decoded_data = nb_read_to_end(decoder).unwrap(); |
| |
| assert_eq!(decoded_data, b"Hello World!"); |
| } |
| } |