blackbox_log/parser/decode/
tagged_variable.rs

1use crate::parser::{InternalError, InternalResult};
2use crate::Reader;
3
4pub(crate) fn tagged_variable(data: &mut Reader, extra: usize) -> InternalResult<[i32; 8]> {
5    debug_assert!(extra < 8);
6
7    let mut values = [0; 8];
8
9    if extra == 0 {
10        values[0] = super::variable_signed(data)?;
11    } else {
12        let mut header = data.read_u8().ok_or(InternalError::Eof)?;
13
14        for value in values.iter_mut().take(extra + 1) {
15            *value = if (header & 1) == 1 {
16                super::variable_signed(data)?
17            } else {
18                0
19            };
20
21            header >>= 1;
22        }
23
24        if header != 0 {
25            return Err(InternalError::Retry);
26        }
27    }
28
29    Ok(values)
30}
31
32#[cfg(test)]
33mod tests {
34    use super::*;
35
36    #[test]
37    fn one_value() {
38        let mut b = Reader::new(&[2]);
39
40        let expected = [1, 0, 0, 0, 0, 0, 0, 0];
41        assert_eq!(expected, tagged_variable(&mut b, 0).unwrap());
42        assert!(b.is_empty());
43    }
44
45    #[test]
46    fn simple_two_values() {
47        let b = [0b0000_0011, 2, 2];
48        let mut b = Reader::new(&b);
49
50        let expected = [1, 1, 0, 0, 0, 0, 0, 0];
51        assert_eq!(expected, tagged_variable(&mut b, 1).unwrap());
52        assert!(b.is_empty());
53    }
54
55    #[test]
56    fn fewer_in_tag_than_expected() {
57        let b = [0b0000_0010, 2];
58        let mut b = Reader::new(&b);
59
60        let expected = [0, 1, 0, 0, 0, 0, 0, 0];
61        assert_eq!(expected, tagged_variable(&mut b, 1).unwrap());
62        assert!(b.is_empty());
63    }
64
65    #[test]
66    #[should_panic(expected = "Eof")]
67    fn multiple_expected_but_empty() {
68        let mut b = Reader::new(&[]);
69
70        tagged_variable(&mut b, 1).unwrap();
71    }
72
73    #[test]
74    #[should_panic(expected = "Retry")]
75    fn more_in_tag_than_expected() {
76        let b = [0b0000_0111, 2, 2, 2];
77        let mut b = Reader::new(&b);
78
79        tagged_variable(&mut b, 1).unwrap();
80    }
81}