From 2c0fcc47a0ff32f611bb603ddb1af02035e21bc4 Mon Sep 17 00:00:00 2001 From: Nathan Fisher Date: Tue, 23 Jan 2024 00:07:03 -0500 Subject: [PATCH] Add detection for zstd compression. Reader must implement Read + Seek --- .gitignore | 1 + README.md | 2 +- src/lib.rs | 25 ++++++++++++++++++++++++- test/li.txt.zst | Bin 0 -> 537 bytes 4 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 test/li.txt.zst diff --git a/.gitignore b/.gitignore index bd670cc..5cfe772 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target test/ !test/li.txt +!test/li.txt.zst diff --git a/README.md b/README.md index deb3885..38777dc 100644 --- a/README.md +++ b/README.md @@ -38,4 +38,4 @@ to see Haggis implemented in other languages. - [x] List archive nodes - [x] Override user/group when creating archives - [x] Override user/group when extracting archives -- [ ] Automatically detect zstd compressed archives +- [x] Automatically detect zstd compressed archives diff --git a/src/lib.rs b/src/lib.rs index cc91538..1e00ae8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,7 +3,7 @@ use std::{ collections::HashMap, fs, - io::{BufWriter, Write}, + io::{BufWriter, Read, Seek, Write}, sync::Mutex, }; #[cfg(feature = "parallel")] @@ -41,6 +41,18 @@ pub use stream::Message as StreamMessage; pub static MAGIC: [u8; 7] = [0x89, b'h', b'a', b'g', b'g', b'i', b's']; +static ZSTD_MAGIC: [u8; 4] = [0x28, 0xb5, 0x2f, 0xfd]; + +/// Tries to detect if the bytes in *reader* are zstd compressed +/// # Errors +/// Returns `Error` if io fails +pub fn detect_zstd(reader: &mut R) -> Result { + let mut buf = [0; 4]; + reader.read_exact(&mut buf)?; + reader.rewind()?; + Ok(buf == ZSTD_MAGIC) +} + /// Creates a haggis archive from a list of files /// # Errors /// Returns `crate::Error` if io fails or several other error conditions @@ -176,3 +188,14 @@ pub fn par_stream_archive( sender.send(Message::Eof).map_err(|_| Error::SenderError)?; Ok(()) } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn check_zstd() { + let mut fd = fs::File::open("test/li.txt.zst").unwrap(); + assert!(detect_zstd(&mut fd).unwrap()); + } +} diff --git a/test/li.txt.zst b/test/li.txt.zst new file mode 100644 index 0000000000000000000000000000000000000000..bd71f7d3c6780ec9878a7490cde98cf3bfb3f283 GIT binary patch literal 537 zcmV+!0_OcFwJ-f-?E+m802ZZM9B@gJ2Y4Z6w6X~8Z=cvMl{k=^f`Os+P3i9rAyEKR z08s$%I(Mm7Skt;Pdu+}^t;36x5~%Z|F-J zaD(mYNSawo?4WCNv8l~tUT`6uZLjCfaqLa(Sb7Qqg>a)3XuFn(9p@@Nq=$`JPx4~h z(9vBVoZ}!K^CjN3t3ydzY-8vq```v=A7;|{Yubco`Vs=67(-OTkPE37S(ea#`>y!g zXbXf#G9I`=*N9!kX-8@WJAfNlrj#h?l-lR+dx4gfR9OJUpk2bW7uLtO4Q84SH`)1Z z?c^wN99%2b5^XM|!|9;jI>J{Lu5YucEaNrhn?Vnrlh_P|cyZQU#h|;+V_zGLw-PVv zNl*-?g!@k73~nF{mPgBA_qA4dQHqmZaB1n0g*YFr7uam2 z!D8;OF&jci)A3toO!>NC9~wR&5EKDYmL9PO2oSls3xKlJCjqSY?$#p99$*xjo&~yw ziFfP3cFv7~Q_mM0xU2(5QPvu5sRPMqrVyY~FsiC>paJ6Vb7v6}6zOc7$d30Fp{};3 zj^59_W2Db0XsC0i@F*(F+zJR