1use std::{
2 io::{Read, Seek, Result},
3 mem::size_of,
4};
5use bytemuck::{Pod, Zeroable};
6
7use super::{
8 bin::{read_struct, Readable},
9 magicnumber::MagicNumber,
10};
11pub use super::str::{BZString, ZString};
12
13
14#[repr(C)]
15#[derive(Debug, Clone, Copy, Zeroable, Pod)]
16pub struct Header {
17 pub offset_hash_table: u32,
18 pub num_files: u32,
19}
20impl Readable for Header {
21 fn offset(_: &()) -> Option<usize> {
22 Some(size_of::<MagicNumber>())
23 }
24 fn read_here<R: Read + Seek>(reader: R, _: &()) -> Result<Self> {
25 read_struct(reader)
26 }
27}
28
29pub struct V001(pub Header);
30
31#[repr(C)]
32#[derive(Debug, Clone, Copy, Zeroable, Pod)]
33pub struct FileRecord {
34 pub size: u32,
35 pub offset: u32,
36}
37impl Readable for FileRecord {
38 fn read_here<R: Read + Seek>(reader: R, _: &()) -> Result<Self> {
39 read_struct(reader)
40 }
41}
42
43#[derive(Debug)]
44pub struct FileRecords(pub Vec<FileRecord>);
45impl Readable for FileRecords {
46 type ReadableArgs = Header;
47 fn offset(_: &Header) -> Option<usize> {
48 Header::offset0().map(|h| h + size_of::<Header>())
49 }
50 fn read_here<R: Read + Seek>(reader: R, header: &Header) -> Result<Self> {
51 FileRecord::read_many0(reader, header.num_files as usize)
52 .map(FileRecords)
53 }
54}
55
56#[derive(Debug)]
57pub struct FileNames(pub Vec<ZString>);
58impl Readable for FileNames {
59 type ReadableArgs = Header;
60 fn offset(header: &Header) -> Option<usize> {
61 FileRecords::offset(header)
62 .map(|fr| fr + (header.num_files as usize) * size_of::<FileRecord>())
63 }
64 fn read_here<R: Read + Seek>(reader: R, header: &Header) -> Result<Self> {
65 ZString::read_many0(reader, header.num_files as usize)
66 .map(FileNames)
67 }
68}
69
70
71#[derive(Debug)]
72pub struct FileNameHashes(pub Vec<u64>);
73impl Readable for FileNameHashes {
74 type ReadableArgs = Header;
75 fn offset(header: &Header) -> Option<usize> {
76 Header::offset0().map(|h| (header.offset_hash_table as usize) - h)
77 }
78 fn read_here<R: Read + Seek>(reader: R, header: &Header) -> Result<Self> {
79 u64::read_many0(reader, header.num_files as usize)
80 .map(FileNameHashes)
81 }
82}