use std::io::{Read, Seek};
use crate::common::detection::FileFormat;
pub fn detect_zip_format(bytes: &[u8]) -> Option<FileFormat> {
if bytes.len() < 4 || &bytes[0..4] != crate::common::detection::utils::ZIP_SIGNATURE {
return None;
}
let cursor = std::io::Cursor::new(bytes);
detect_zip_format_from_reader(&mut cursor.clone())
}
pub fn detect_zip_format_from_reader<R: Read + Seek>(
reader: &mut R
) -> Option<FileFormat> {
let package = match crate::ooxml::OpcPackage::from_reader(reader) {
Ok(pkg) => pkg,
Err(_) => return None,
};
detect_ooxml_format_from_package(&package)
}
pub fn detect_ooxml_format_from_package(package: &crate::ooxml::OpcPackage) -> Option<FileFormat> {
if package.iter_parts().any(|part| {
part.content_type().contains("wordprocessingml") ||
part.content_type().contains("document.main")
}) {
return Some(FileFormat::Docx);
}
if package.iter_parts().any(|part| {
part.content_type().contains("presentationml") ||
part.content_type().contains("presentation.main")
}) {
return Some(FileFormat::Pptx);
}
if package.iter_parts().any(|part| {
part.content_type().contains("spreadsheetml") ||
part.content_type().contains("worksheet") ||
part.content_type().contains("workbook")
}) {
let has_binary_parts = package.iter_parts().any(|part| {
part.content_type().contains("binary") ||
part.content_type().contains("xlsb")
});
if has_binary_parts {
return Some(FileFormat::Xlsb);
} else {
return Some(FileFormat::Xlsx);
}
}
None
}