use super::CompressionFormat;
const GZIP_MAGIC: [u8; 2] = [0x1f, 0x8b];
const ZSTD_MAGIC: [u8; 4] = [0x28, 0xb5, 0x2f, 0xfd];
const XZ_MAGIC: [u8; 6] = [0xfd, 0x37, 0x7a, 0x58, 0x5a, 0x00];
const LZMA_MAGIC: [u8; 2] = [0x5d, 0x00];
const BZIP2_MAGIC: [u8; 3] = [0x42, 0x5a, 0x68];
pub const MIN_HEADER_SIZE: usize = 6;
pub fn detect_from_magic(header: &[u8]) -> CompressionFormat {
if header.len() >= 6 && header[..6] == XZ_MAGIC {
return CompressionFormat::Xz;
}
if header.len() >= 4 && header[..4] == ZSTD_MAGIC {
return CompressionFormat::Zstd;
}
if header.len() >= 3 && header[..3] == BZIP2_MAGIC {
return CompressionFormat::Bzip2;
}
if header.len() >= 2 && header[..2] == GZIP_MAGIC {
return CompressionFormat::Gzip;
}
if header.len() >= 2 && header[..2] == LZMA_MAGIC {
return CompressionFormat::Xz; }
CompressionFormat::None
}
pub fn is_binary(data: &[u8]) -> bool {
if data.contains(&0) {
return true;
}
let non_text_count = data
.iter()
.filter(|&&b| {
b < 0x20 && b != b'\n' && b != b'\r' && b != b'\t'
})
.count();
if data.len() > 10 && non_text_count * 10 > data.len() {
return true;
}
false
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_detect_gzip() {
let header = [0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00];
assert_eq!(detect_from_magic(&header), CompressionFormat::Gzip);
}
#[test]
fn test_detect_zstd() {
let header = [0x28, 0xb5, 0x2f, 0xfd, 0x00, 0x00];
assert_eq!(detect_from_magic(&header), CompressionFormat::Zstd);
}
#[test]
fn test_detect_xz() {
let header = [0xfd, 0x37, 0x7a, 0x58, 0x5a, 0x00];
assert_eq!(detect_from_magic(&header), CompressionFormat::Xz);
}
#[test]
fn test_detect_bzip2() {
let header = [0x42, 0x5a, 0x68, 0x39, 0x31, 0x41];
assert_eq!(detect_from_magic(&header), CompressionFormat::Bzip2);
}
#[test]
fn test_detect_plain_text() {
let header = b"Hello, World!";
assert_eq!(detect_from_magic(header), CompressionFormat::None);
}
#[test]
fn test_detect_empty() {
let header: &[u8] = &[];
assert_eq!(detect_from_magic(header), CompressionFormat::None);
}
#[test]
fn test_is_binary_with_nul() {
let data = b"hello\x00world";
assert!(is_binary(data));
}
#[test]
fn test_is_binary_plain_text() {
let data = b"Hello, World!\nThis is plain text.\n";
assert!(!is_binary(data));
}
#[test]
fn test_is_binary_with_tabs() {
let data = b"column1\tcolumn2\tcolumn3\n";
assert!(!is_binary(data));
}
#[test]
fn test_is_binary_high_non_printable() {
let data = [
0x01, 0x02, 0x03, b'a', b'b', b'c', b'd', b'e', b'f', b'g', b'h',
];
assert!(is_binary(&data));
}
}