Merge pull request #215 from figsoda/snappy

support snappy format
This commit is contained in:
João Marcos Bezerra 2021-12-08 00:17:59 -03:00 committed by GitHub
commit fddc79628a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 34 additions and 12 deletions

7
Cargo.lock generated
View File

@ -454,6 +454,7 @@ dependencies = [
"parse-display", "parse-display",
"proptest", "proptest",
"rand", "rand",
"snap",
"tar", "tar",
"tempfile", "tempfile",
"test-strategy", "test-strategy",
@ -713,6 +714,12 @@ dependencies = [
"winapi-util", "winapi-util",
] ]
[[package]]
name = "snap"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45456094d1983e2ee2a18fdfebce3189fa451699d0502cb8e3b49dba5ba41451"
[[package]] [[package]]
name = "strsim" name = "strsim"
version = "0.10.0" version = "0.10.0"

View File

@ -22,6 +22,7 @@ libc = "0.2.103"
linked-hash-map = "0.5.4" linked-hash-map = "0.5.4"
lzzzz = "0.8.0" lzzzz = "0.8.0"
once_cell = "1.8.0" once_cell = "1.8.0"
snap = "1.0.5"
tar = "0.4.37" tar = "0.4.37"
walkdir = "2.3.2" walkdir = "2.3.2"
xz2 = "0.1.6" xz2 = "0.1.6"

View File

@ -72,11 +72,11 @@ ouch c file.txt file.zip
# Supported formats # Supported formats
| Format | `.tar` | `.zip` | `.bz`, `.bz2` | `.gz` | `.lz4` | `.xz`, `.lzma` | `.zst` | | Format | `.tar` | `.zip` | `.bz`, `.bz2` | `.gz` | `.lz4` | `.xz`, `.lzma` | `.sz` | `.zst` |
|:---------:|:------:|:------:|:-------------:|:-----:|:------:|:---------------------:|:------:| |:---------:|:------:|:------:|:-------------:|:-----:|:------:|:--------------:|:-----:|:-------|
| Supported | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | Supported | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
And the aliases: `tgz`, `tbz`, `tbz2`, `tlz4`, `txz`, `tlz`, `tlzma`, `tzst`. And the aliases: `tgz`, `tbz`, `tbz2`, `tlz4`, `txz`, `tlzma`, `tsz`, `tzst`.
Formats can be chained: Formats can be chained:

View File

