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