use crate::errors::AssetErrors;
use anyhow::{anyhow, Result};
use encoding_rs::WINDOWS_1252;
use std::io::Read;
pub struct ResourceIndexItem {
pub uid: String,
pub name: String,
pub char_name: Option<String>,
pub start: u32,
pub unknown: u32,
pub size: u32,
}
impl ResourceIndexItem {
pub fn read<T: Read>(mut reader: T) -> Result<Self> {
let mut buffer = [0; 2];
reader.read(&mut buffer)?;
let values = unsafe {
let (_, values, _) = buffer.align_to::<u16>();
values
};
let [uid_length] = values[..] else {
return Err(anyhow!(AssetErrors::ParserError).context("index item uid length"));
};
let mut buffer = vec![0; uid_length.into()];
reader.read(&mut buffer)?;
let uid = String::from_utf8(buffer)?;
let mut buffer = [0; 1];
reader.read(&mut buffer)?;
assert_eq!(buffer[0], 0);
let mut buffer = [0; 4 * 3];
reader.read(&mut buffer)?;
let values = unsafe {
let (_, values, _) = buffer.align_to::<u32>();
values
};
let [start, unknown, size] = values[..] else {
return Err(anyhow!(AssetErrors::ParserError).context("index item start/unknown/size"));
};
let mut buffer = [0; 2];
reader.read(&mut buffer)?;
let values = unsafe {
let (_, values, _) = buffer.align_to::<u16>();
values
};
let [name_length] = values[..] else {
return Err(anyhow!(AssetErrors::ParserError).context("index item name length"));
};
let mut buffer = vec![0; name_length.into()];
reader.read(&mut buffer)?;
let (name, _, _) = WINDOWS_1252.decode(&buffer);
let name = name.into_owned();
let mut buffer = [0; 2];
reader.read(&mut buffer)?;
let values = unsafe {
let (_, values, _) = buffer.align_to::<u16>();
values
};
let char_name = match values[0] {
0 => {
let mut buffer = [0; 2];
reader.read(&mut buffer)?;
None
}
len => {
let mut buffer = vec![0; len.into()];
reader.read(&mut buffer)?;
let (char_name, _, _) = WINDOWS_1252.decode(&buffer);
let char_name = char_name.into_owned();
let mut buffer = [0; 1];
reader.read(&mut buffer)?;
Some(char_name)
}
};
Ok(Self {
uid,
name,
char_name,
start,
unknown,
size,
})
}
}