source2_demo/string_table/
mod.rs1mod 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 pub fn iter(&self) -> impl Iterator<Item = &StringTableRow> {
36 self.items.iter()
37 }
38
39 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}