pxar: Refactor SequentialDecoder to store the callback function within the struct

Reduces the number of arguments for the function calls within the decoder.

Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
This commit is contained in:
Christian Ebner 2019-07-04 14:03:20 +02:00 committed by Dietmar Maurer
parent b46c3fad03
commit 7dcbe051e9
5 changed files with 34 additions and 44 deletions

View File

@ -649,14 +649,14 @@ fn restore(
let mut reader = BufferedDynamicReader::new(index, chunk_reader); let mut reader = BufferedDynamicReader::new(index, chunk_reader);
let feature_flags = pxar::CA_FORMAT_DEFAULT; let feature_flags = pxar::CA_FORMAT_DEFAULT;
let mut decoder = pxar::SequentialDecoder::new(&mut reader, feature_flags); let mut decoder = pxar::SequentialDecoder::new(&mut reader, feature_flags, |path| {
decoder.restore(Path::new(target), & |path| {
if verbose { if verbose {
println!("{:?}", path); println!("{:?}", path);
} }
Ok(()) Ok(())
})?; });
decoder.restore(Path::new(target))?;
Ok(Value::Null) Ok(Value::Null)
} }

View File

@ -30,7 +30,7 @@ fn print_filenames(
let mut feature_flags = pxar::CA_FORMAT_DEFAULT; let mut feature_flags = pxar::CA_FORMAT_DEFAULT;
feature_flags ^= pxar::CA_FORMAT_WITH_XATTRS; feature_flags ^= pxar::CA_FORMAT_WITH_XATTRS;
feature_flags ^= pxar::CA_FORMAT_WITH_FCAPS; feature_flags ^= pxar::CA_FORMAT_WITH_FCAPS;
let mut decoder = pxar::SequentialDecoder::new(&mut reader, feature_flags); let mut decoder = pxar::SequentialDecoder::new(&mut reader, feature_flags, |_| Ok(()));
let stdout = std::io::stdout(); let stdout = std::io::stdout();
let mut out = stdout.lock(); let mut out = stdout.lock();
@ -65,7 +65,7 @@ fn dump_archive(
if !with_acls { if !with_acls {
feature_flags ^= pxar::CA_FORMAT_WITH_ACL; feature_flags ^= pxar::CA_FORMAT_WITH_ACL;
} }
let mut decoder = pxar::SequentialDecoder::new(&mut reader, feature_flags); let mut decoder = pxar::SequentialDecoder::new(&mut reader, feature_flags, |_| Ok(()));
let stdout = std::io::stdout(); let stdout = std::io::stdout();
let mut out = stdout.lock(); let mut out = stdout.lock();
@ -105,14 +105,14 @@ fn extract_archive(
feature_flags ^= pxar::CA_FORMAT_WITH_ACL; feature_flags ^= pxar::CA_FORMAT_WITH_ACL;
} }
let mut decoder = pxar::SequentialDecoder::new(&mut reader, feature_flags); let mut decoder = pxar::SequentialDecoder::new(&mut reader, feature_flags, |path| {
decoder.restore(Path::new(target), & |path| {
if verbose { if verbose {
println!("{:?}", path); println!("{:?}", path);
} }
Ok(()) Ok(())
})?; });
decoder.restore(Path::new(target))?;
Ok(Value::Null) Ok(Value::Null)
} }

View File

