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:
parent
b46c3fad03
commit
7dcbe051e9
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
});
|
||||
|
@ -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(())
|
||||
}
|
||||
|
@ -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()?;
|
||||
|
Loading…
Reference in New Issue
Block a user