From 7dcbe051e9fb27a52afa3e45b222ea01109571f1 Mon Sep 17 00:00:00 2001 From: Christian Ebner Date: Thu, 4 Jul 2019 14:03:20 +0200 Subject: [PATCH] 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 --- src/bin/proxmox-backup-client.rs | 8 ++++---- src/bin/pxar.rs | 12 ++++++------ src/client/pxar_decode_writer.rs | 8 ++++---- src/pxar/decoder.rs | 19 ++++++++----------- src/pxar/sequential_decoder.rs | 31 ++++++++++++------------------- 5 files changed, 34 insertions(+), 44 deletions(-) diff --git a/src/bin/proxmox-backup-client.rs b/src/bin/proxmox-backup-client.rs index 53456c4c..6e316b1b 100644 --- a/src/bin/proxmox-backup-client.rs +++ b/src/bin/proxmox-backup-client.rs @@ -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) } diff --git a/src/bin/pxar.rs b/src/bin/pxar.rs index 27a5533f..fac3888d 100644 --- a/src/bin/pxar.rs +++ b/src/bin/pxar.rs @@ -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) } diff --git a/src/client/pxar_decode_writer.rs b/src/client/pxar_decode_writer.rs index ba708d91..801e6a29 100644 --- a/src/client/pxar_decode_writer.rs +++ b/src/client/pxar_decode_writer.rs @@ -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); } }); diff --git a/src/pxar/decoder.rs b/src/pxar/decoder.rs index 3820fb5a..d806e28b 100644 --- a/src/pxar/decoder.rs +++ b/src/pxar/decoder.rs @@ -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::() 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 { + pub fn new(reader: &'a mut R, callback: F) -> Result { 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( + 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(()) } diff --git a/src/pxar/sequential_decoder.rs b/src/pxar/sequential_decoder.rs index cb82de6a..1cbec187 100644 --- a/src/pxar/sequential_decoder.rs +++ b/src/pxar/sequential_decoder.rs @@ -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, + callback: F, } const HEADER_SIZE: u64 = std::mem::size_of::() 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( - &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( + 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()?;