an efficient binary archive format
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

cleanup

zach b8b873ce f501d42e

+17 -14
+1
include/bindle.h
··· 15 15 typedef enum BindleCompress { 16 16 BindleCompressNone, 17 17 BindleCompressZstd, 18 + BindleCompressAuto, 18 19 } BindleCompress; 19 20 20 21 typedef struct Bindle Bindle;
+8 -9
src/bin/bindle.rs
··· 101 101 Commands::List { bindle_file } => { 102 102 let b = init(bindle_file); 103 103 if b.is_empty() { 104 - println!("Archive is empty."); 104 + println!("Archive is empty"); 105 105 return Ok(()); 106 106 } 107 107 ··· 134 134 let mut b = init(bindle_file); 135 135 let data = std::fs::read(&file_path)?; 136 136 137 - println!("Adding '{}' ({} bytes)...", name, data.len()); 137 + println!("Adding '{}' ({} bytes)", name, data.len()); 138 138 139 139 b.add( 140 140 &name, ··· 147 147 )?; 148 148 b.save()?; 149 149 150 - println!("Successfully saved to archive."); 150 + println!("OK"); 151 151 } 152 152 153 153 Commands::Cat { name, bindle_file } => { ··· 171 171 compress, 172 172 } => { 173 173 let mut b = init(bindle_file); 174 - println!("Packing directory '{:?}'...", src_dir); 174 + println!("Packing '{}'", src_dir.display()); 175 175 b.pack( 176 176 src_dir, 177 177 if compress { ··· 181 181 }, 182 182 )?; 183 183 b.save()?; 184 - println!("Done."); 184 + println!("OK"); 185 185 } 186 186 187 187 Commands::Unpack { ··· 189 189 dest_dir, 190 190 } => { 191 191 let b = init(bindle_file); 192 - println!("Unpacking to '{:?}'...", dest_dir); 192 + println!("Unpacking to '{}'", dest_dir.display()); 193 193 b.unpack(dest_dir)?; 194 - println!("Done."); 194 + println!("OK"); 195 195 } 196 196 197 197 Commands::Vacuum { bindle_file } => { 198 198 let mut b = init(bindle_file); 199 - println!("Vacuuming archive to reclaim space..."); 200 199 b.vacuum()?; 201 - println!("Vacuum complete."); 200 + println!("OK"); 202 201 } 203 202 } 204 203 Ok(())
+8 -5
src/lib.rs
··· 14 14 const ENTRY_SIZE: usize = std::mem::size_of::<Entry>(); 15 15 const FOOTER_SIZE: usize = std::mem::size_of::<Footer>(); 16 16 const HEADER_SIZE: usize = 8; 17 + const AUTO_COMPRESS_THRESHOLD: usize = 2048; 17 18 18 19 fn pad< 19 20 const SIZE: usize, ··· 34 35 #[repr(C)] 35 36 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)] 36 37 pub enum Compress { 37 - #[default] 38 38 None, 39 39 Zstd, 40 + #[default] 41 + Auto, 40 42 } 41 43 42 44 #[repr(C, packed)] ··· 175 177 } 176 178 177 179 pub fn add(&mut self, name: &str, data: &[u8], compress: Compress) -> io::Result<()> { 178 - let (processed, c_type) = if compress == Compress::Zstd { 179 - (zstd::encode_all(data, 3)?, 1) 180 + let compress = compress == Compress::Zstd || data.len() > AUTO_COMPRESS_THRESHOLD; 181 + let (processed, c_type) = if compress { 182 + (Cow::Owned(zstd::encode_all(data, 3)?), Compress::Zstd) 180 183 } else { 181 - (data.to_vec(), 0) 184 + (Cow::Borrowed(data), Compress::None) 182 185 }; 183 186 184 187 self.file.seek(SeekFrom::Start(self.data_end))?; ··· 197 200 offset: offset.to_le_bytes(), 198 201 compressed_size: c_size.to_le_bytes(), 199 202 uncompressed_size: (data.len() as u64).to_le_bytes(), 200 - compression_type: c_type, 203 + compression_type: c_type as u8, 201 204 name_len: (name.len() as u16).to_le_bytes(), 202 205 ..Default::default() 203 206 };