@ -31,14 +31,14 @@ impl PxarDecodeWriter {
let child = thread::spawn(move|| { let child = thread::spawn(move|| {
let mut reader = unsafe { std::fs::File::from_raw_fd(rx) }; let mut reader = unsafe { std::fs::File::from_raw_fd(rx) };
let mut decoder = pxar::SequentialDecoder::new(&mut reader, pxar::CA_FORMAT_DEFAULT); let mut decoder = pxar::SequentialDecoder::new(&mut reader, pxar::CA_FORMAT_DEFAULT, |path| {
if let Err(err) = decoder.restore(&base, & |path| {
if verbose { if verbose {
println!("{:?}", path); println!("{:?}", path);
} }
Ok(()) Ok(())
}) { });
if let Err(err) = decoder.restore(&base) {
eprintln!("pxar decode failed - {}", err); eprintln!("pxar decode failed - {}", err);
} }
}); });

View File

@ -21,22 +21,22 @@ pub struct CaDirectoryEntry {
} }
// This one needs Read+Seek // This one needs Read+Seek
pub struct Decoder<'a, R: Read + Seek> { pub struct Decoder<'a, R: Read + Seek, F: Fn(&Path) -> Result<(), Error>> {
inner: SequentialDecoder<'a, R>, inner: SequentialDecoder<'a, R, F>,
root_start: u64, root_start: u64,
root_end: u64, root_end: u64,
} }
const HEADER_SIZE: u64 = std::mem::size_of::<CaFormatHeader>() as u64; const HEADER_SIZE: u64 = std::mem::size_of::<CaFormatHeader>() as u64;
impl <'a, R: Read + Seek> Decoder<'a, R> { impl <'a, R: Read + Seek, F: Fn(&Path) -> Result<(), Error>> Decoder<'a, R, F> {
pub fn new(reader: &'a mut R) -> Result<Self, Error> { pub fn new(reader: &'a mut R, callback: F) -> Result<Self, Error> {
let root_end = reader.seek(SeekFrom::End(0))?; let root_end = reader.seek(SeekFrom::End(0))?;
Ok(Self { Ok(Self {
inner: SequentialDecoder::new(reader, CA_FORMAT_DEFAULT), inner: SequentialDecoder::new(reader, CA_FORMAT_DEFAULT, callback),
root_start: 0, root_start: 0,
root_end: root_end, root_end: root_end,
}) })
@ -62,19 +62,16 @@ impl <'a, R: Read + Seek> Decoder<'a, R> {
Ok(pos) Ok(pos)
} }
pub fn restore<F>( pub fn restore(
&mut self, &mut self,
dir: &CaDirectoryEntry, dir: &CaDirectoryEntry,
path: &Path, path: &Path,
callback: F, ) -> Result<(), Error> {
) -> Result<(), Error>
where F: Fn(&Path) -> Result<(), Error>
{
let start = dir.start; let start = dir.start;
self.seek(SeekFrom::Start(start))?; self.seek(SeekFrom::Start(start))?;
self.inner.restore(path, &callback)?; self.inner.restore(path)?;
Ok(()) Ok(())
} }

View File

@ -29,23 +29,25 @@ use crate::tools::acl;
use crate::tools::xattr; use crate::tools::xattr;
// This one need Read, but works without Seek // This one need Read, but works without Seek
pub struct SequentialDecoder<'a, R: Read> { pub struct SequentialDecoder<'a, R: Read, F: Fn(&Path) -> Result<(), Error>> {
reader: &'a mut R, reader: &'a mut R,
feature_flags: u64, feature_flags: u64,
skip_buffer: Vec<u8>, skip_buffer: Vec<u8>,
callback: F,
} }
const HEADER_SIZE: u64 = std::mem::size_of::<CaFormatHeader>() as u64; const HEADER_SIZE: u64 = std::mem::size_of::<CaFormatHeader>() as u64;
impl <'a, R: Read> SequentialDecoder<'a, R> { impl <'a, R: Read, F: Fn(&Path) -> Result<(), Error>> SequentialDecoder<'a, R, F> {
pub fn new(reader: &'a mut R, feature_flags: u64) -> Self { pub fn new(reader: &'a mut R, feature_flags: u64, callback: F) -> Self {
let skip_buffer = vec::undefined(64*1024); let skip_buffer = vec::undefined(64*1024);
Self { Self {
reader, reader,
feature_flags, feature_flags,
skip_buffer skip_buffer,
callback,
} }
} }
@ -450,13 +452,7 @@ impl <'a, R: Read> SequentialDecoder<'a, R> {
/// Restore an archive into the specified directory. /// Restore an archive into the specified directory.
/// ///
/// The directory is created if it does not exist. /// The directory is created if it does not exist.
pub fn restore<F>( pub fn restore(&mut self, path: &Path) -> Result<(), Error> {
&mut self,
path: &Path,
callback: &F,
) -> Result<(), Error>
where F: Fn(&Path) -> Result<(), Error>
{
let _ = std::fs::create_dir(path); let _ = std::fs::create_dir(path);
@ -464,25 +460,22 @@ impl <'a, R: Read> SequentialDecoder<'a, R> {
.map_err(|err| format_err!("unable to open target directory {:?} - {}", path, err))?; .map_err(|err| format_err!("unable to open target directory {:?} - {}", path, err))?;
let mut relative_path = PathBuf::new(); let mut relative_path = PathBuf::new();
self.restore_sequential(path, &mut relative_path, &OsString::new(), &dir, callback) self.restore_sequential(path, &mut relative_path, &OsString::new(), &dir)
} }
fn restore_sequential<F>( fn restore_sequential(
&mut self, &mut self,
base_path: &Path, base_path: &Path,
relative_path: &mut PathBuf, relative_path: &mut PathBuf,
filename: &OsStr, // repeats path last relative_path component filename: &OsStr, // repeats path last relative_path component
parent: &nix::dir::Dir, parent: &nix::dir::Dir,
callback: &F, ) -> Result<(), Error> {
) -> Result<(), Error>
where F: Fn(&Path) -> Result<(), Error>
{
let parent_fd = parent.as_raw_fd(); let parent_fd = parent.as_raw_fd();
let full_path = base_path.join(&relative_path); let full_path = base_path.join(&relative_path);
(callback)(&full_path)?; (self.callback)(&full_path)?;
let head: CaFormatHeader = self.read_item()?; let head: CaFormatHeader = self.read_item()?;
@ -519,7 +512,7 @@ impl <'a, R: Read> SequentialDecoder<'a, R> {
while head.htype == CA_FORMAT_FILENAME { while head.htype == CA_FORMAT_FILENAME {
let name = self.read_filename(head.size)?; let name = self.read_filename(head.size)?;
relative_path.push(&name); relative_path.push(&name);
self.restore_sequential(base_path, relative_path, &name, &dir, callback)?; self.restore_sequential(base_path, relative_path, &name, &dir)?;
relative_path.pop(); relative_path.pop();
head = self.read_item()?; head = self.read_item()?;