1use std::io::{self, Read, Seek, Cursor};
4
5use glam::{Affine3A, Vec3A};
6use smallvec::SmallVec;
7use thiserror::Error;
8
9use crate::util::io::WgReadExt;
10
11use super::{MAGIC, Element, Value, DataType};
12
13
14pub fn from_reader<R: Read + Seek>(mut reader: R) -> Result<Box<Element>, DeError> {
19
20 if !reader.check_exact(MAGIC)? {
22 return Err(DeError::InvalidMagic);
23 }
24
25 reader.skip::<1>()?;
27
28 let dict = read_dictionary(&mut reader)?;
30 let mut element = Box::new(Element::new());
31 read_element(&mut reader, &mut *element, &dict[..])?;
32 Ok(element)
33
34}
35
36
37#[inline]
39pub fn from_bytes<B: AsRef<[u8]>>(data: B) -> Result<Box<Element>, DeError> {
40 let data = data.as_ref();
41 from_reader(Cursor::new(data))
42}
43
44
45fn read_dictionary<R: Read + Seek>(reader: &mut R) -> Result<Vec<String>, DeError> {
47 let mut dict = Vec::new();
48 loop {
49 let string = reader.read_cstring_variable()?;
50 if string.is_empty() {
51 return Ok(dict)
52 }
53 dict.push(string);
54 }
55}
56
57
58fn read_data_descriptor<R: Read>(reader: &mut R) -> Result<DataDescriptor, DeError> {
60 let data_descriptor = reader.read_u32()?;
61 let raw_data_type = data_descriptor >> 28;
62 Ok(DataDescriptor {
63 ty: DataType::from_raw(raw_data_type)
64 .ok_or(DeError::InvalidDataType(raw_data_type))?,
65 end_offset: data_descriptor & 0x00FFFFFFF,
66 })
67}
68
69
70fn read_child_descriptor<R: Read>(reader: &mut R) -> Result<ChildDescriptor, DeError> {
72 Ok(ChildDescriptor {
73 name_index: reader.read_u16()? as usize,
74 data: read_data_descriptor(&mut *reader)?,
75 })
76}
77
78
79fn read_element<R: Read>(reader: &mut R, element: &mut Element, dict: &[String]) -> Result<(), DeError> {
82
83 let children_count = reader.read_u16()? as usize;
84 let self_descriptor = read_data_descriptor(&mut *reader)?;
85 let mut children_descriptors = SmallVec::<[ChildDescriptor; 16]>::new();
86
87 for _ in 0..children_count {
88 children_descriptors.push(read_child_descriptor(&mut *reader)?);
89 }
90
91 read_data(&mut *reader, &mut element.value, &self_descriptor, dict, 0)?;
92 let mut offset = self_descriptor.end_offset;
93
94 for child in children_descriptors {
95 let mut value = Value::Boolean(false);
96 read_data(&mut *reader, &mut value, &child.data, dict, offset)?;
97 offset = child.data.end_offset;
98 element.add_children(&dict[child.name_index], value);
99 }
100
101 Ok(())
102
103}
104
105
106fn read_data<R: Read>(reader: &mut R, value: &mut Value, desc: &DataDescriptor, dict: &[String], offset: u32) -> Result<(), DeError> {
108 let len = (desc.end_offset - offset) as usize;
109 match desc.ty {
110 DataType::Element => {
111 let mut element = Box::new(Element::new());
112 read_element(reader, &mut *element, dict)?;
113 *value = Value::Element(element);
114 },
115 DataType::String => *value = Value::String(read_string(reader, len)?),
116 DataType::Integer => *value = Value::Integer(read_integer(reader, len)?),
117 DataType::Boolean => *value = Value::Boolean(read_bool(reader, len)?),
118 DataType::CompressedString => *value = Value::String(read_compressed_string(reader, len)?),
119 DataType::Float => {
120 let floats = read_vector(reader, len)?;
121 match floats.len() {
122 12 => *value = Value::Affine3(Affine3A::from_cols_slice(&floats[..12])),
123 3 => *value = Value::Vec3(Vec3A::from_slice(&floats[..3])),
124 1 => *value = Value::Float(floats[0]),
125 len => return Err(DeError::InvalidVectorLen(len))
126 }
127 }
128 }
129 Ok(())
130}
131
132
133fn read_string<R: Read>(reader: &mut R, len: usize) -> Result<String, DeError> {
135 if len == 0 {
136 Ok("".to_string())
137 } else {
138 reader.read_string(len as usize).map_err(Into::into)
139 }
140}
141
142
143fn read_compressed_string<R: Read>(reader: &mut R, len: usize) -> Result<String, DeError> {
145 let data = reader.read_blob(len)?;
146 Ok(base64::encode(&data[..]))
147}
148
149
150fn read_integer<R: Read>(reader: &mut R, len: usize) -> Result<i64, DeError> {
152 match len {
153 0 => Ok(0),
154 1 => Ok(reader.read_i8()? as i64),
155 2 => Ok(reader.read_i16()? as i64),
156 4 => Ok(reader.read_i32()? as i64),
157 8 => Ok(reader.read_i64()?),
158 _ => Err(DeError::InvalidIntegerLen(len))
159 }
160}
161
162
163fn read_bool<R: Read>(reader: &mut R, len: usize) -> Result<bool, DeError> {
165 match len {
166 0 => Ok(false),
167 1 => Ok(reader.read_u8()? == 1),
168 _ => Err(DeError::InvalidBoolLen(len))
169 }
170}
171
172
173fn read_vector<R: Read>(reader: &mut R, len: usize) -> Result<SmallVec<[f32; 12]>, DeError> {
175
176 if len % 4 != 0 {
177 return Err(DeError::InvalidVectorLen(len))
178 }
179
180 let n = len / 4;
181 let mut res = SmallVec::new();
182 for _ in 0..n {
183 res.push(reader.read_f32()?);
184 }
185
186 Ok(res)
187
188}
189
190
191struct DataDescriptor {
193 ty: DataType,
195 end_offset: u32,
198}
199
200
201struct ChildDescriptor {
203 data: DataDescriptor,
205 name_index: usize
207}
208
209
210#[derive(Debug, Error)]
212pub enum DeError {
213 #[error("invalid magic")]
215 InvalidMagic,
216 #[error("invalid data type id {0}")]
218 InvalidDataType(u32),
219 #[error("invalid data length of {0} bytes for a number")]
221 InvalidIntegerLen(usize),
222 #[error("invalid data length of {0} bytes for a boolean")]
224 InvalidBoolLen(usize),
225 #[error("invalid data length of {0} bytes for a vector")]
227 InvalidVectorLen(usize),
228 #[error("io error: {0}")]
230 Io(#[from] io::Error),
231}