aboutsummaryrefslogtreecommitdiff
path: root/src/object.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/object.rs')
-rw-r--r--src/object.rs246
1 files changed, 0 insertions, 246 deletions
diff --git a/src/object.rs b/src/object.rs
deleted file mode 100644
index 92415e1..0000000
--- a/src/object.rs
+++ /dev/null
@@ -1,246 +0,0 @@
-use crate::helper::{AlignExt, Endianness, ReadExt};
-use crate::serialized_file::TypeTreeNode;
-use anyhow::{Result, bail};
-use log::trace;
-use serde::Serialize;
-use std::io::Seek;
-use std::{collections::BTreeMap, io::Read};
-
-#[derive(Debug, Clone, Serialize)]
-pub enum Value {
- Bool(bool),
- U8(u8),
- I8(i8),
- U16(u16),
- I16(i16),
- U32(u32),
- I32(i32),
- F32(f32),
- U64(u64),
- I64(i64),
- F64(f64),
- Array(Vec<Value>),
- Object {
- class: String,
- fields: BTreeMap<String, Value>,
- },
- Typeless(Vec<u8>),
- String(String),
-}
-
-pub fn read_value(
- ty: &TypeTreeNode,
- 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" => {
- assert_eq!(ty.byte_size, 1);
- Ok(Value::U8(data.read_u8()?))
- }
- "Type*" => Ok(Value::U32(data.read_u32(e)?)),
- "int" => Ok(Value::I32(data.read_i32(e)?)),
- "unsigned int" => Ok(Value::U32(data.read_u32(e)?)),
- "UInt8" => Ok(Value::U8(data.read_u8()?)),
- "UInt16" => Ok(Value::U16(data.read_u16(e)?)),
- "UInt32" => Ok(Value::U32(data.read_u32(e)?)),
- "UInt64" => Ok(Value::U64(data.read_u64(e)?)),
- "SInt8" => Ok(Value::I8(data.read_i8()?)),
- "SInt16" => Ok(Value::I16(data.read_i16(e)?)),
- "SInt32" => Ok(Value::I32(data.read_i32(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| match e {
- Value::U8(x) => x,
- _ => unreachable!(),
- })
- .collect::<Vec<_>>();
- Ok(Value::String(String::from_utf8(bytes)?))
- }
- "Array" => {
- align |= ty.children[0].post_align();
- assert_eq!(ty.byte_size, -1);
- let Value::I32(size) = read_value(&ty.children[0], e, data)? else {
- unreachable!()
- };
- trace!("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))
- }
- "TypelessData" => {
- let len = data.read_u32(e)?;
- let mut buf = vec![0u8; len as usize];
- data.read_exact(&mut buf)?;
- Ok(Value::Typeless(buf))
- }
- _ => {
- if ty.children.is_empty() && ty.byte_size != 0 {
- 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(),
- })
- }
- };
- 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
-}
-
-impl Value {
- pub fn class_name(&self) -> Option<&String> {
- if let Value::Object { class, .. } = self {
- Some(class)
- } else {
- None
- }
- }
- pub fn as_class(self, name: &str) -> Option<BTreeMap<String, Value>> {
- if let Value::Object { class, fields } = self {
- if class == name { Some(fields) } else { None }
- } else {
- None
- }
- }
- pub fn as_string(self) -> Option<String> {
- if let Value::String(s) = self {
- Some(s)
- } else {
- None
- }
- }
- pub fn as_i64(&self) -> Option<i64> {
- if let Value::I64(s) = self {
- Some(*s)
- } else {
- None
- }
- }
- pub fn as_i32(&self) -> Option<i32> {
- if let Value::I32(s) = self {
- Some(*s)
- } else {
- None
- }
- }
- pub fn as_u32(&self) -> Option<u32> {
- if let Value::U32(s) = self {
- Some(*s)
- } else {
- None
- }
- }
- pub fn as_u64(&self) -> Option<u64> {
- match self {
- Self::U64(x) => Some(*x),
- Self::U32(x) => Some(*x as u64),
- _ => None,
- }
- }
- pub fn as_f32(&self) -> Option<f32> {
- if let Value::F32(s) = self {
- Some(*s)
- } else {
- None
- }
- }
- pub fn as_u16(&self) -> Option<u16> {
- if let Value::U16(s) = self {
- Some(*s)
- } else {
- None
- }
- }
- pub fn as_bool(&self) -> Option<bool> {
- if let Value::Bool(s) = self {
- Some(*s)
- } else {
- None
- }
- }
- pub fn as_array(self) -> Option<Vec<Value>> {
- if let Value::Array(s) = self {
- Some(s)
- } else {
- None
- }
- }
- pub fn as_typeless(self) -> Option<Vec<u8>> {
- if let Value::Typeless(s) = self {
- Some(s)
- } else {
- None
- }
- }
- pub fn to_json(self) -> serde_json::Value {
- match self {
- Value::Bool(x) => serde_json::Value::Bool(x),
- Value::U8(x) => serde_json::Value::Number(x.into()),
- Value::I8(x) => serde_json::Value::Number(x.into()),
- Value::U16(x) => serde_json::Value::Number(x.into()),
- Value::I16(x) => serde_json::Value::Number(x.into()),
- Value::U32(x) => serde_json::Value::Number(x.into()),
- Value::U64(x) => serde_json::Value::Number(x.into()),
- Value::I32(x) => serde_json::Value::Number(x.into()),
- Value::F32(x) => serde_json::Value::Number(
- serde_json::Number::from_f64(x as f64).unwrap_or(0.into()),
- ),
- Value::I64(x) => serde_json::Value::Number(x.into()),
- Value::F64(x) => serde_json::Value::Number(serde_json::Number::from_f64(x).unwrap()),
- Value::String(x) => serde_json::Value::String(x),
- Value::Typeless(values) => serde_json::Value::Array(
- values
- .into_iter()
- .map(|e| serde_json::Value::Number(e.into()))
- .collect(),
- ),
- Value::Array(values) => {
- serde_json::Value::Array(values.into_iter().map(Value::to_json).collect())
- }
- Value::Object { class, fields } => serde_json::Value::Object(
- fields
- .into_iter()
- .map(|(k, v)| (k, v.to_json()))
- .chain(Some((
- "@class".to_string(),
- serde_json::Value::String(class),
- )))
- .collect(),
- ),
- }
- }
-}