Skip to main content

bom/
model.rs

1use deku::prelude::*;
2
3#[derive(Debug, PartialEq, DekuRead)]
4#[deku(endian = "big", magic = b"BOMStore")]
5pub struct StoreHeader {
6    // b'BOMStore'
7    // pub magic: [u8; 8],
8    // Always 1
9    pub version: u32,
10    // Number of non-null entries in BOMBlockTable
11    block_count: u32,
12    // Offset to index table
13    index_offset: u32,
14    // Length of index table, index_offset + index_len = file_length
15    index_len: u32,
16    // Offset to var table
17    var_offset: u32,
18    // Length of var table, var_offset + var_len = file_length
19    var_len: u32,
20    // unknown: [u8; 480],
21    #[deku(seek_from_start = "*index_offset as u64")]
22    pub index_store: IndexStore,
23    #[deku(seek_from_start = "*var_offset as u64")]
24    pub var_store: VariableStore,
25}
26
27#[derive(Debug, PartialEq, DekuRead)]
28#[deku(endian = "big", ctx = "endian: deku::ctx::Endian")]
29pub struct IndexStore {
30    count: u32,
31    #[deku(count = "count")]
32    pub indexs: Vec<Index>,
33}
34
35#[derive(Debug, PartialEq, DekuRead)]
36#[deku(endian = "big", ctx = "endian: deku::ctx::Endian")]
37pub struct Index {
38    pub offset: u32,
39    pub len: u32,
40}
41
42#[derive(Debug, PartialEq, DekuRead)]
43#[deku(endian = "big", ctx = "endian: deku::ctx::Endian")]
44pub struct VariableStore {
45    count: u32,
46    #[deku(count = "count")]
47    pub vars: Vec<Variable>,
48}
49
50#[derive(Debug, PartialEq, DekuRead)]
51#[deku(endian = "big", ctx = "endian: deku::ctx::Endian")]
52pub struct Variable {
53    pub index: u32,
54    pub len: u8,
55    #[deku(count = "len")]
56    pub name: Vec<u8>,
57}
58
59impl StoreHeader {
60    pub fn index_with_name(&self, name: &[u8]) -> Option<&Index> {
61        self.var_with_name(name)
62            .and_then(|var| self.index_store.indexs.get(var.index as usize))
63    }
64
65    pub fn var_with_name(&self, name: &[u8]) -> Option<&Variable> {
66        self.var_store.vars.iter().find(|var| var.name == name)
67    }
68}
69
70#[derive(Debug, PartialEq, DekuRead)]
71#[deku(endian = "big", magic = b"tree")]
72pub struct TreeHeader {
73    // // tree
74    // tag: [u8; 4],
75    // always 1
76    pub version: u32,
77    // Index for BOMPaths
78    pub index: u32,
79    // Always 4096
80    pub block_size: u32,
81    // Total number of paths in all leaves combined
82    pub path_count: u32,
83    unknown: u8,
84}
85
86#[derive(Debug, PartialEq, DekuRead)]
87#[deku(endian = "big")]
88pub struct TreePaths {
89    pub is_leaf: u16,
90    pub count: u16,
91    pub forward: u32,
92    pub backward: u32,
93    #[deku(count = "count")]
94    pub indices: Vec<TreePathIndex>,
95}
96
97#[derive(Debug, PartialEq, DekuRead)]
98#[deku(endian = "big", ctx = "endian: deku::ctx::Endian")]
99pub struct TreePathIndex {
100    pub val: u32,
101    pub key: u32,
102}
103
104#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, deku::DekuRead)]
105pub struct BOMStr {
106    #[deku(read_all, map = "crate::deku_read_str")]
107    pub content: String,
108}
109
110#[derive(Debug, PartialEq, PartialOrd, Eq, Ord, deku::DekuRead)]
111pub struct BOMBytes {
112    #[deku(read_all)]
113    pub content: Vec<u8>,
114}