feat: Add listing and decompressing support for lzip

This commit is contained in:
Mathias Zhang 2025-07-03 19:17:03 +08:00
parent 16a1c308b4
commit 2216764e1d
No known key found for this signature in database
5 changed files with 24 additions and 3 deletions

View File

@ -75,6 +75,9 @@ pub fn compress_files(
encoder,
level.map_or(6, |l| (l as u32).clamp(0, 9)),
)),
Lzip => return Err(crate::Error::UnsupportedFormat {
reason: "Lzip compression is not supported in ouch.".to_string(),
}),
Snappy => Box::new(
gzp::par::compress::ParCompress::<gzp::snap::Snap>::builder()
.compression_level(gzp::par::compress::Compression::new(
@ -111,7 +114,7 @@ pub fn compress_files(
}
match first_format {
Gzip | Bzip | Bzip3 | Lz4 | Lzma | Xz | Snappy | Zstd | Brotli => {
Gzip | Bzip | Bzip3 | Lz4 | Lzma | Xz | Lzip | Snappy | Zstd | Brotli => {
writer = chain_writer_encoder(&first_format, writer)?;
let mut reader = fs::File::open(&files[0])?;

View File

@ -132,6 +132,10 @@ pub fn decompress_file(options: DecompressOptions) -> crate::Result<()> {
liblzma::stream::Stream::new_lzma_decoder(u64::MAX).unwrap()
)),
Xz => Box::new(liblzma::read::XzDecoder::new(decoder)),
Lzip => Box::new(liblzma::read::XzDecoder::new_stream(
decoder,
liblzma::stream::Stream::new_lzip_decoder(u64::MAX, 0).unwrap(),
)),
Snappy => Box::new(snap::read::FrameDecoder::new(decoder)),
Zstd => Box::new(zstd::stream::Decoder::new(decoder)?),
Brotli => Box::new(brotli::Decompressor::new(decoder, BUFFER_CAPACITY)),
@ -147,7 +151,7 @@ pub fn decompress_file(options: DecompressOptions) -> crate::Result<()> {
}
let files_unpacked = match first_extension {
Gzip | Bzip | Bzip3 | Lz4 | Lzma | Xz | Snappy | Zstd | Brotli => {
Gzip | Bzip | Bzip3 | Lz4 | Lzma | Xz | Lzip | Snappy | Zstd | Brotli => {
reader = chain_reader_decoder(&first_extension, reader)?;
let mut writer = match utils::ask_to_create_file(

View File

@ -62,6 +62,10 @@ pub fn list_archive_contents(
liblzma::stream::Stream::new_lzma_decoder(u64::MAX).unwrap(),
)),
Xz => Box::new(liblzma::read::XzDecoder::new(decoder)),
Lzip => Box::new(liblzma::read::XzDecoder::new_stream(
decoder,
liblzma::stream::Stream::new_lzip_decoder(u64::MAX, 0).unwrap(),
)),
Snappy => Box::new(snap::read::FrameDecoder::new(decoder)),
Zstd => Box::new(zstd::stream::Decoder::new(decoder)?),
Brotli => Box::new(brotli::Decompressor::new(decoder, BUFFER_CAPACITY)),
@ -131,7 +135,7 @@ pub fn list_archive_contents(
Box::new(archive::sevenz::list_archive(io::Cursor::new(vec), password)?)
}
Gzip | Bzip | Bzip3 | Lz4 | Lzma | Xz | Snappy | Zstd | Brotli => {
Gzip | Bzip | Bzip3 | Lz4 | Lzma | Xz | Lzip | Snappy | Zstd | Brotli => {
unreachable!("Not an archive, should be validated before calling this function.");
}
};

View File

@ -89,6 +89,8 @@ pub enum CompressionFormat {
Xz,
/// .lzma
Lzma,
/// .lzip
Lzip,
/// .sz
Snappy,
/// tar, tgz, tbz, tbz2, tbz3, txz, tlz4, tlzma, tsz, tzst
@ -118,6 +120,7 @@ impl CompressionFormat {
Lz4 => false,
Lzma => false,
Xz => false,
Lzip => false,
Snappy => false,
Zstd => false,
Brotli => false,
@ -135,6 +138,7 @@ fn to_extension(ext: &[u8]) -> Option<Extension> {
b"tlz4" => &[Tar, Lz4],
b"txz" => &[Tar, Xz],
b"tlzma" => &[Tar, Lzma],
b"tlz" => &[Tar, Lzip],
b"tsz" => &[Tar, Snappy],
b"tzst" => &[Tar, Zstd],
b"zip" => &[Zip],
@ -144,6 +148,7 @@ fn to_extension(ext: &[u8]) -> Option<Extension> {
b"lz4" => &[Lz4],
b"xz" => &[Xz],
b"lzma" => &[Lzma],
b"lz" => &[Lzip],
b"sz" => &[Snappy],
b"zst" => &[Zstd],
b"rar" => &[Rar],

View File

@ -144,6 +144,9 @@ pub fn try_infer_extension(path: &Path) -> Option<Extension> {
fn is_xz(buf: &[u8]) -> bool {
buf.starts_with(&[0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00])
}
fn is_lzip(buf: &[u8]) -> bool {
buf.starts_with(&[0x4C, 0x5A, 0x49, 0x50])
}
fn is_lz4(buf: &[u8]) -> bool {
buf.starts_with(&[0x04, 0x22, 0x4D, 0x18])
}
@ -193,6 +196,8 @@ pub fn try_infer_extension(path: &Path) -> Option<Extension> {
Some(Extension::new(&[Lzma], "lzma"))
} else if is_xz(&buf) {
Some(Extension::new(&[Xz], "xz"))
} else if is_lzip(&buf) {
Some(Extension::new(&[Lzip], "lzip"))
} else if is_lz4(&buf) {
Some(Extension::new(&[Lz4], "lz4"))
} else if is_sz(&buf) {