Skip to content

Commit

Permalink
Refactor to make calls to miniz more explicit
Browse files Browse the repository at this point in the history
Separate out the extra buffering added to implement the Read/Write interface
from the actual decompression/compression.
  • Loading branch information
alexcrichton committed Mar 3, 2015
1 parent 2077908 commit 6360d3e
Show file tree
Hide file tree
Showing 6 changed files with 352 additions and 251 deletions.
27 changes: 17 additions & 10 deletions src/deflate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,31 @@ use raw;
///
/// This structure implements a `Write` interface and takes a stream of
/// uncompressed data, writing the compressed data to the wrapped writer.
pub struct EncoderWriter<W> {
pub struct EncoderWriter<W: Write> {
inner: raw::EncoderWriter<W>,
}

/// A DEFLATE encoder, or compressor.
///
/// This structure implements a `Read` interface and will read uncompressed
/// data from an underlying stream and emit a stream of compressed data.
pub struct EncoderReader<R> {
pub struct EncoderReader<R: Read> {
inner: raw::EncoderReader<R>,
}

/// A DEFLATE decoder, or decompressor.
///
/// This structure implements a `Read` interface and takes a stream of
/// compressed data as input, providing the decompressed data when read from.
pub struct DecoderReader<R> {
pub struct DecoderReader<R: Read> {
inner: raw::DecoderReader<R>,
}

/// A DEFLATE decoder, or decompressor.
///
/// This structure implements a `Write` and will emit a stream of decompressed
/// data when fed a stream of compressed data.
pub struct DecoderWriter<W> {
pub struct DecoderWriter<W: Write> {
inner: raw::DecoderWriter<W>,
}

Expand All @@ -56,8 +56,8 @@ impl<W: Write> EncoderWriter<W> {
/// This will flush the underlying data stream and then return the contained
/// writer if the flush succeeded.
pub fn finish(mut self) -> io::Result<W> {
try!(self.inner.do_finish());
Ok(self.inner.inner.take().unwrap())
try!(self.inner.finish());
Ok(self.inner.into_inner())
}
}

Expand All @@ -78,12 +78,14 @@ impl<R: Read> EncoderReader<R> {

/// Consumes this encoder, returning the underlying reader.
pub fn into_inner(self) -> R {
self.inner.inner
self.inner.into_inner()
}
}

impl<R: Read> Read for EncoderReader<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.inner.read(buf) }
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf)
}
}

