litchi 0.0.1

High-performance parser for Microsoft Office, OpenDocument, and Apple iWork file formats with unified API
Documentation
//! ODF (OpenDocument Format) detection.

use std::io::{Read, Seek};
use crate::common::detection::FileFormat;

/// Detect ODF format from mimetype content.
/// Uses the standard ODF MIME type mapping.
pub fn detect_odf_format_from_mimetype(mimetype: &[u8]) -> Option<FileFormat> {
    let mime_str = String::from_utf8_lossy(mimetype).trim().to_string();

    match mime_str.as_str() {
        "application/vnd.oasis.opendocument.text" => Some(FileFormat::Odt),
        "application/vnd.oasis.opendocument.spreadsheet" => Some(FileFormat::Ods),
        "application/vnd.oasis.opendocument.presentation" => Some(FileFormat::Odp),
        _ => None,
    }
}

/// Detect ODF format from byte content.
/// Reads mimetype file directly from ZIP archive.
pub fn detect_odf_format(bytes: &[u8]) -> Option<FileFormat> {
    // Check if it starts with ZIP signature
    if bytes.len() < 4 || &bytes[0..4] != crate::common::detection::utils::ZIP_SIGNATURE {
        return None;
    }

    // Create a cursor to read the ZIP file
    let cursor = std::io::Cursor::new(bytes);
    detect_odf_format_from_reader(&mut cursor.clone())
}

/// Detect ODF format from a reader.
/// Reads mimetype file directly from ZIP archive.
pub fn detect_odf_format_from_reader<R: Read + Seek>(
    reader: &mut R
) -> Option<FileFormat> {
    use std::io::Cursor;

    // Read the entire file into memory for ZIP analysis
    let mut buffer = Vec::new();
    if reader.read_to_end(&mut buffer).is_err() {
        return None;
    }

    // Reset reader position
    let _ = reader.seek(std::io::SeekFrom::Start(0));

    // Try to open as ZIP archive
    let cursor = Cursor::new(&buffer);
    let zip_result = zip::ZipArchive::new(cursor);

    if let Ok(mut archive) = zip_result {
        // Read MIME type from mimetype file
        if let Ok(mimetype) = crate::common::detection::utils::read_zip_file(&mut archive, "mimetype") {
            return detect_odf_format_from_mimetype(&mimetype);
        }
    }

    None
}