mirror of
https://github.com/Drop-OSS/drop.git
synced 2026-07-25 17:24:48 +10:00
fix segmentation fault
add read_block function to reader
This commit is contained in:
@@ -3,6 +3,7 @@ use std::str;
|
|||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
|
|
||||||
use libarchive3_sys::ffi;
|
use libarchive3_sys::ffi;
|
||||||
|
use error::ErrCode;
|
||||||
|
|
||||||
pub enum ReadCompression {
|
pub enum ReadCompression {
|
||||||
All,
|
All,
|
||||||
@@ -93,8 +94,9 @@ pub enum WriteFilter {
|
|||||||
pub trait Handle {
|
pub trait Handle {
|
||||||
unsafe fn handle(&self) -> *mut ffi::Struct_archive;
|
unsafe fn handle(&self) -> *mut ffi::Struct_archive;
|
||||||
|
|
||||||
fn err_code(&self) -> i32 {
|
fn err_code(&self) -> ErrCode {
|
||||||
unsafe { ffi::archive_errno(self.handle()) }
|
let code = unsafe { ffi::archive_errno(self.handle()) };
|
||||||
|
ErrCode(code)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn err_msg(&self) -> String {
|
fn err_msg(&self) -> String {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use archive;
|
|||||||
pub type ArchiveResult<T> = Result<T, ArchiveError>;
|
pub type ArchiveResult<T> = Result<T, ArchiveError>;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ErrCode(i32);
|
pub struct ErrCode(pub i32);
|
||||||
|
|
||||||
impl fmt::Display for ErrCode {
|
impl fmt::Display for ErrCode {
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
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 {
|
impl<'a> From<&'a archive::Handle> for ArchiveError {
|
||||||
fn from(handle: &'a archive::Handle) -> ArchiveError {
|
fn from(handle: &'a archive::Handle) -> ArchiveError {
|
||||||
ArchiveError::Sys(ErrCode::from(handle), handle.err_msg())
|
ArchiveError::Sys(handle.err_code(), handle.err_msg())
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> From<&'a archive::Handle> for ErrCode {
|
|
||||||
fn from(handle: &'a archive::Handle) -> ErrCode {
|
|
||||||
ErrCode(handle.err_code())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a archive::Handle> for ArchiveResult<()> {
|
impl<'a> From<&'a archive::Handle> for ArchiveResult<()> {
|
||||||
fn from(handle: &'a archive::Handle) -> ArchiveResult<()> {
|
fn from(handle: &'a archive::Handle) -> ArchiveResult<()> {
|
||||||
match handle.err_code() {
|
match handle.err_code() {
|
||||||
0 => Ok(()),
|
ErrCode(0) => Ok(()),
|
||||||
_ => Err(ArchiveError::from(handle)),
|
_ => Err(ArchiveError::from(handle)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use std::io::{self, Read};
|
|||||||
use std::mem;
|
use std::mem;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
use std::slice;
|
||||||
|
|
||||||
use libc::{c_void, ssize_t};
|
use libc::{c_void, ssize_t};
|
||||||
use libarchive3_sys::ffi;
|
use libarchive3_sys::ffi;
|
||||||
@@ -38,7 +39,7 @@ pub trait Reader : Handle {
|
|||||||
unsafe { ffi::archive_read_header_position(self.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) };
|
let res = unsafe { ffi::archive_read_next_header(self.handle(), &mut self.entry().handle) };
|
||||||
if res == 0 {
|
if res == 0 {
|
||||||
Some(self.entry())
|
Some(self.entry())
|
||||||
@@ -46,6 +47,20 @@ pub trait Reader : Handle {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn read_block(&self) -> ArchiveResult<Option<&[u8]>> {
|
||||||
|
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 {
|
pub struct FileReader {
|
||||||
@@ -56,7 +71,7 @@ pub struct FileReader {
|
|||||||
pub struct StreamReader {
|
pub struct StreamReader {
|
||||||
handle: *mut ffi::Struct_archive,
|
handle: *mut ffi::Struct_archive,
|
||||||
entry: ReaderEntry,
|
entry: ReaderEntry,
|
||||||
_pipe: Pipe,
|
_pipe: Box<Pipe>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Builder {
|
pub struct Builder {
|
||||||
@@ -133,9 +148,8 @@ impl Drop for FileReader {
|
|||||||
impl StreamReader {
|
impl StreamReader {
|
||||||
pub fn open<T: Any + Read>(mut builder: Builder, src: T) -> ArchiveResult<Self> {
|
pub fn open<T: Any + Read>(mut builder: Builder, src: T) -> ArchiveResult<Self> {
|
||||||
unsafe {
|
unsafe {
|
||||||
builder.consume();
|
let mut pipe = Box::new(Pipe::new(src));
|
||||||
let mut pipe = Pipe::new(src);
|
let pipe_ptr: *mut c_void = &mut *pipe as *mut Pipe as *mut c_void;
|
||||||
let pipe_ptr: *mut c_void = &mut pipe as *mut Pipe as *mut c_void;
|
|
||||||
match ffi::archive_read_open(builder.handle(),
|
match ffi::archive_read_open(builder.handle(),
|
||||||
pipe_ptr,
|
pipe_ptr,
|
||||||
None,
|
None,
|
||||||
@@ -147,9 +161,13 @@ impl StreamReader {
|
|||||||
entry: ReaderEntry::default(),
|
entry: ReaderEntry::default(),
|
||||||
_pipe: pipe,
|
_pipe: pipe,
|
||||||
};
|
};
|
||||||
|
builder.consume();
|
||||||
Ok(reader)
|
Ok(reader)
|
||||||
}
|
}
|
||||||
_ => Err(ArchiveError::from(&builder as &Handle)),
|
_ => {
|
||||||
|
builder.consume();
|
||||||
|
Err(ArchiveError::from(&builder as &Handle))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user