src/backup/catalog.rs: new parse() helper

This commit is contained in:
Dietmar Maurer 2019-11-09 14:37:33 +01:00
parent 5d92935e03
commit 265664517a

View File

@ -102,6 +102,47 @@ impl DirInfo {
Ok((self.name, data)) Ok((self.name, data))
} }
fn parse<C: FnMut(CatalogEntryType, Vec<u8>, u64, u64, u64) -> Result<(), Error>>(
data: &[u8],
mut callback: C,
) -> Result<(), Error> {
let mut cursor = data;
let entries = catalog_decode_u64(&mut cursor)?;
for _ in 0..entries {
let mut buf = [ 0u8 ];
cursor.read_exact(&mut buf)?;
let etype = CatalogEntryType::try_from(buf[0])?;
let name_len = catalog_decode_u64(&mut cursor)?;
let name = cursor.read_exact_allocated(name_len as usize)?;
match etype {
CatalogEntryType::Directory => {
let offset = catalog_decode_u64(&mut cursor)?;
callback(etype, name, offset, 0, 0)?;
}
CatalogEntryType::File => {
let size = catalog_decode_u64(&mut cursor)?;
let mtime = catalog_decode_u64(&mut cursor)?;
callback(etype, name, 0, size, mtime)?;
}
_ => {
callback(etype, name, 0, 0, 0)?;
}
}
}
if !cursor.is_empty() {
bail!("unable to parse whole catalog data block");
}
Ok(())
}
} }
pub struct CatalogWriter<W> { pub struct CatalogWriter<W> {
@ -280,16 +321,7 @@ impl <R: Read + Seek> CatalogReader<R> {
let data = self.reader.read_exact_allocated(size as usize)?; let data = self.reader.read_exact_allocated(size as usize)?;
let mut cursor = &data[..]; DirInfo::parse(&data, |etype, name, offset, size, mtime| {
let entries = catalog_decode_u64(&mut cursor)?;
//println!("TEST {} {} size {}", start, entries, size);
for _ in 0..entries {
let etype = CatalogEntryType::try_from(Self::next_byte(&mut cursor)?)?;
let name_len = catalog_decode_u64(&mut cursor)?;
let name = cursor.read_exact_allocated(name_len as usize)?;
let mut path = std::path::PathBuf::from(prefix); let mut path = std::path::PathBuf::from(prefix);
path.push(std::ffi::OsString::from_vec(name)); path.push(std::ffi::OsString::from_vec(name));
@ -297,7 +329,6 @@ impl <R: Read + Seek> CatalogReader<R> {
match etype { match etype {
CatalogEntryType::Directory => { CatalogEntryType::Directory => {
println!("{} {:?}", char::from(etype as u8), path); println!("{} {:?}", char::from(etype as u8), path);
let offset = catalog_decode_u64(&mut cursor)?;
if offset > start { if offset > start {
bail!("got wrong directory offset ({} > {})", offset, start); bail!("got wrong directory offset ({} > {})", offset, start);
} }
@ -305,31 +336,24 @@ impl <R: Read + Seek> CatalogReader<R> {
self.dump_dir(&path, pos)?; self.dump_dir(&path, pos)?;
} }
CatalogEntryType::File => { CatalogEntryType::File => {
let size = catalog_decode_u64(&mut cursor)?;
let mtime = catalog_decode_u64(&mut cursor)?;
let dt = Local.timestamp(mtime as i64, 0); let dt = Local.timestamp(mtime as i64, 0);
println!("{} {:?} {} {}", println!(
"{} {:?} {} {}",
char::from(etype as u8), char::from(etype as u8),
path, path,
size, size,
dt.to_rfc3339_opts(chrono::SecondsFormat::Secs, false) dt.to_rfc3339_opts(chrono::SecondsFormat::Secs, false),
); );
} }
_ => { _ => {
println!("{} {:?}", char::from(etype as u8), path); println!("{} {:?}", char::from(etype as u8), path);
} }
} }
}
if !cursor.is_empty() {
bail!("unable to parse whole catalog data block");
}
Ok(()) Ok(())
})
} }
} }
/// Serialize u64 as short, variable length byte sequence /// Serialize u64 as short, variable length byte sequence