physis/havok/
binary_tag_file_reader.rs

1// SPDX-FileCopyrightText: 2020 Inseok Lee
2// SPDX-License-Identifier: MIT
3
4#![allow(clippy::arc_with_non_send_sync)]
5
6use crate::havok::byte_reader::ByteReader;
7use crate::havok::object::{
8    HavokInteger, HavokObject, HavokObjectType, HavokObjectTypeMember, HavokRootObject, HavokValue,
9    HavokValueType,
10};
11use crate::havok::slice_ext::SliceByteOrderExt;
12use core::cell::RefCell;
13use std::collections::HashMap;
14use std::sync::Arc;
15
16#[repr(i8)]
17enum HavokTagType {
18    Eof = -1,
19    Invalid = 0,
20    FileInfo = 1,
21    Type = 2,
22    Object = 3,
23    ObjectRemember = 4,
24    Backref = 5,
25    ObjectNull = 6,
26    FileEnd = 7,
27}
28
29impl HavokTagType {
30    pub fn from_raw(raw: u8) -> Self {
31        match raw {
32            255 => HavokTagType::Eof,
33            0 => HavokTagType::Invalid,
34            1 => HavokTagType::FileInfo,
35            2 => HavokTagType::Type,
36            3 => HavokTagType::Object,
37            4 => HavokTagType::ObjectRemember,
38            5 => HavokTagType::Backref,
39            6 => HavokTagType::ObjectNull,
40            7 => HavokTagType::FileEnd,
41            _ => panic!(),
42        }
43    }
44}
45
46pub struct HavokBinaryTagFileReader<'a> {
47    file_version: u8,
48    remembered_strings: Vec<Arc<str>>,
49    remembered_types: Vec<Arc<HavokObjectType>>,
50    remembered_objects: Vec<Arc<RefCell<HavokObject>>>,
51    objects: Vec<Arc<RefCell<HavokObject>>>,
52    reader: ByteReader<'a>,
53}
54
55impl<'a> HavokBinaryTagFileReader<'a> {
56    pub fn read(data: &'a [u8]) -> HavokRootObject {
57        let mut reader = Self::new(ByteReader::new(data));
58
59        reader.do_read()
60    }
61
62    fn new(reader: ByteReader<'a>) -> Self {
63        let file_version = 0;
64        let remembered_strings = vec![Arc::from("string"), Arc::from("")];
65        let remembered_types = vec![Arc::new(HavokObjectType::new(
66            Arc::from("object"),
67            None,
68            Vec::new(),
69        ))];
70        let remembered_objects = Vec::new();
71        let objects = Vec::new();
72
73        Self {
74            file_version,
75            remembered_strings,
76            remembered_types,
77            remembered_objects,
78            objects,
79            reader,
80        }
81    }
82
83    fn do_read(&mut self) -> HavokRootObject {
84        let signature1 = self.reader.read_bytes(4).to_int_le::<u32>();
85        let signature2 = self.reader.read_bytes(4).to_int_le::<u32>();
86        if signature1 != 0xCAB0_0D1E || signature2 != 0xD011_FACE {
87            panic!()
88        }
89
90        loop {
91            let tag_type = HavokTagType::from_raw(self.read_packed_int() as u8);
92            match tag_type {
93                HavokTagType::FileInfo => {
94                    self.file_version = self.read_packed_int() as u8;
95                    assert_eq!(self.file_version, 3, "Unimplemented version");
96                    self.remembered_objects
97                        .push(Arc::new(RefCell::new(HavokObject::new(
98                            self.remembered_types[0].clone(),
99                            HashMap::new(),
100                        ))))
101                }
102                HavokTagType::Type => {
103                    let object_type = self.read_type();
104                    self.remembered_types.push(Arc::new(object_type));
105                }
106                HavokTagType::Backref => panic!(),
107                HavokTagType::ObjectRemember => {
108                    let object = Arc::new(RefCell::new(self.read_object()));
109
110                    self.remembered_objects.push(object.clone());
111                    self.objects.push(object);
112                }
113                HavokTagType::FileEnd => {
114                    break;
115                }
116                _ => panic!(),
117            }
118        }
119
120        // fill object references
121        for object in &self.objects {
122            self.fill_object_reference(&mut object.borrow_mut());
123        }
124
125        HavokRootObject::new(self.remembered_objects[1].clone())
126    }
127
128    fn read_object(&mut self) -> HavokObject {
129        let object_type_index = self.read_packed_int();
130        let object_type = self.remembered_types[object_type_index as usize].clone();
131
132        let members = object_type.members();
133        let data_existence = self.read_bit_field(members.len());
134
135        let data = members
136            .into_iter()
137            .enumerate()
138            .map(|(index, member)| {
139                let value = if data_existence[index] {
140                    self.read_object_member_value(member)
141                } else {
142                    Self::default_value(member.type_)
143                };
144                (index, value)
145            })
146            .collect::<HashMap<_, _>>();
147
148        HavokObject::new(object_type.clone(), data)
149    }
150
151    fn read_object_member_value(&mut self, member: &HavokObjectTypeMember) -> HavokValue {
152        if member.type_.is_array() {
153            let array_len = self.read_packed_int();
154            if member.type_.base_type() == HavokValueType::OBJECT && member.class_name.is_none() {
155                panic!()
156            }
157
158            HavokValue::Array(self.read_array(member, array_len as usize))
159        } else {
160            match member.type_ {
161                HavokValueType::BYTE => HavokValue::Integer(self.reader.read() as i32),
162                HavokValueType::INT => HavokValue::Integer(self.read_packed_int()),
163                HavokValueType::REAL => HavokValue::Real(self.reader.read_f32_le()),
164                HavokValueType::STRING => HavokValue::String(self.read_string()),
165                HavokValueType::OBJECT => {
166                    HavokValue::ObjectReference(self.read_packed_int() as usize)
167                }
168                _ => panic!("unimplemented {}", member.type_.bits()),
169            }
170        }
171    }
172
173    fn read_array(&mut self, member: &HavokObjectTypeMember, array_len: usize) -> Vec<HavokValue> {
174        let base_type = member.type_.base_type();
175        match base_type {
176            HavokValueType::STRING => (0..array_len)
177                .map(|_| HavokValue::String(self.read_string()))
178                .collect::<Vec<_>>(),
179            HavokValueType::STRUCT => {
180                let target_type = self.find_type(member.class_name.as_ref().unwrap());
181                let data_existence = self.read_bit_field(target_type.member_count());
182
183                let mut result_objects = Vec::new();
184                for _ in 0..array_len {
185                    let object = Arc::new(RefCell::new(HavokObject::new(
186                        target_type.clone(),
187                        HashMap::new(),
188                    )));
189
190                    result_objects.push(object.clone());
191                    self.objects.push(object);
192                }
193
194                // struct of array
195                for (member_index, member) in target_type.members().into_iter().enumerate() {
196                    if data_existence[member_index] {
197                        if member.type_.is_tuple() {
198                            panic!()
199                        } else {
200                            let data = self.read_array(member, array_len);
201                            for (index, item) in data.into_iter().enumerate() {
202                                result_objects[index].borrow_mut().set(member_index, item);
203                            }
204                        }
205                    }
206                }
207
208                result_objects
209                    .into_iter()
210                    .map(HavokValue::Object)
211                    .collect::<Vec<_>>()
212            }
213            HavokValueType::OBJECT => (0..array_len)
214                .map(|_| {
215                    let object_index = self.read_packed_int();
216
217                    HavokValue::ObjectReference(object_index as usize)
218                })
219                .collect::<Vec<_>>(),
220            HavokValueType::BYTE => (0..array_len)
221                .map(|_| HavokValue::Integer(self.reader.read() as HavokInteger))
222                .collect::<Vec<_>>(),
223            HavokValueType::INT => {
224                if self.file_version >= 3 {
225                    self.read_packed_int(); // type?
226                }
227                (0..array_len)
228                    .map(|_| HavokValue::Integer(self.read_packed_int()))
229                    .collect::<Vec<_>>()
230            }
231            HavokValueType::REAL => (0..array_len)
232                .map(|_| HavokValue::Real(self.reader.read_f32_le()))
233                .collect::<Vec<_>>(),
234            HavokValueType::VEC4
235            | HavokValueType::VEC8
236            | HavokValueType::VEC12
237            | HavokValueType::VEC16 => {
238                let vec_size = member.type_.base_type().vec_size() as usize;
239                (0..array_len)
240                    .map(|_| {
241                        HavokValue::Vec(
242                            (0..vec_size)
243                                .map(|_| self.reader.read_f32_le())
244                                .collect::<Vec<_>>(),
245                        )
246                    })
247                    .collect::<Vec<_>>()
248            }
249            _ => panic!(
250                "unimplemented {} {}",
251                member.type_.bits(),
252                member.type_.base_type().bits()
253            ),
254        }
255    }
256
257    fn read_type(&mut self) -> HavokObjectType {
258        let name = self.read_string();
259        let _version = self.read_packed_int();
260        let parent = self.read_packed_int();
261        let member_count = self.read_packed_int();
262
263        let parent = self.remembered_types[parent as usize].clone();
264        let members = (0..member_count)
265            .map(|_| {
266                let member_name = self.read_string();
267                let type_ = HavokValueType::from_bits(self.read_packed_int() as u32).unwrap();
268
269                let tuple_size = if type_.is_tuple() {
270                    self.read_packed_int()
271                } else {
272                    0
273                };
274                let type_name = if type_.base_type() == HavokValueType::OBJECT
275                    || type_.base_type() == HavokValueType::STRUCT
276                {
277                    Some(self.read_string())
278                } else {
279                    None
280                };
281
282                HavokObjectTypeMember::new(member_name, type_, tuple_size as u32, type_name)
283            })
284            .collect::<Vec<_>>();
285
286        HavokObjectType::new(name, Some(parent), members)
287    }
288
289    fn read_string(&mut self) -> Arc<str> {
290        let length = self.read_packed_int();
291        if length < 0 {
292            return self.remembered_strings[-length as usize].clone();
293        }
294
295        let result = Arc::from(
296            std::str::from_utf8(self.reader.read_bytes(length as usize))
297                .unwrap()
298                .to_owned(),
299        );
300        self.remembered_strings.push(Arc::clone(&result));
301
302        result
303    }
304
305    fn read_bit_field(&mut self, count: usize) -> Vec<bool> {
306        let bytes_to_read = ((count + 7) & 0xffff_fff8) / 8;
307        let bytes = self.reader.read_bytes(bytes_to_read);
308
309        let mut result = Vec::with_capacity(count);
310        for byte in bytes {
311            let mut byte = *byte;
312            for _ in 0..8 {
313                result.push((byte & 1) == 1);
314                byte >>= 1;
315
316                if result.len() == count {
317                    break;
318                }
319            }
320        }
321
322        result
323    }
324
325    fn read_packed_int(&mut self) -> HavokInteger {
326        let mut byte = self.reader.read();
327
328        let mut result = ((byte & 0x7f) >> 1) as u32;
329        let neg = byte & 1;
330
331        let mut shift = 6;
332        while byte & 0x80 != 0 {
333            byte = self.reader.read();
334
335            result |= ((byte as u32) & 0xffff_ff7f) << shift;
336            shift += 7;
337        }
338        if neg == 1 {
339            -(result as HavokInteger)
340        } else {
341            result as HavokInteger
342        }
343    }
344
345    fn find_type(&self, type_name: &str) -> Arc<HavokObjectType> {
346        self.remembered_types
347            .iter()
348            .find(|&x| &*x.name == type_name)
349            .unwrap()
350            .clone()
351    }
352
353    fn fill_object_reference(&self, object: &mut HavokObject) {
354        let mut values_to_update = Vec::new();
355        for (index, mut value) in object.members_mut() {
356            match &mut value {
357                HavokValue::ObjectReference(x) => {
358                    let object_ref = &self.remembered_objects[*x];
359                    values_to_update.push((*index, HavokValue::Object(object_ref.clone())));
360                }
361                HavokValue::Array(x) => {
362                    x.iter_mut().for_each(|item| {
363                        if let HavokValue::ObjectReference(x) = item {
364                            let object_ref = &self.remembered_objects[*x];
365
366                            *item = HavokValue::Object(object_ref.clone())
367                        }
368                    });
369                }
370                _ => {}
371            }
372        }
373
374        for (index, value) in values_to_update {
375            object.set(index, value);
376        }
377    }
378
379    fn default_value(type_: HavokValueType) -> HavokValue {
380        if type_.is_vec() {
381            HavokValue::Array(
382                (0..type_.vec_size())
383                    .map(|_| Self::default_value(type_.base_type()))
384                    .collect::<Vec<_>>(),
385            )
386        } else if type_.is_array() || type_.is_tuple() {
387            HavokValue::Array(Vec::new())
388        } else {
389            match type_ {
390                HavokValueType::EMPTY => HavokValue::Integer(HavokInteger::default()),
391                HavokValueType::BYTE => HavokValue::Integer(HavokInteger::default()),
392                HavokValueType::INT => HavokValue::Integer(HavokInteger::default()),
393                HavokValueType::OBJECT => HavokValue::ObjectReference(0),
394                _ => panic!("unimplemented {}", type_.bits()),
395            }
396        }
397    }
398}