diff --git a/libraries/libarchive/src/archive.rs b/libraries/libarchive/src/archive.rs index 06163780..e680965d 100644 --- a/libraries/libarchive/src/archive.rs +++ b/libraries/libarchive/src/archive.rs @@ -3,6 +3,7 @@ use std::str; use std::ffi::CStr; use libarchive3_sys::ffi; +use error::ErrCode; pub enum ReadCompression { All, @@ -93,8 +94,9 @@ pub enum WriteFilter { pub trait Handle { unsafe fn handle(&self) -> *mut ffi::Struct_archive; - fn err_code(&self) -> i32 { - unsafe { ffi::archive_errno(self.handle()) } + fn err_code(&self) -> ErrCode { + let code = unsafe { ffi::archive_errno(self.handle()) }; + ErrCode(code) } fn err_msg(&self) -> String { diff --git a/libraries/libarchive/src/error.rs b/libraries/libarchive/src/error.rs index 0c5c70de..7d22effb 100644 --- a/libraries/libarchive/src/error.rs +++ b/libraries/libarchive/src/error.rs @@ -5,7 +5,7 @@ use archive; pub type ArchiveResult = Result; #[derive(Debug)] -pub struct ErrCode(i32); +pub struct ErrCode(pub i32); impl fmt::Display for ErrCode { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { @@ -44,20 +44,14 @@ impl fmt::Display for ArchiveError { impl<'a> From<&'a archive::Handle> for ArchiveError { fn from(handle: &'a archive::Handle) -> ArchiveError { - ArchiveError::Sys(ErrCode::from(handle), handle.err_msg()) - } -} - -impl<'a> From<&'a archive::Handle> for ErrCode { - fn from(handle: &'a archive::Handle) -> ErrCode { - ErrCode(handle.err_code()) + ArchiveError::Sys(handle.err_code(), handle.err_msg()) } } impl<'a> From<&'a archive::Handle> for ArchiveResult<()> { fn from(handle: &'a archive::Handle) -> ArchiveResult<()> { match handle.err_code() { - 0 => Ok(()), + ErrCode(0) => Ok(()), _ => Err(ArchiveError::from(handle)), } } diff --git a/libraries/libarchive/src/reader.rs b/libraries/libarchive/src/reader.rs index 45bb1d76..ee124df4 100644 --- a/libraries/libarchive/src/reader.rs +++ b/libraries/libarchive/src/reader.rs @@ -6,6 +6,7 @@ use std::io::{self, Read}; use std::mem; use std::path::Path; use std::ptr; +use std::slice; use libc::{c_void, ssize_t}; use libarchive3_sys::ffi; @@ -38,7 +39,7 @@ pub trait Reader : Handle { unsafe { ffi::archive_read_header_position(self.handle()) } } - fn next_header(&mut self) -> Option<&ReaderEntry> { + fn next_header(&mut self) -> Option<&mut ReaderEntry> { let res = unsafe { ffi::archive_read_next_header(self.handle(), &mut self.entry().handle) }; if res == 0 { Some(self.entry()) @@ -46,6 +47,20 @@ pub trait Reader : Handle { None } } + + fn read_block(&self) -> ArchiveResult> { + let mut buff = ptr::null(); + let mut size = 0; + let mut offset = 0; + + unsafe { + match ffi::archive_read_data_block(self.handle(), &mut buff, &mut size, &mut offset) { + ffi::ARCHIVE_EOF => Ok(None), + ffi::ARCHIVE_OK => Ok(Some(slice::from_raw_parts(buff as *const u8, size))), + _ => Err(ArchiveError::Sys(self.err_code(), self.err_msg())), + } + } + } } pub struct FileReader { @@ -56,7 +71,7 @@ pub struct FileReader { pub struct StreamReader { handle: *mut ffi::Struct_archive, entry: ReaderEntry, - _pipe: Pipe, + _pipe: Box, } pub struct Builder { @@ -133,9 +148,8 @@ impl Drop for FileReader { impl StreamReader { pub fn open(mut builder: Builder, src: T) -> ArchiveResult { unsafe { - builder.consume(); - let mut pipe = Pipe::new(src); - let pipe_ptr: *mut c_void = &mut pipe as *mut Pipe as *mut c_void; + let mut pipe = Box::new(Pipe::new(src)); + let pipe_ptr: *mut c_void = &mut *pipe as *mut Pipe as *mut c_void; match ffi::archive_read_open(builder.handle(), pipe_ptr, None, @@ -147,9 +161,13 @@ impl StreamReader { entry: ReaderEntry::default(), _pipe: pipe, }; + builder.consume(); Ok(reader) } - _ => Err(ArchiveError::from(&builder as &Handle)), + _ => { + builder.consume(); + Err(ArchiveError::from(&builder as &Handle)) + } } } }