impl<R: Read> DecoderReader<R> {
Expand All @@ -100,6 +102,11 @@ impl<R: Read> DecoderReader<R> {
pub fn new_with_buf(r: R, buf: Vec<u8>) -> DecoderReader<R> {
DecoderReader { inner: raw::DecoderReader::new(r, true, buf) }
}

/// Consumes this decoder, returning the underlying reader.
pub fn into_inner(self) -> R {
self.inner.into_inner()
}
}

impl<R: Read> Read for DecoderReader<R> {
Expand All @@ -125,8 +132,8 @@ impl<W: Write> DecoderWriter<W> {
/// This will flush the underlying data stream and then return the contained
/// writer if the flush succeeded.
pub fn finish(mut self) -> io::Result<W> {
try!(self.inner.do_finish());
Ok(self.inner.inner.take().unwrap())
try!(self.inner.finish());
Ok(self.inner.into_inner())
}
}

Expand Down
43 changes: 19 additions & 24 deletions src/gz.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ static FCOMMENT: u8 = 1 << 4;
///
/// This structure exposes a `Write` interface that will emit compressed data
/// to the underlying writer `W`.
pub struct EncoderWriter<W> {
pub struct EncoderWriter<W: Write> {
inner: raw::EncoderWriter<W>,
crc: Crc,
header: Vec<u8>,
Expand All @@ -35,7 +35,7 @@ pub struct EncoderWriter<W> {
/// This structure exposes a `Read` interface that will read uncompressed data
/// from the underlying reader and expose the compressed version as a `Read`
/// interface.
pub struct EncoderReader<R> {
pub struct EncoderReader<R: Read> {
inner: raw::EncoderReader<CrcReader<R>>,
header: Vec<u8>,
pos: usize,
Expand All @@ -56,7 +56,7 @@ pub struct Builder {
///
/// This structure exposes a `Read` interface that will consume compressed
/// data from the underlying reader and emit uncompressed data.
pub struct DecoderReader<R> {
pub struct DecoderReader<R: Read> {
inner: CrcReader<raw::DecoderReader<R>>,
header: Header,
}
Expand Down Expand Up @@ -207,8 +207,8 @@ impl<W: Write> EncoderWriter<W> {
if self.header.len() != 0 {
try!(self.inner.write_all(&self.header));
}
try!(self.inner.do_finish());
let mut inner = self.inner.inner.take().unwrap();
try!(self.inner.finish());
let mut inner = self.inner.take_inner();
let (sum, amt) = (self.crc.sum() as u32, self.crc.amt());
let buf = [
(sum >> 0) as u8,
Expand All @@ -228,7 +228,7 @@ impl<W: Write> EncoderWriter<W> {
impl<W: Write> Write for EncoderWriter<W> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
if self.header.len() != 0 {
try!(self.inner.inner.as_mut().unwrap().write_all(&self.header));
try!(self.inner.write_all_raw(&self.header));
self.header.truncate(0);
}
let n = try!(self.inner.write(buf));
Expand All @@ -242,7 +242,7 @@ impl<W: Write> Write for EncoderWriter<W> {
#[unsafe_destructor]
impl<W: Write> Drop for EncoderWriter<W> {
fn drop(&mut self) {
if self.inner.inner.is_some() {
if !self.inner.unwrapped() {
let _ = self.do_finish();
}
}
Expand All @@ -262,20 +262,21 @@ impl<R: Read> EncoderReader<R> {

/// Returns the underlying stream, consuming this encoder
pub fn into_inner(self) -> R {
self.inner.inner.into_inner()
self.inner.into_inner().into_inner()
}

fn read_footer(&mut self, into: &mut [u8]) -> io::Result<usize> {
if self.pos == 8 { return Ok(0) }
let crc = self.inner.get_ref().crc();
let ref arr = [
(self.inner.inner.crc().sum() >> 0) as u8,
(self.inner.inner.crc().sum() >> 8) as u8,
(self.inner.inner.crc().sum() >> 16) as u8,
(self.inner.inner.crc().sum() >> 24) as u8,
(self.inner.inner.crc().amt() >> 0) as u8,
(self.inner.inner.crc().amt() >> 8) as u8,
(self.inner.inner.crc().amt() >> 16) as u8,
(self.inner.inner.crc().amt() >> 24) as u8,
(crc.sum() >> 0) as u8,
(crc.sum() >> 8) as u8,
(crc.sum() >> 16) as u8,
(crc.sum() >> 24) as u8,
(crc.amt() >> 0) as u8,
(crc.amt() >> 8) as u8,
(crc.amt() >> 16) as u8,
(crc.amt() >> 24) as u8,
];
Ok(copy(into, arr, &mut self.pos))
}
Expand Down Expand Up @@ -413,16 +414,10 @@ impl<R: Read> DecoderReader<R> {
fn finish(&mut self) -> io::Result<()> {
let ref mut buf = [0u8; 8];
{
let flate = self.inner.inner();
let mut len = {
let remaining = &flate.buf[flate.pos..];
let len = cmp::min(remaining.len(), buf.len());
bytes::copy_memory(buf, &remaining[..len]);
len
};
let mut len = 0;

while len < buf.len() {
match try!(flate.inner.read(&mut buf[len..])) {
match try!(self.inner.inner().read_raw(&mut buf[len..])) {
0 => return Err(corrupt()),
n => len += n,
}
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ mod deflate;
mod gz;
mod raw;
mod zlib;
mod stream;

/// Types which operate over `Reader` streams, both encoders and decoders for
/// various formats.
Expand Down
Loading

0 comments on commit 6360d3e

Please sign in to comment.