use std::error::Error;
use std::io::prelude::*;
use flate2::read::GzDecoder;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FileType {
KerbalMachineCode,
KerbalObject,
Unknown,
}
pub fn determine_file_type(contents: &[u8]) -> Result<FileType, Box<dyn Error>> {
if contents.len() < 4 {
return Err("Error: Provided a file that is less than 4 bytes long".into());
}
if is_gzip(contents) {
let mut decoder = GzDecoder::new(contents);
let mut decompressed = [0, 0, 0, 0];
decoder.read_exact(&mut decompressed)?;
if is_ksm(&decompressed) {
return Ok(FileType::KerbalMachineCode);
}
} else if is_ko(contents) {
return Ok(FileType::KerbalObject);
}
Ok(FileType::Unknown)
}
fn is_gzip(contents: &[u8]) -> bool {
contents[0] == 0x1f && contents[1] == 0x8b && contents[2] == 0x08 && contents[3] == 0x00
}
fn is_ksm(contents: &[u8]) -> bool {
contents[0] == 0x6b && contents[1] == 0x03 && contents[2] == 0x58 && contents[3] == 0x45
}
fn is_ko(contents: &[u8]) -> bool {
contents[0] == 0x6b && contents[1] == 0x01 && contents[2] == 0x6f && contents[3] == 0x66
}