use crate::raw::error::SdmpError;
pub const CODEC_SDMP7: u8 = 0x07;
pub const CODEC_SDMP8: u8 = 0x08;
pub const CODEC_C4: u8 = 0x04;
pub const CODEC_C2: u8 = 0x02;
pub const MAGIC: [u8; 4] = *b"SDMP";
pub struct Header {
pub codec: u8,
pub version: u8,
pub original_size: u32,
pub file_count: u32,
}
impl Header {
pub const SIZE: usize = 14;
pub fn read(bytes: &[u8]) -> Result<Self, SdmpError> {
if bytes.len() < Self::SIZE {
return Err(SdmpError::UnexpectedEof);
}
if bytes[0..4] != MAGIC {
return Err(SdmpError::NotAnSdmpFile);
}
let codec = bytes[4];
if ![CODEC_SDMP7, CODEC_SDMP8, CODEC_C4, CODEC_C2].contains(&codec) {
return Err(SdmpError::UnknownCodec(codec));
}
let version = bytes[5];
let original_size = u32::from_le_bytes([bytes[6], bytes[7], bytes[8], bytes[9]]);
let file_count = u32::from_le_bytes([bytes[10], bytes[11], bytes[12], bytes[13]]);
Ok(Self {
codec,
version,
original_size,
file_count,
})
}
#[must_use]
pub fn write(&self) -> [u8; Self::SIZE] {
let mut bytes = [0u8; Self::SIZE];
bytes[0..4].copy_from_slice(&MAGIC);
bytes[4] = self.codec;
bytes[5] = self.version;
bytes[6..10].copy_from_slice(&self.original_size.to_le_bytes());
bytes[10..14].copy_from_slice(&self.file_count.to_le_bytes());
bytes
}
}