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 0000000..bd71f7d Binary files /dev/null and b/test/li.txt.zst differ