aboutsummaryrefslogtreecommitdiff
path: root/src/object.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/object.rs')
-rw-r--r--src/object.rs21
1 files changed, 18 insertions, 3 deletions
diff --git a/src/object.rs b/src/object.rs
index ab27ea4..bdaf3ec 100644
--- a/src/object.rs
+++ b/src/object.rs
@@ -1,6 +1,6 @@
use crate::helper::{AlignExt, Endianness, ReadExt};
use crate::serialized_file::TypeTreeNode;
-use anyhow::Result;
+use anyhow::{Result, bail};
use log::trace;
use std::io::Seek;
use std::{collections::BTreeMap, io::Read};
@@ -29,6 +29,8 @@ pub fn read_value(
e: Endianness,
data: &mut (impl Read + Seek),
) -> Result<Value> {
+ let mut align = false;
+ let pos_before = data.stream_position()?;
let r = match ty.type_string.as_str() {
"char" => Ok(Value::U8(data.read_u8()?)),
"int" => Ok(Value::I32(data.read_i32(e)?)),
@@ -63,10 +65,14 @@ pub fn read_value(
Ok(Value::String(String::from_utf8(bytes)?))
}
"Array" => {
+ align |= ty.children[0].post_align();
let Value::I32(size) = read_value(&ty.children[0], e, data)? else {
unreachable!()
};
trace!("array of size {size}");
+ if size > 10000 {
+ eprintln!("{ty:#?}");
+ }
let mut elems = Vec::new();
for _ in 0..size {
elems.push(read_value(&ty.children[1], e, data)?);
@@ -87,7 +93,16 @@ pub fn read_value(
})
}
};
- if ty.post_align() {
+ let pos_after = data.stream_position()?;
+ if ty.byte_size != -1 && pos_after - pos_before < ty.byte_size as u64 {
+ bail!(
+ "did not read enough data ({} expected, {} actual)",
+ ty.byte_size,
+ pos_after - pos_before
+ );
+ }
+ if align || ty.post_align() {
+ trace!("post align");
data.align(4)?;
}
r
@@ -116,7 +131,7 @@ impl Value {
.into_iter()
.map(|(k, v)| (k, v.to_json()))
.chain(Some((
- "_class".to_string(),
+ "@class".to_string(),
serde_json::Value::String(class),
)))
.collect(),