#![allow(unused_variables)]
use std::io::Cursor;
use binrw::BinRead;
use binrw::binrw;
use crate::common::{Language, Platform};
use crate::exh::ExcelDataPagination;
use crate::{ByteSpan, ReadableFile};
#[binrw]
#[brw(magic = b"EXDF")]
#[brw(big)]
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub(crate) struct EXDHeader {
pub(crate) version: u16,
pub(crate) unk1: u16,
pub(crate) data_offset_size: u32,
#[brw(pad_after = 16)] pub(crate) data_section_size: u32,
}
impl EXDHeader {
pub(crate) const SIZE: usize = 0x20;
}
#[binrw]
#[brw(big)]
#[derive(Debug, Clone)]
pub(crate) struct ExcelDataOffset {
pub(crate) row_id: u32,
pub(crate) offset: u32,
}
#[binrw]
#[brw(big)]
#[allow(dead_code)]
#[derive(Debug)]
pub(crate) struct DataSectionHeader {
pub(crate) size: u32,
pub(crate) row_count: u16,
}
#[binrw]
#[brw(big)]
#[allow(dead_code)]
#[derive(Debug)]
pub(crate) struct SubRowHeader {
pub(crate) subrow_id: u16,
}
#[binrw]
#[brw(big)]
#[allow(dead_code)]
#[derive(Debug)]
pub(crate) struct DataSection {
pub(crate) header: DataSectionHeader,
#[br(temp, count = header.size)]
#[bw(ignore)]
data: Vec<u8>,
}
#[binrw]
#[brw(big)]
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct EXD {
pub(crate) header: EXDHeader,
#[br(count = header.data_offset_size / core::mem::size_of::<ExcelDataOffset>() as u32)]
#[bw(ignore)]
pub(crate) data_offsets: Vec<ExcelDataOffset>,
#[br(count = header.data_section_size)]
#[bw(ignore)]
pub(crate) remaining_data: Vec<u8>,
}
impl EXD {
pub fn calculate_filename(
name: &str,
language: Language,
page: &ExcelDataPagination,
) -> String {
match language {
Language::None => {
format!("{name}_{}.exd", page.start_id)
}
lang => {
format!("{name}_{}_{}.exd", page.start_id, lang.shortname())
}
}
}
}
impl ReadableFile for EXD {
fn from_existing(_platform: Platform, buffer: ByteSpan) -> Option<EXD> {
EXD::read_args(&mut Cursor::new(&buffer), ()).ok()
}
}
#[cfg(test)]
mod tests {
use crate::pass_random_invalid;
use super::*;
#[test]
fn test_invalid() {
pass_random_invalid::<EXD>();
}
}