src/pxar/decoder.rs: use trait object as reader
So that the Decoder is no longer genertic.
This commit is contained in:
		@ -7,8 +7,6 @@ use std::path::Path;
 | 
				
			|||||||
use failure::*;
 | 
					use failure::*;
 | 
				
			||||||
use libc;
 | 
					use libc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::backup::*;
 | 
					 | 
				
			||||||
use crate::client::*;
 | 
					 | 
				
			||||||
use crate::pxar::*;
 | 
					use crate::pxar::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use super::catalog::{CatalogReader, DirEntry};
 | 
					use super::catalog::{CatalogReader, DirEntry};
 | 
				
			||||||
@ -21,7 +19,7 @@ pub struct Shell {
 | 
				
			|||||||
    /// List of paths selected for a restore
 | 
					    /// List of paths selected for a restore
 | 
				
			||||||
    selected: HashSet<Vec<u8>>,
 | 
					    selected: HashSet<Vec<u8>>,
 | 
				
			||||||
    /// Decoder instance for the current pxar archive
 | 
					    /// Decoder instance for the current pxar archive
 | 
				
			||||||
    decoder: Decoder<BufferedDynamicReader<RemoteChunkReader>>,
 | 
					    decoder: Decoder,
 | 
				
			||||||
    /// Root directory for the give archive as stored in the catalog
 | 
					    /// Root directory for the give archive as stored in the catalog
 | 
				
			||||||
    root: Vec<DirEntry>,
 | 
					    root: Vec<DirEntry>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -60,7 +58,7 @@ impl Shell {
 | 
				
			|||||||
    pub fn new(
 | 
					    pub fn new(
 | 
				
			||||||
        mut catalog: CatalogReader<std::fs::File>,
 | 
					        mut catalog: CatalogReader<std::fs::File>,
 | 
				
			||||||
        archive_name: &str,
 | 
					        archive_name: &str,
 | 
				
			||||||
        decoder: Decoder<BufferedDynamicReader<RemoteChunkReader>>
 | 
					        decoder: Decoder,
 | 
				
			||||||
    ) -> Result<Self, Error> {
 | 
					    ) -> Result<Self, Error> {
 | 
				
			||||||
        let catalog_root = catalog.root()?;
 | 
					        let catalog_root = catalog.root()?;
 | 
				
			||||||
        // The root for the given archive as stored in the catalog
 | 
					        // The root for the given archive as stored in the catalog
 | 
				
			||||||
 | 
				
			|||||||
@ -1707,7 +1707,6 @@ async fn mount_do(param: Value, pipe: Option<RawFd>) -> Result<Value, Error> {
 | 
				
			|||||||
        let most_used = index.find_most_used_chunks(8);
 | 
					        let most_used = index.find_most_used_chunks(8);
 | 
				
			||||||
        let chunk_reader = RemoteChunkReader::new(client.clone(), crypt_config, most_used);
 | 
					        let chunk_reader = RemoteChunkReader::new(client.clone(), crypt_config, most_used);
 | 
				
			||||||
        let reader = BufferedDynamicReader::new(index, chunk_reader);
 | 
					        let reader = BufferedDynamicReader::new(index, chunk_reader);
 | 
				
			||||||
        //let decoder = pxar::Decoder::new(Box::<dyn pxar::fuse::ReadSeek>::new(reader))?;
 | 
					 | 
				
			||||||
        let decoder = pxar::Decoder::new(reader)?;
 | 
					        let decoder = pxar::Decoder::new(reader)?;
 | 
				
			||||||
        let options = OsStr::new("ro,default_permissions");
 | 
					        let options = OsStr::new("ro,default_permissions");
 | 
				
			||||||
        let mut session = pxar::fuse::Session::from_decoder(decoder, &options, pipe.is_none())
 | 
					        let mut session = pxar::fuse::Session::from_decoder(decoder, &options, pipe.is_none())
 | 
				
			||||||
 | 
				
			|||||||
@ -26,9 +26,13 @@ pub struct DirectoryEntry {
 | 
				
			|||||||
    pub entry: PxarEntry,
 | 
					    pub entry: PxarEntry,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Trait to create ReadSeek Decoder trait objects.
 | 
				
			||||||
 | 
					trait ReadSeek: Read + Seek {}
 | 
				
			||||||
 | 
					impl <R: Read + Seek> ReadSeek for R {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// This one needs Read+Seek
 | 
					// This one needs Read+Seek
 | 
				
			||||||
pub struct Decoder<R: Read + Seek> {
 | 
					pub struct Decoder {
 | 
				
			||||||
    inner: SequentialDecoder<R>,
 | 
					    inner: SequentialDecoder<Box<dyn ReadSeek>>,
 | 
				
			||||||
    root_start: u64,
 | 
					    root_start: u64,
 | 
				
			||||||
    root_end: u64,
 | 
					    root_end: u64,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -36,10 +40,11 @@ pub struct Decoder<R: Read + Seek> {
 | 
				
			|||||||
const HEADER_SIZE: u64 = std::mem::size_of::<PxarHeader>() as u64;
 | 
					const HEADER_SIZE: u64 = std::mem::size_of::<PxarHeader>() as u64;
 | 
				
			||||||
const GOODBYE_ITEM_SIZE: u64 = std::mem::size_of::<PxarGoodbyeItem>() as u64;
 | 
					const GOODBYE_ITEM_SIZE: u64 = std::mem::size_of::<PxarGoodbyeItem>() as u64;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<R: Read + Seek> Decoder<R> {
 | 
					impl Decoder {
 | 
				
			||||||
    pub fn new(mut reader: R) -> Result<Self, Error> {
 | 
					    pub fn new<R: Read + Seek + 'static>(mut reader: R) -> Result<Self, Error> {
 | 
				
			||||||
        let root_end = reader.seek(SeekFrom::End(0))?;
 | 
					        let root_end = reader.seek(SeekFrom::End(0))?;
 | 
				
			||||||
        let inner = SequentialDecoder::new(reader, super::flags::DEFAULT);
 | 
					        let boxed_reader: Box<dyn ReadSeek + 'static> = Box::new(reader);
 | 
				
			||||||
 | 
					        let inner = SequentialDecoder::new(boxed_reader, super::flags::DEFAULT);
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
        Ok(Self { inner, root_start: 0, root_end })
 | 
					        Ok(Self { inner, root_start: 0, root_end })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -6,7 +6,7 @@ use std::collections::HashMap;
 | 
				
			|||||||
use std::convert::TryFrom;
 | 
					use std::convert::TryFrom;
 | 
				
			||||||
use std::ffi::{CStr, CString, OsStr};
 | 
					use std::ffi::{CStr, CString, OsStr};
 | 
				
			||||||
use std::fs::File;
 | 
					use std::fs::File;
 | 
				
			||||||
use std::io::{BufReader, Read, Seek};
 | 
					use std::io::BufReader;
 | 
				
			||||||
use std::os::unix::ffi::{OsStrExt, OsStringExt};
 | 
					use std::os::unix::ffi::{OsStrExt, OsStringExt};
 | 
				
			||||||
use std::path::Path;
 | 
					use std::path::Path;
 | 
				
			||||||
use std::sync::Mutex;
 | 
					use std::sync::Mutex;
 | 
				
			||||||
@ -83,8 +83,8 @@ struct FuseArgs {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/// `Context` for callback functions providing the decoder, caches and the
 | 
					/// `Context` for callback functions providing the decoder, caches and the
 | 
				
			||||||
/// offset within the archive for the i-node given by the caller.
 | 
					/// offset within the archive for the i-node given by the caller.
 | 
				
			||||||
struct Context<R: Read + Seek> {
 | 
					struct Context {
 | 
				
			||||||
    decoder: Decoder<R>,
 | 
					    decoder: Decoder,
 | 
				
			||||||
    goodbye_cache: Option<(Inode, Vec<(PxarGoodbyeItem, Offset, Offset)>)>,
 | 
					    goodbye_cache: Option<(Inode, Vec<(PxarGoodbyeItem, Offset, Offset)>)>,
 | 
				
			||||||
    attr_cache: Option<(Inode, PxarAttributes)>,
 | 
					    attr_cache: Option<(Inode, PxarAttributes)>,
 | 
				
			||||||
    ino_offset: Offset,
 | 
					    ino_offset: Offset,
 | 
				
			||||||
@ -92,10 +92,9 @@ struct Context<R: Read + Seek> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/// `Session` stores a pointer to the session context and is used to mount the
 | 
					/// `Session` stores a pointer to the session context and is used to mount the
 | 
				
			||||||
/// archive to the given mountpoint.
 | 
					/// archive to the given mountpoint.
 | 
				
			||||||
pub struct Session<R: Read + Seek> {
 | 
					pub struct Session {
 | 
				
			||||||
    ptr: MutPtr,
 | 
					    ptr: MutPtr,
 | 
				
			||||||
    verbose: bool,
 | 
					    verbose: bool,
 | 
				
			||||||
    _phantom: std::marker::PhantomData<R>,
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// `Operations` defines the callback function table of supported operations.
 | 
					/// `Operations` defines the callback function table of supported operations.
 | 
				
			||||||
@ -151,7 +150,9 @@ struct Operations {
 | 
				
			|||||||
    copy_file_range: Option<extern fn(req: Request, ino_in: u64, off_in: c_int, fi_in: MutPtr, ino_out: u64, off_out: c_int, fi_out: MutPtr, len: size_t, flags: c_int)>,
 | 
					    copy_file_range: Option<extern fn(req: Request, ino_in: u64, off_in: c_int, fi_in: MutPtr, ino_out: u64, off_out: c_int, fi_out: MutPtr, len: size_t, flags: c_int)>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Session<BufReader<File>>  {
 | 
					
 | 
				
			||||||
 | 
					impl Session  {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Create a new low level fuse session.
 | 
					    /// Create a new low level fuse session.
 | 
				
			||||||
    ///
 | 
					    ///
 | 
				
			||||||
    /// `Session` is created using the provided mount options and sets the
 | 
					    /// `Session` is created using the provided mount options and sets the
 | 
				
			||||||
@ -169,9 +170,7 @@ impl Session<BufReader<File>>  {
 | 
				
			|||||||
        let decoder = Decoder::new(reader)?;
 | 
					        let decoder = Decoder::new(reader)?;
 | 
				
			||||||
        Self::setup_session(decoder, args, oprs, verbose)
 | 
					        Self::setup_session(decoder, args, oprs, verbose)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl <R: Read + Seek> Session<R>  {
 | 
					 | 
				
			||||||
    fn setup_args(options: &OsStr, verbose: bool) -> Result<Vec<CString>, Error> {
 | 
					    fn setup_args(options: &OsStr, verbose: bool) -> Result<Vec<CString>, Error> {
 | 
				
			||||||
        // First argument should be the executable name
 | 
					        // First argument should be the executable name
 | 
				
			||||||
        let mut arguments = vec![
 | 
					        let mut arguments = vec![
 | 
				
			||||||
@ -202,7 +201,7 @@ impl <R: Read + Seek> Session<R>  {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn setup_session(
 | 
					    fn setup_session(
 | 
				
			||||||
        decoder: Decoder<R>,
 | 
					        decoder: Decoder,
 | 
				
			||||||
        args: Vec<CString>,
 | 
					        args: Vec<CString>,
 | 
				
			||||||
        oprs: Operations,
 | 
					        oprs: Operations,
 | 
				
			||||||
        verbose: bool,
 | 
					        verbose: bool,
 | 
				
			||||||
@ -244,7 +243,6 @@ impl <R: Read + Seek> Session<R>  {
 | 
				
			|||||||
        Ok(Self {
 | 
					        Ok(Self {
 | 
				
			||||||
            ptr: session_ptr,
 | 
					            ptr: session_ptr,
 | 
				
			||||||
            verbose,
 | 
					            verbose,
 | 
				
			||||||
            _phantom: std::marker::PhantomData,
 | 
					 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -255,7 +253,7 @@ impl <R: Read + Seek> Session<R>  {
 | 
				
			|||||||
    /// Options have to be provided as comma separated OsStr, e.g.
 | 
					    /// Options have to be provided as comma separated OsStr, e.g.
 | 
				
			||||||
    /// ("ro,default_permissions").
 | 
					    /// ("ro,default_permissions").
 | 
				
			||||||
    pub fn from_decoder(
 | 
					    pub fn from_decoder(
 | 
				
			||||||
        decoder: Decoder<R>,
 | 
					        decoder: Decoder,
 | 
				
			||||||
        options: &OsStr,
 | 
					        options: &OsStr,
 | 
				
			||||||
        verbose: bool,
 | 
					        verbose: bool,
 | 
				
			||||||
    ) -> Result<Self, Error> {
 | 
					    ) -> Result<Self, Error> {
 | 
				
			||||||
@ -319,10 +317,10 @@ impl <R: Read + Seek> Session<R>  {
 | 
				
			|||||||
    /// The error code will be used to reply to libfuse.
 | 
					    /// The error code will be used to reply to libfuse.
 | 
				
			||||||
    fn run_in_context<F>(req: Request, inode: u64, code: F)
 | 
					    fn run_in_context<F>(req: Request, inode: u64, code: F)
 | 
				
			||||||
        where
 | 
					        where
 | 
				
			||||||
        F: FnOnce(&mut Context<R>) -> Result<(), i32>,
 | 
					        F: FnOnce(&mut Context) -> Result<(), i32>,
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        let boxed_ctx = unsafe {
 | 
					        let boxed_ctx = unsafe {
 | 
				
			||||||
            let ptr = fuse_req_userdata(req) as *mut Mutex<Context<R>>;
 | 
					            let ptr = fuse_req_userdata(req) as *mut Mutex<Context>;
 | 
				
			||||||
            Box::from_raw(ptr)
 | 
					            Box::from_raw(ptr)
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        let result = boxed_ctx
 | 
					        let result = boxed_ctx
 | 
				
			||||||
@ -532,7 +530,7 @@ impl <R: Read + Seek> Session<R>  {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl <R: Read + Seek> Drop for Session<R> {
 | 
					impl Drop for Session {
 | 
				
			||||||
    fn drop(&mut self) {
 | 
					    fn drop(&mut self) {
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
            fuse_session_unmount(self.ptr);
 | 
					            fuse_session_unmount(self.ptr);
 | 
				
			||||||
@ -593,7 +591,7 @@ struct EntryParam {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/// Update the goodbye table to the one corresponding to the i-node offset, both
 | 
					/// Update the goodbye table to the one corresponding to the i-node offset, both
 | 
				
			||||||
/// given in the `Context`.
 | 
					/// given in the `Context`.
 | 
				
			||||||
fn update_goodbye_cache<R: Read + Seek>(mut ctx: &mut Context<R>) -> Result<(), i32> {
 | 
					fn update_goodbye_cache(mut ctx: &mut Context) -> Result<(), i32> {
 | 
				
			||||||
    if let Some((off, _)) = &ctx.goodbye_cache {
 | 
					    if let Some((off, _)) = &ctx.goodbye_cache {
 | 
				
			||||||
        if *off == ctx.ino_offset {
 | 
					        if *off == ctx.ino_offset {
 | 
				
			||||||
            // Cache contains already the correct goodbye table
 | 
					            // Cache contains already the correct goodbye table
 | 
				
			||||||
@ -623,8 +621,8 @@ fn update_goodbye_cache<R: Read + Seek>(mut ctx: &mut Context<R>) -> Result<(),
 | 
				
			|||||||
/// The matching items archive offset, entry and payload size are returned.
 | 
					/// The matching items archive offset, entry and payload size are returned.
 | 
				
			||||||
/// If there is no entry with matching `filename` and `hash` a `libc::ENOENT` is
 | 
					/// If there is no entry with matching `filename` and `hash` a `libc::ENOENT` is
 | 
				
			||||||
/// returned.
 | 
					/// returned.
 | 
				
			||||||
fn find_goodbye_entry<R: Read + Seek>(
 | 
					fn find_goodbye_entry(
 | 
				
			||||||
    mut ctx: &mut Context<R>,
 | 
					    mut ctx: &mut Context,
 | 
				
			||||||
    filename: &CStr,
 | 
					    filename: &CStr,
 | 
				
			||||||
    hash: u64,
 | 
					    hash: u64,
 | 
				
			||||||
) -> Result<(u64, PxarEntry, PxarAttributes, u64), i32> {
 | 
					) -> Result<(u64, PxarEntry, PxarAttributes, u64), i32> {
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user