dem/netmsg_doer/
delta_description.rs

1use std::str::from_utf8;
2
3use crate::types::{Delta, DeltaDecoder, DeltaDecoderS};
4
5use super::*;
6
7impl Doer for SvcDeltaDescription {
8    fn id(&self) -> u8 {
9        14
10    }
11
12    fn parse(i: &[u8], aux: AuxRefCell) -> Result<Self> {
13        let (i, name) = null_string(i)?;
14        let (i, total_fields) = le_u16(i)?;
15
16        let clone = i;
17
18        let mut aux = aux.borrow_mut();
19
20        // Delta description is usually in LOADING section and first frame message.
21        // It will detail the deltas being used and its index for correct decoding.
22        // So this would be the only message that modifies the delta decode table.
23
24        let mut br = BitReader::new(i);
25        let data: Vec<Delta> = (0..total_fields)
26            .map(|_| {
27                parse_delta(
28                    aux.delta_decoders.get("delta_description_t\0").unwrap(),
29                    &mut br,
30                )
31            })
32            .collect();
33
34        let decoder: DeltaDecoder = data
35            .iter()
36            .map(|entry| {
37                DeltaDecoderS {
38                    name: entry.get("name").unwrap().to_owned(),
39                    bits: u32::from_le_bytes(
40                        entry.get("bits").unwrap().as_slice().try_into().unwrap(),
41                    ), // heh
42                    divisor: f32::from_le_bytes(
43                        entry.get("divisor").unwrap().as_slice().try_into().unwrap(),
44                    ),
45                    flags: u32::from_le_bytes(
46                        entry.get("flags").unwrap().as_slice().try_into().unwrap(),
47                    ),
48                }
49            })
50            .collect();
51
52        let range = br.get_consumed_bytes();
53        let clone = &clone[..range];
54        let (i, _) = take(range)(i)?;
55
56        // mutate delta_decoders
57        aux.delta_decoders
58            .insert(from_utf8(name).unwrap().to_owned(), decoder.clone());
59
60        Ok((
61            i,
62            Self {
63                name: name.to_vec(),
64                total_fields,
65                fields: decoder,
66                clone: clone.to_vec(),
67            },
68        ))
69    }
70
71    fn write(&self, _: AuxRefCell) -> ByteVec {
72        let mut writer = ByteWriter::new();
73
74        writer.append_u8(self.id());
75
76        writer.append_u8_slice(&self.name);
77        writer.append_u16(self.total_fields);
78
79        // This is intentionally done like this because I don't think anyone
80        // would try to modify delta description.
81        writer.append_u8_slice(&self.clone);
82
83        writer.data
84    }
85}