diff options
Diffstat (limited to 'src/object.rs')
-rw-r--r-- | src/object.rs | 87 |
1 files changed, 85 insertions, 2 deletions
diff --git a/src/object.rs b/src/object.rs index 9875517..5ad1441 100644 --- a/src/object.rs +++ b/src/object.rs @@ -1,4 +1,87 @@ +use crate::helper::{AlignExt, Endianness, ReadExt}; use crate::serialized_file::TypeTreeNode; -use std::io::Read; +use anyhow::Result; +use log::debug; +use std::io::Seek; +use std::{collections::BTreeMap, io::Read}; -pub fn read_value(ty: TypeTreeNode, data: &mut impl Read) {} +#[derive(Debug)] +pub enum Value { + Bool(bool), + U8(u8), + U16(u16), + U32(u32), + I32(i32), + F32(f32), + I64(i64), + F64(f64), + Array(Vec<Value>), + Object { + class: String, + fields: BTreeMap<String, Value>, + }, + String(String), +} + +pub fn read_value( + ty: &TypeTreeNode, + e: Endianness, + data: &mut (impl Read + Seek), +) -> Result<Value> { + match ty.type_string.as_str() { + "char" => Ok(Value::U8(data.read_u8()?)), + "int" => Ok(Value::I32(data.read_i32(e)?)), + "unsigned int" => Ok(Value::U32(data.read_u32(e)?)), + "UInt16" => Ok(Value::U16(data.read_u16(e)?)), + "SInt64" => Ok(Value::I64(data.read_i64(e)?)), + "bool" => Ok(Value::Bool(data.read_u8()? != 0)), + "float" => { + data.align(4)?; + Ok(Value::F32(data.read_f32(e)?)) + } + "double" => { + data.align(4)?; + Ok(Value::F64(data.read_f64(e)?)) + } + "string" => { + let Value::Array(arr) = read_value(&ty.children[0], e, data)? else { + unreachable!() + }; + let bytes = arr + .into_iter() + .map(|e| { + if let Value::U8(x) = e { + x + } else { + unreachable!() + } + }) + .collect::<Vec<_>>(); + Ok(Value::String(String::from_utf8(bytes)?)) + } + "Array" => { + let Value::I32(size) = read_value(&ty.children[0], e, data)? else { + unreachable!() + }; + debug!("array of size {size}"); + let mut elems = Vec::new(); + for _ in 0..size { + elems.push(read_value(&ty.children[1], e, data)?); + } + Ok(Value::Array(elems)) + } + _ => { + if ty.children.is_empty() && ty.byte_size != -1 { + todo!("need type {:?}", ty.type_string); + } + let mut fields = BTreeMap::new(); + for c in &ty.children { + fields.insert(c.name_string.clone(), read_value(&c, e, data)?); + } + Ok(Value::Object { + fields, + class: ty.type_string.clone(), + }) + } + } +} |