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 feature_flags = pxar::CA_FORMAT_DEFAULT;
let mut decoder = pxar::SequentialDecoder::new(&mut reader, feature_flags);
decoder.restore(Path::new(target), & |path| {
let mut decoder = pxar::SequentialDecoder::new(&mut reader, feature_flags, |path| {
if verbose {
println!("{:?}", path);
}
Ok(())
})?;
});
decoder.restore(Path::new(target))?;
Ok(Value::Null)
}

View File

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

View File

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

View File

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

View File

@ -29,23 +29,25 @@ use crate::tools::acl;
use crate::tools::xattr;
// 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,
feature_flags: u64,
skip_buffer: Vec<u8>,
callback: F,
}
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);
Self {
reader,
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.
///
/// The directory is created if it does not exist.
pub fn restore<F>(
&mut self,
path: &Path,
callback: &F,
) -> Result<(), Error>
where F: Fn(&Path) -> Result<(), Error>
{
pub fn restore(&mut self, path: &Path) -> Result<(), Error> {
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))?;
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,
base_path: &Path,
relative_path: &mut PathBuf,
filename: &OsStr, // repeats path last relative_path component
parent: &nix::dir::Dir,
callback: &F,
) -> Result<(), Error>
where F: Fn(&Path) -> Result<(), Error>
{
) -> Result<(), Error> {
let parent_fd = parent.as_raw_fd();
let full_path = base_path.join(&relative_path);
(callback)(&full_path)?;
(self.callback)(&full_path)?;
let head: CaFormatHeader = self.read_item()?;
@ -519,7 +512,7 @@ impl <'a, R: Read> SequentialDecoder<'a, R> {
while head.htype == CA_FORMAT_FILENAME {
let name = self.read_filename(head.size)?;
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();
head = self.read_item()?;