wgtk/pxml/
de.rs

1//! Deserialization module for Packed XML.
2
3use 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
14/// Read a packed XML data from an readable and seekable object.
15/// 
16/// *The content will be read starting from the inital position
17/// of the reader.*
18pub fn from_reader<R: Read + Seek>(mut reader: R) -> Result<Box<Element>, DeError> {
19
20    // Validate file's magic
21    if !reader.check_exact(MAGIC)? {
22        return Err(DeError::InvalidMagic);
23    }
24
25    // Unknown byte
26    reader.skip::<1>()?;
27
28    // Parsing
29    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/// Read a packed XML from raw bytes.
38#[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
45/// Internal function to read dictionary.
46fn 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
58/// Internal function to read a data descriptor.
59fn 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
70/// Internal function to read a child descriptor (data + name).
71fn 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
79/// Internal function that reads the current's element descriptor
80/// and its children.
81fn 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
106/// Internal function to read a value.
107fn 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
133/// Internal function to read a string of specific length.
134fn 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
143/// Internal function that reads a compressed string.
144fn 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
150/// Internal function to read a data from its descriptor and a reader.
151fn 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
163/// Internal function to read a boolean data.
164fn 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
173/// Internal function to read a 
174fn 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
191/// Internal data descriptor.
192struct DataDescriptor {
193    /// Type of data.
194    ty: DataType,
195    /// Offset of the end of the data, this can be used to
196    /// compute data length if start address is known.
197    end_offset: u32,
198}
199
200
201/// Internal descriptor for children elements of an element.
202struct ChildDescriptor {
203    /// Data descriptor for this child.
204    data: DataDescriptor,
205    /// Name index in the dictionary.
206    name_index: usize
207}
208
209
210/// Deserialization error that can happen while deserializing
211#[derive(Debug, Error)]
212pub enum DeError {
213    /// Invalid magic signature for the file.
214    #[error("invalid magic")]
215    InvalidMagic,
216    /// Invalid data type while parsing.
217    #[error("invalid data type id {0}")]
218    InvalidDataType(u32),
219    /// Invalid data size for a number.
220    #[error("invalid data length of {0} bytes for a number")]
221    InvalidIntegerLen(usize),
222    /// Invalid data size for a boolean.
223    #[error("invalid data length of {0} bytes for a boolean")]
224    InvalidBoolLen(usize),
225    /// Invalid vector length, not a multiple a 4 bytes (f32).
226    #[error("invalid data length of {0} bytes for a vector")]
227    InvalidVectorLen(usize),
228    /// IO error while unpacking.
229    #[error("io error: {0}")]
230    Io(#[from] io::Error),
231}