Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ codecov = {repository = "sile/libflate"}
adler32 = "1"
byteorder = "1"
crc32fast = "1"
take_mut = "0.2.2"

[dev-dependencies]
clap = "2"
49 changes: 26 additions & 23 deletions src/gzip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ use byteorder::ReadBytesExt;
use byteorder::WriteBytesExt;
use std::ffi::CString;
use std::io;
use std::mem;
use std::time;

use checksum;
Expand Down Expand Up @@ -1118,33 +1117,37 @@ where
Err(_) => return Ok(0),
Ok(ref mut decoder) => decoder.read(buf)?,
};
// take_mut closure must have the type it borrows as return type,
// so we put the function return result to this variable instead.
// If function logic is correct, these initial values will never be returned.
let mut result: io::Result<usize> = Err(
io::Error::new(io::ErrorKind::Other, "If you see this error, please report a bug in libflate")
);
if read_size == 0 {
let mut reader = mem::replace(&mut self.decoder, Err(unsafe { mem::uninitialized() }))
.ok()
.take()
.expect("Never fails")
.into_inner();
match Header::read_from(&mut reader) {
Err(e) => {
mem::forget(mem::replace(&mut self.decoder, Err(reader)));
if e.kind() == io::ErrorKind::UnexpectedEof {
Ok(0)
} else {
Err(e)
take_mut::take(self, |mut owned_self| {
let mut reader = owned_self.decoder.ok().take().expect("Never fails").into_inner();
match Header::read_from(&mut reader) {
Err(e) => {
if e.kind() == io::ErrorKind::UnexpectedEof {
result = Ok(0);
} else {
result = Err(e);
}
owned_self.decoder = Err(reader);
owned_self
}
Ok(header) => {
owned_self.header = header.clone();
owned_self.decoder = Ok(Decoder::with_header(reader, header));
result = owned_self.read(buf);
owned_self
}
}
Ok(header) => {
self.header = header.clone();
mem::forget(mem::replace(
&mut self.decoder,
Ok(Decoder::with_header(reader, header)),
));
self.read(buf)
}
}
})
} else {
Ok(read_size)
result = Ok(read_size);
}
result
}
}

Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
extern crate adler32;
extern crate byteorder;
extern crate crc32fast;
extern crate take_mut;

pub use finish::Finish;

Expand Down