source2_demo/string_table/
mod.rs

1mod container;
2mod row;
3
4pub use container::*;
5pub use row::*;
6
7use crate::entity::BaselineContainer;
8use crate::error::StringTableError;
9use crate::reader::{BitsReader, Reader};
10use std::cell::RefCell;
11use std::rc::Rc;
12
13#[derive(Clone, Default)]
14pub struct StringTable {
15    pub(crate) index: i32,
16    pub(crate) name: String,
17    pub(crate) items: Vec<StringTableRow>,
18    pub(crate) user_data_fixed_size: bool,
19    pub(crate) user_data_size: i32,
20    pub(crate) flags: u32,
21    pub(crate) var_int_bit_counts: bool,
22    pub(crate) keys: RefCell<Vec<String>>,
23}
24
25impl StringTable {
26    pub fn index(&self) -> i32 {
27        self.index
28    }
29
30    pub fn name(&self) -> &str {
31        &self.name
32    }
33
34    /// Iterator over string table rows.
35    pub fn iter(&self) -> impl Iterator<Item = &StringTableRow> {
36        self.items.iter()
37    }
38
39    /// Returns [`StringTableRow`] for given index.
40    pub fn get_row_by_index(&self, idx: usize) -> Result<&StringTableRow, StringTableError> {
41        self.items
42            .get(idx)
43            .ok_or(StringTableError::RowNotFoundByIndex(
44                idx as i32,
45                self.name.clone(),
46            ))
47    }
48
49    pub(crate) fn parse(
50        &mut self,
51        baselines: &mut BaselineContainer,
52        buf: &[u8],
53        num_updates: i32,
54    ) -> Result<Vec<i32>, StringTableError> {
55        let items = &mut self.items;
56        let mut reader = Reader::new(buf);
57        let mut index = -1;
58        let mut delta_pos = 0;
59        let mut keys = self.keys.borrow_mut();
60
61        let mut modified = vec![];
62
63        if self.name == "decalprecache" {
64            return Ok(modified);
65        }
66
67        for _ in 0..num_updates {
68            reader.refill();
69
70            index += 1;
71            if !reader.read_bool() {
72                index += reader.read_var_u32() as i32 + 1;
73            }
74
75            let key = reader.read_bool().then(|| {
76                let delta_zero = if delta_pos > 32 { delta_pos & 31 } else { 0 };
77                let key = if reader.read_bool() {
78                    let pos = (delta_zero + reader.read_bits_no_refill(5) as usize) & 31;
79                    let size = reader.read_bits_no_refill(5) as usize;
80
81                    if delta_pos < pos || keys[pos].len() < size {
82                        reader.read_string()
83                    } else {
84                        let x = String::new();
85                        x + &keys[pos][..size] + &reader.read_string()
86                    }
87                } else {
88                    reader.read_string()
89                };
90                keys[delta_pos & 31].clone_from(&key);
91                delta_pos += 1;
92                key
93            });
94
95            let value = reader.read_bool().then(|| {
96                let mut is_compressed = false;
97                let bit_size = if self.user_data_fixed_size {
98                    self.user_data_size as u32
99                } else {
100                    if (self.flags & 0x1) != 0 {
101                        is_compressed = reader.read_bool();
102                    }
103                    if self.var_int_bit_counts {
104                        reader.read_ubit_var() * 8
105                    } else {
106                        reader.read_bits_no_refill(17) * 8
107                    }
108                };
109
110                let value = Rc::new(if is_compressed {
111                    let mut decoder = snap::raw::Decoder::new();
112                    decoder
113                        .decompress_vec(&reader.read_bits_as_bytes(bit_size))
114                        .unwrap()
115                } else {
116                    reader.read_bits_as_bytes(bit_size)
117                });
118
119                if self.name == "instancebaseline" {
120                    baselines.add_baseline(key.as_ref().unwrap().parse().unwrap_or(-1), value.clone());
121                }
122
123                value
124            });
125
126            if let Some(x) = items.get_mut(index as usize) {
127                if let Some(k) = key {
128                    x.key = k;
129                }
130                x.value = value;
131            } else {
132                items.push(StringTableRow::new(index, key.unwrap_or_default(), value));
133            }
134
135            modified.push(index);
136        }
137
138        Ok(modified)
139    }
140}