weakauras_codec_lib_serialize/deserialization/
mod.rs1mod reader;
8
9use crate::{
10 EmbeddedTypeTag, FORMAT_VERSION, TypeTag, error::DeserializationError, macros::check_recursion,
11};
12use reader::SliceReader;
13use weakauras_codec_lua_value::{LuaMapKey, LuaValue, Map};
14
15pub struct Deserializer<'s> {
33 remaining_depth: usize,
34 reader: SliceReader<'s>,
35
36 table_refs: Vec<LuaValue>,
37 string_refs: Vec<String>,
38}
39
40impl<'s> Deserializer<'s> {
41 pub fn from_slice(slice: &'s [u8]) -> Self {
43 Self {
44 remaining_depth: 128,
45 reader: SliceReader::new(slice),
46
47 table_refs: Vec::new(),
48 string_refs: Vec::new(),
49 }
50 }
51
52 pub fn deserialize_all(mut self) -> Result<Vec<LuaValue>, DeserializationError> {
54 match self.reader.read_u8() {
55 Some(val) if val == FORMAT_VERSION || val == FORMAT_VERSION + 1 => {}
56 _ => return Err(DeserializationError::InvalidPrefix),
57 }
58
59 let mut result = Vec::new();
60
61 while let Some(v) = self.deserialize_helper()? {
62 result.push(v);
63 }
64
65 Ok(result)
66 }
67
68 pub fn deserialize_first(mut self) -> Result<Option<LuaValue>, DeserializationError> {
70 match self.reader.read_u8() {
71 Some(val) if val == FORMAT_VERSION || val == FORMAT_VERSION + 1 => {}
72 _ => return Err(DeserializationError::InvalidPrefix),
73 }
74
75 self.deserialize_helper()
76 }
77
78 fn deserialize_helper(&mut self) -> Result<Option<LuaValue>, DeserializationError> {
79 match self.reader.read_u8() {
80 None => Ok(None),
81 Some(value) => {
82 if value & 1 == 1 {
83 Ok(Some(LuaValue::Number((value >> 1) as f64)))
85 } else if value & 3 == 2 {
86 let tag = EmbeddedTypeTag::from_u8((value & 0x0F) >> 2)
89 .ok_or(DeserializationError::InvalidEmbeddedTag)?;
90 let len = value >> 4;
91
92 self.deserialize_embedded(tag, len).map(Option::Some)
93 } else if value & 7 == 4 {
94 let next_byte = self
97 .reader
98 .read_u8()
99 .ok_or(DeserializationError::UnexpectedEof)?
100 as u16;
101 let packed = (next_byte << 8) + value as u16;
102
103 Ok(Some(LuaValue::Number(if value & 15 == 12 {
104 -((packed >> 4) as f64)
105 } else {
106 (packed >> 4) as f64
107 })))
108 } else {
109 let tag =
112 TypeTag::from_u8(value >> 3).ok_or(DeserializationError::InvalidTag)?;
113
114 self.deserialize_one(tag).map(Option::Some)
115 }
116 }
117 }
118 }
119
120 #[inline(always)]
121 fn extract_value(&mut self) -> Result<LuaValue, DeserializationError> {
122 match self.deserialize_helper() {
123 Ok(Some(value)) => Ok(value),
124 Ok(None) => Err(DeserializationError::UnexpectedEof),
125 Err(e) => Err(e),
126 }
127 }
128
129 fn deserialize_embedded(
130 &mut self,
131 tag: EmbeddedTypeTag,
132 len: u8,
133 ) -> Result<LuaValue, DeserializationError> {
134 match tag {
135 EmbeddedTypeTag::Str => self.deserialize_string(len as usize),
136 EmbeddedTypeTag::Map => self.deserialize_map(len as usize),
137 EmbeddedTypeTag::Array => self.deserialize_array(len as usize),
138 EmbeddedTypeTag::Mixed => {
140 self.deserialize_mixed(((len & 3) + 1) as usize, ((len >> 2) + 1) as usize)
141 }
142 }
143 }
144
145 fn deserialize_one(&mut self, tag: TypeTag) -> Result<LuaValue, DeserializationError> {
146 match tag {
147 TypeTag::Null => Ok(LuaValue::Null),
148
149 TypeTag::Int16Pos => self.deserialize_int(2).map(|v| LuaValue::Number(v as f64)),
150 TypeTag::Int16Neg => self
151 .deserialize_int(2)
152 .map(|v| LuaValue::Number(-(v as f64))),
153 TypeTag::Int24Pos => self.deserialize_int(3).map(|v| LuaValue::Number(v as f64)),
154 TypeTag::Int24Neg => self
155 .deserialize_int(3)
156 .map(|v| LuaValue::Number(-(v as f64))),
157 TypeTag::Int32Pos => self.deserialize_int(4).map(|v| LuaValue::Number(v as f64)),
158 TypeTag::Int32Neg => self
159 .deserialize_int(4)
160 .map(|v| LuaValue::Number(-(v as f64))),
161 TypeTag::Int64Pos => self.deserialize_int(7).map(|v| LuaValue::Number(v as f64)),
162 TypeTag::Int64Neg => self
163 .deserialize_int(7)
164 .map(|v| LuaValue::Number(-(v as f64))),
165
166 TypeTag::Float => self.deserialize_f64().map(LuaValue::Number),
167 TypeTag::FloatStrPos => self.deserialize_f64_from_str().map(LuaValue::Number),
168 TypeTag::FloatStrNeg => self
169 .deserialize_f64_from_str()
170 .map(|v| LuaValue::Number(-v)),
171
172 TypeTag::True => Ok(LuaValue::Boolean(true)),
173 TypeTag::False => Ok(LuaValue::Boolean(false)),
174
175 TypeTag::Str8 => {
176 let len = self
177 .reader
178 .read_u8()
179 .ok_or(DeserializationError::UnexpectedEof)?;
180 self.deserialize_string(len as usize)
181 }
182 TypeTag::Str16 => {
183 let len = self.deserialize_int(2)?;
184 self.deserialize_string(len as usize)
185 }
186 TypeTag::Str24 => {
187 let len = self.deserialize_int(3)?;
188 self.deserialize_string(len as usize)
189 }
190
191 TypeTag::Map8 => {
192 let len = self
193 .reader
194 .read_u8()
195 .ok_or(DeserializationError::UnexpectedEof)?;
196 self.deserialize_map(len as usize)
197 }
198 TypeTag::Map16 => {
199 let len = self.deserialize_int(2)?;
200 self.deserialize_map(len as usize)
201 }
202 TypeTag::Map24 => {
203 let len = self.deserialize_int(3)?;
204 self.deserialize_map(len as usize)
205 }
206
207 TypeTag::Array8 => {
208 let len = self
209 .reader
210 .read_u8()
211 .ok_or(DeserializationError::UnexpectedEof)?;
212 self.deserialize_array(len as usize)
213 }
214 TypeTag::Array16 => {
215 let len = self.deserialize_int(2)?;
216 self.deserialize_array(len as usize)
217 }
218 TypeTag::Array24 => {
219 let len = self.deserialize_int(3)?;
220 self.deserialize_array(len as usize)
221 }
222
223 TypeTag::Mixed8 => {
224 let array_len = self
225 .reader
226 .read_u8()
227 .ok_or(DeserializationError::UnexpectedEof)?;
228 let map_len = self
229 .reader
230 .read_u8()
231 .ok_or(DeserializationError::UnexpectedEof)?;
232
233 self.deserialize_mixed(array_len as usize, map_len as usize)
234 }
235 TypeTag::Mixed16 => {
236 let array_len = self.deserialize_int(2)?;
237 let map_len = self.deserialize_int(2)?;
238
239 self.deserialize_mixed(array_len as usize, map_len as usize)
240 }
241 TypeTag::Mixed24 => {
242 let array_len = self.deserialize_int(3)?;
243 let map_len = self.deserialize_int(3)?;
244
245 self.deserialize_mixed(array_len as usize, map_len as usize)
246 }
247
248 TypeTag::StrRef8 => {
249 let index = self
250 .reader
251 .read_u8()
252 .ok_or(DeserializationError::UnexpectedEof)?
253 .checked_sub(1)
254 .ok_or(DeserializationError::InvalidStringReference)?;
255 match self.string_refs.get(index as usize) {
256 None => Err(DeserializationError::InvalidStringReference),
257 Some(s) => Ok(LuaValue::String(s.clone())),
258 }
259 }
260 TypeTag::StrRef16 => {
261 let index = self
262 .deserialize_int(2)?
263 .checked_sub(1)
264 .ok_or(DeserializationError::InvalidStringReference)?;
265 match self.string_refs.get(index as usize) {
266 None => Err(DeserializationError::InvalidStringReference),
267 Some(s) => Ok(LuaValue::String(s.clone())),
268 }
269 }
270 TypeTag::StrRef24 => {
271 let index = self
272 .deserialize_int(3)?
273 .checked_sub(1)
274 .ok_or(DeserializationError::InvalidStringReference)?;
275 match self.string_refs.get(index as usize) {
276 None => Err(DeserializationError::InvalidStringReference),
277 Some(s) => Ok(LuaValue::String(s.clone())),
278 }
279 }
280
281 TypeTag::MapRef8 => {
282 let index = self
283 .reader
284 .read_u8()
285 .ok_or(DeserializationError::UnexpectedEof)?
286 .checked_sub(1)
287 .ok_or(DeserializationError::InvalidMapReference)?;
288 match self.table_refs.get(index as usize) {
289 None => Err(DeserializationError::InvalidMapReference),
290 Some(v) => Ok(v.clone()),
291 }
292 }
293 TypeTag::MapRef16 => {
294 let index = self
295 .deserialize_int(2)?
296 .checked_sub(1)
297 .ok_or(DeserializationError::InvalidMapReference)?;
298 match self.table_refs.get(index as usize) {
299 None => Err(DeserializationError::InvalidMapReference),
300 Some(v) => Ok(v.clone()),
301 }
302 }
303 TypeTag::MapRef24 => {
304 let index = self
305 .deserialize_int(3)?
306 .checked_sub(1)
307 .ok_or(DeserializationError::InvalidMapReference)?;
308 match self.table_refs.get(index as usize) {
309 None => Err(DeserializationError::InvalidMapReference),
310 Some(v) => Ok(v.clone()),
311 }
312 }
313 }
314 }
315
316 fn deserialize_string(&mut self, len: usize) -> Result<LuaValue, DeserializationError> {
317 match self.reader.read_string(len) {
318 None => Err(DeserializationError::UnexpectedEof),
319 Some(s) => {
320 let s = s.into_owned();
321 if len > 2 {
322 self.string_refs.push(s.clone());
323 }
324
325 Ok(LuaValue::String(s))
326 }
327 }
328 }
329
330 fn deserialize_f64(&mut self) -> Result<f64, DeserializationError> {
331 match self.reader.read_f64() {
332 None => Err(DeserializationError::UnexpectedEof),
333 Some(v) => Ok(v),
334 }
335 }
336
337 fn deserialize_f64_from_str(&mut self) -> Result<f64, DeserializationError> {
338 let len = self
339 .reader
340 .read_u8()
341 .ok_or(DeserializationError::UnexpectedEof)?;
342
343 match self.reader.read_bytes(len as usize) {
344 None => Err(DeserializationError::UnexpectedEof),
345 Some(bytes) => core::str::from_utf8(bytes)
346 .ok()
347 .and_then(|s| s.parse::<f64>().ok())
348 .ok_or(DeserializationError::InvalidFloatNumber),
349 }
350 }
351
352 fn deserialize_int(&mut self, bytes: usize) -> Result<u64, DeserializationError> {
353 match self.reader.read_int(bytes) {
354 None => Err(DeserializationError::UnexpectedEof),
355 Some(v) => Ok(v),
356 }
357 }
358
359 fn deserialize_map(&mut self, len: usize) -> Result<LuaValue, DeserializationError> {
360 let mut m = Map::new();
361
362 for _ in 0..len {
363 check_recursion!(self, DeserializationError, {
364 let (key, value) = (self.extract_value()?, self.extract_value()?);
365
366 m.insert(LuaMapKey::try_from(key)?, value);
367 });
368 }
369
370 let m = LuaValue::Map(m);
371 self.table_refs.push(m.clone());
372 Ok(m)
373 }
374
375 fn deserialize_array(&mut self, len: usize) -> Result<LuaValue, DeserializationError> {
376 let mut v = Vec::new();
377
378 for _ in 0..len {
379 check_recursion!(self, DeserializationError, {
380 v.push(self.extract_value()?);
381 });
382 }
383
384 let v = LuaValue::Array(v);
385 self.table_refs.push(v.clone());
386 Ok(v)
387 }
388
389 fn deserialize_mixed(
390 &mut self,
391 array_len: usize,
392 map_len: usize,
393 ) -> Result<LuaValue, DeserializationError> {
394 let mut m = Map::new();
395
396 for i in 1..=array_len {
397 check_recursion!(self, DeserializationError, {
398 let el = self.extract_value()?;
399 m.insert(LuaMapKey::try_from(LuaValue::Number(i as f64)).unwrap(), el);
400 });
401 }
402
403 for _ in 0..map_len {
404 check_recursion!(self, DeserializationError, {
405 let (key, value) = (self.extract_value()?, self.extract_value()?);
406
407 m.insert(LuaMapKey::try_from(key)?, value);
408 });
409 }
410
411 let m = LuaValue::Map(m);
412 self.table_refs.push(m.clone());
413 Ok(m)
414 }
415}