@ -309,6 +309,7 @@ fn compress_files(
Bzip => Box::new(bzip2::write::BzEncoder::new(encoder, Default::default())), Bzip => Box::new(bzip2::write::BzEncoder::new(encoder, Default::default())),
Lz4 => Box::new(lzzzz::lz4f::WriteCompressor::new(encoder, Default::default())?), Lz4 => Box::new(lzzzz::lz4f::WriteCompressor::new(encoder, Default::default())?),
Lzma => Box::new(xz2::write::XzEncoder::new(encoder, 6)), Lzma => Box::new(xz2::write::XzEncoder::new(encoder, 6)),
Snappy => Box::new(snap::write::FrameEncoder::new(encoder)),
Zstd => { Zstd => {
let zstd_encoder = zstd::stream::write::Encoder::new(encoder, Default::default()); let zstd_encoder = zstd::stream::write::Encoder::new(encoder, Default::default());
// Safety: // Safety:
@ -326,7 +327,7 @@ fn compress_files(
} }
match formats[0].compression_formats[0] { match formats[0].compression_formats[0] {
Gzip | Bzip | Lz4 | Lzma | Zstd => { Gzip | Bzip | Lz4 | Lzma | Snappy | Zstd => {
let _progress = Progress::new_accessible_aware( let _progress = Progress::new_accessible_aware(
total_input_size, total_input_size,
precise, precise,
@ -462,6 +463,7 @@ fn decompress_file(
Bzip => Box::new(bzip2::read::BzDecoder::new(decoder)), Bzip => Box::new(bzip2::read::BzDecoder::new(decoder)),
Lz4 => Box::new(lzzzz::lz4f::ReadDecompressor::new(decoder)?), Lz4 => Box::new(lzzzz::lz4f::ReadDecompressor::new(decoder)?),
Lzma => Box::new(xz2::read::XzDecoder::new(decoder)), Lzma => Box::new(xz2::read::XzDecoder::new(decoder)),
Snappy => Box::new(snap::read::FrameDecoder::new(decoder)),
Zstd => Box::new(zstd::stream::Decoder::new(decoder)?), Zstd => Box::new(zstd::stream::Decoder::new(decoder)?),
Tar | Zip => unreachable!(), Tar | Zip => unreachable!(),
}; };
@ -474,7 +476,7 @@ fn decompress_file(
let files_unpacked; let files_unpacked;
match formats[0].compression_formats[0] { match formats[0].compression_formats[0] {
Gzip | Bzip | Lz4 | Lzma | Zstd => { Gzip | Bzip | Lz4 | Lzma | Snappy | Zstd => {
reader = chain_reader_decoder(&formats[0].compression_formats[0], reader)?; reader = chain_reader_decoder(&formats[0].compression_formats[0], reader)?;
let writer = utils::create_or_ask_overwrite(&output_file_path, question_policy)?; let writer = utils::create_or_ask_overwrite(&output_file_path, question_policy)?;
@ -594,6 +596,7 @@ fn list_archive_contents(
Bzip => Box::new(bzip2::read::BzDecoder::new(decoder)), Bzip => Box::new(bzip2::read::BzDecoder::new(decoder)),
Lz4 => Box::new(lzzzz::lz4f::ReadDecompressor::new(decoder)?), Lz4 => Box::new(lzzzz::lz4f::ReadDecompressor::new(decoder)?),
Lzma => Box::new(xz2::read::XzDecoder::new(decoder)), Lzma => Box::new(xz2::read::XzDecoder::new(decoder)),
Snappy => Box::new(snap::read::FrameDecoder::new(decoder)),
Zstd => Box::new(zstd::stream::Decoder::new(decoder)?), Zstd => Box::new(zstd::stream::Decoder::new(decoder)?),
Tar | Zip => unreachable!(), Tar | Zip => unreachable!(),
}; };
@ -625,7 +628,7 @@ fn list_archive_contents(
crate::archive::zip::list_archive(zip_archive)? crate::archive::zip::list_archive(zip_archive)?
} }
Gzip | Bzip | Lz4 | Lzma | Zstd => { Gzip | Bzip | Lz4 | Lzma | Snappy | Zstd => {
panic!("Not an archive! This should never happen, if it does, something is wrong with `CompressionFormat::is_archive()`. Please report this error!"); panic!("Not an archive! This should never happen, if it does, something is wrong with `CompressionFormat::is_archive()`. Please report this error!");
} }
}; };

View File

@ -57,7 +57,9 @@ pub enum CompressionFormat {
Lz4, Lz4,
/// .xz .lzma /// .xz .lzma
Lzma, Lzma,
/// tar, tgz, tbz, tbz2, txz, tlz, tlz4, tlzma, tzst /// .sz
Snappy,
/// tar, tgz, tbz, tbz2, txz, tlz4, tlzma, tsz, tzst
Tar, Tar,
/// .zst /// .zst
Zstd, Zstd,
@ -75,6 +77,7 @@ impl CompressionFormat {
Bzip => false, Bzip => false,
Lz4 => false, Lz4 => false,
Lzma => false, Lzma => false,
Snappy => false,
Zstd => false, Zstd => false,
} }
} }
@ -91,6 +94,7 @@ impl fmt::Display for CompressionFormat {
Zstd => ".zst", Zstd => ".zst",
Lz4 => ".lz4", Lz4 => ".lz4",
Lzma => ".lz", Lzma => ".lz",
Snappy => ".sz",
Tar => ".tar", Tar => ".tar",
Zip => ".zip", Zip => ".zip",
} }
@ -121,13 +125,15 @@ pub fn separate_known_extensions_from_name(mut path: &Path) -> (&Path, Vec<Exten
"tgz" => &[Tar, Gzip], "tgz" => &[Tar, Gzip],
"tbz" | "tbz2" => &[Tar, Bzip], "tbz" | "tbz2" => &[Tar, Bzip],
"tlz4" => &[Tar, Lz4], "tlz4" => &[Tar, Lz4],
"txz" | "tlz" | "tlzma" => &[Tar, Lzma], "txz" | "tlzma" => &[Tar, Lzma],
"tsz" => &[Tar, Snappy],
"tzst" => &[Tar, Zstd], "tzst" => &[Tar, Zstd],
"zip" => &[Zip], "zip" => &[Zip],
"bz" | "bz2" => &[Bzip], "bz" | "bz2" => &[Bzip],
"gz" => &[Gzip], "gz" => &[Gzip],
"lz4" => &[Lz4], "lz4" => &[Lz4],
"xz" | "lzma" => &[Lzma], "xz" | "lzma" => &[Lzma],
"sz" => &[Snappy],
"zst" => &[Zstd], "zst" => &[Zstd],
_ => break, _ => break,
}; };

View File

@ -83,6 +83,9 @@ pub fn try_infer_extension(path: &Path) -> Option<Extension> {
fn is_lz4(buf: &[u8]) -> bool { fn is_lz4(buf: &[u8]) -> bool {
buf.starts_with(&[0x04, 0x22, 0x4D, 0x18]) buf.starts_with(&[0x04, 0x22, 0x4D, 0x18])
} }
fn is_sz(buf: &[u8]) -> bool {
buf.starts_with(&[0xFF, 0x06, 0x00, 0x00, 0x73, 0x4E, 0x61, 0x50, 0x70, 0x59])
}
fn is_zst(buf: &[u8]) -> bool { fn is_zst(buf: &[u8]) -> bool {
buf.starts_with(&[0x28, 0xB5, 0x2F, 0xFD]) buf.starts_with(&[0x28, 0xB5, 0x2F, 0xFD])
} }
@ -113,6 +116,8 @@ pub fn try_infer_extension(path: &Path) -> Option<Extension> {
Some(Extension::new(&[Lzma], "xz")) Some(Extension::new(&[Lzma], "xz"))
} else if is_lz4(&buf) { } else if is_lz4(&buf) {
Some(Extension::new(&[Lz4], "lz4")) Some(Extension::new(&[Lz4], "lz4"))
} else if is_sz(&buf) {
Some(Extension::new(&[Snappy], "sz"))
} else if is_zst(&buf) { } else if is_zst(&buf) {
Some(Extension::new(&[Zstd], "zst")) Some(Extension::new(&[Zstd], "zst"))
} else { } else {

View File

@ -20,8 +20,8 @@ enum DirectoryExtension {
Tbz, Tbz,
Tgz, Tgz,
Tlz4, Tlz4,
Tlz,
Tlzma, Tlzma,
Tsz,
Txz, Txz,
Zip, Zip,
} }
@ -35,6 +35,7 @@ enum FileExtension {
Gz, Gz,
Lz4, Lz4,
Lzma, Lzma,
Sz,
Xz, Xz,
} }

View File

@ -17,7 +17,7 @@ fn sanity_check_through_mime() {
write_random_content(test_file, &mut SmallRng::from_entropy()); write_random_content(test_file, &mut SmallRng::from_entropy());
let formats = [ let formats = [
"tar", "zip", "tar.gz", "tgz", "tbz", "tbz2", "txz", "tlz", "tlzma", "tzst", "tar.bz", "tar.bz2", "tar.lzma", "tar", "zip", "tar.gz", "tgz", "tbz", "tbz2", "txz", "tlzma", "tzst", "tar.bz", "tar.bz2", "tar.lzma",
"tar.xz", "tar.zst", "tar.xz", "tar.zst",
]; ];
@ -30,7 +30,6 @@ fn sanity_check_through_mime() {
"application/x-bzip2", "application/x-bzip2",
"application/x-xz", "application/x-xz",
"application/x-xz", "application/x-xz",
"application/x-xz",
"application/zstd", "application/zstd",
"application/x-bzip2", "application/x-bzip2",
"application/x-bzip2", "application/x-bzip2",