bsalib/
v001.rs

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}