blackbox_log/parser/decode/
tagged_32.rs

1use super::sign_extend;
2use crate::parser::{InternalError, InternalResult};
3use crate::Reader;
4
5const COUNT: usize = 3;
6
7pub(crate) fn tagged_32(data: &mut Reader) -> InternalResult<[i32; COUNT]> {
8    fn read_u8_or_eof(bytes: &mut Reader) -> InternalResult<u8> {
9        bytes.read_u8().ok_or(InternalError::Eof)
10    }
11
12    let mut result = [0; COUNT];
13
14    let byte = read_u8_or_eof(data)?;
15    match (byte & 0xC0) >> 6 {
16        // 2 bits
17        0 => {
18            #[inline(always)]
19            fn convert(x: u8) -> i32 {
20                sign_extend::<2>((x & 3).into())
21            }
22
23            result[0] = convert(byte >> 4);
24            result[1] = convert(byte >> 2);
25            result[2] = convert(byte);
26        }
27
28        // 4 bits
29        1 => {
30            #[inline(always)]
31            fn convert(x: u8) -> i32 {
32                sign_extend::<4>(x.into())
33            }
34
35            result[0] = convert(byte & 0x0F);
36
37            let byte = read_u8_or_eof(data)?;
38            result[1] = convert(byte >> 4);
39            result[2] = convert(byte & 0x0F);
40        }
41
42        // 6 bits
43        2 => {
44            #[inline(always)]
45            fn convert(x: u8) -> i32 {
46                sign_extend::<6>((x & 0x3F).into())
47            }
48
49            result[0] = convert(byte);
50
51            let byte = read_u8_or_eof(data)?;
52            result[1] = convert(byte);
53
54            let byte = read_u8_or_eof(data)?;
55            result[2] = convert(byte);
56        }
57
58        3.. => {
59            let mut tags = byte & 0x3F;
60            for x in &mut result {
61                let tag = tags & 3;
62                tags >>= 2;
63
64                *x = match tag {
65                    // 8 bits
66                    0 => read_u8_or_eof(data)?.cast_signed().into(),
67
68                    // 16 bits
69                    1 => data
70                        .read_u16()
71                        .ok_or(InternalError::Eof)?
72                        .cast_signed()
73                        .into(),
74
75                    // 24 bits
76                    2 => {
77                        let x = data.read_u24().ok_or(InternalError::Eof)?;
78                        sign_extend::<24>(x)
79                    }
80
81                    // 32 bits
82                    3.. => data.read_u32().ok_or(InternalError::Eof)?.cast_signed(),
83                }
84            }
85        }
86    }
87
88    Ok(result)
89}
90
91#[cfg(test)]
92mod tests {
93    use alloc::vec;
94    use alloc::vec::Vec;
95
96    use super::*;
97
98    fn bytes(tag: u8, width: usize) -> Vec<u8> {
99        assert_eq!(tag, tag & 3);
100
101        let tag = 0xC0 | (tag << 4) | (tag << 2) | tag;
102        let mut bytes = vec![tag];
103
104        for i in 1..=3 {
105            bytes.push(i);
106            bytes.append(&mut vec![0; width - 1]);
107        }
108
109        bytes
110    }
111
112    #[test]
113    fn all_02_bits() {
114        let b = [0x0D];
115        let mut b = Reader::new(&b);
116
117        assert_eq!([0, -1, 1], tagged_32(&mut b).unwrap());
118        assert!(b.is_empty());
119    }
120
121    #[test]
122    fn all_04_bits() {
123        let b = [0x41, 0x23];
124        let mut b = Reader::new(&b);
125
126        assert_eq!([1, 2, 3], tagged_32(&mut b).unwrap());
127        assert!(b.is_empty());
128    }
129
130    #[test]
131    fn all_06_bits() {
132        let b = [0x81, 0x02, 0x03];
133        let mut b = Reader::new(&b);
134
135        assert_eq!([1, 2, 3], tagged_32(&mut b).unwrap());
136        assert!(b.is_empty());
137    }
138
139    #[test]
140    fn all_08_bits() {
141        let b = bytes(0, 1);
142        let mut b = Reader::new(&b);
143
144        assert_eq!([1, 2, 3], tagged_32(&mut b).unwrap());
145        assert!(b.is_empty());
146    }
147
148    #[test]
149    fn all_16_bits() {
150        let b = bytes(1, 2);
151        let mut b = Reader::new(&b);
152
153        assert_eq!([1, 2, 3], tagged_32(&mut b).unwrap());
154        assert!(b.is_empty());
155    }
156
157    #[test]
158    fn all_24_bits() {
159        let b = bytes(2, 3);
160        let mut b = Reader::new(&b);
161
162        assert_eq!([1, 2, 3], tagged_32(&mut b).unwrap());
163        assert!(b.is_empty());
164    }
165
166    #[test]
167    fn all_32_bits() {
168        let b = bytes(3, 4);
169        let mut b = Reader::new(&b);
170
171        assert_eq!([1, 2, 3], tagged_32(&mut b).unwrap());
172        assert!(b.is_empty());
173    }
174
175    #[test]
176    #[should_panic(expected = "Eof")]
177    fn eof_04_bit() {
178        let mut b = Reader::new(&[0x40]);
179        tagged_32(&mut b).unwrap();
180    }
181
182    #[test]
183    #[should_panic(expected = "Eof")]
184    fn eof_06_bit() {
185        let mut b = Reader::new(&[0x80]);
186        tagged_32(&mut b).unwrap();
187    }
188}