use crate::{
deserializer::{
consumed::Consumed,
number::{read_signed_int, read_unsigned_int},
string::read_string,
},
error::{Result, TypedStreamError},
};
pub fn validate_header(data: &[u8]) -> Result<Consumed<bool>> {
let typedstream_version = read_unsigned_int(data)?;
let signature = read_string(&data[typedstream_version.bytes_consumed..])?;
let system_version =
read_signed_int(&data[typedstream_version.bytes_consumed + signature.bytes_consumed..])?;
if typedstream_version.value != 4
|| signature.value != "streamtyped"
|| system_version.value != 1000
{
return Err(TypedStreamError::InvalidHeader);
}
Ok(Consumed::new(
true,
typedstream_version.bytes_consumed
+ signature.bytes_consumed
+ system_version.bytes_consumed,
))
}
#[cfg(test)]
mod header_tests {
extern crate std;
use alloc::vec;
use std::{env::current_dir, fs::File, io::Read, println};
use crate::deserializer::{constants::I_16, header::validate_header};
#[test]
fn can_validate_header() {
let data = [
0x04, 0x0b, b's', b't', b'r', b'e', b'a', b'm', b't', b'y', b'p', b'e', b'd', I_16, 0xe8, 0x03, ];
let result = validate_header(&data).unwrap();
assert!(result.value);
assert_eq!(result.bytes_consumed, 16);
}
#[test]
fn can_validate_real_header() {
let typedstream_path = current_dir()
.unwrap()
.as_path()
.join("src/test_data/AttributedBodyTextOnly");
println!("Parsing file: {typedstream_path:?}");
let mut file = File::open(typedstream_path).unwrap();
let mut bytes = vec![];
file.read_to_end(&mut bytes).unwrap();
let validated = validate_header(&bytes).unwrap();
assert!(validated.value);
assert_eq!(validated.bytes_consumed, 16);
}
#[test]
fn fails_on_invalid_header() {
let data = [0x01]; assert!(validate_header(&data).is_err());
}
}