blackbox_log/parser/decode/
tagged_32.rs1use 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 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 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 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 0 => read_u8_or_eof(data)?.cast_signed().into(),
67
68 1 => data
70 .read_u16()
71 .ok_or(InternalError::Eof)?
72 .cast_signed()
73 .into(),
74
75 2 => {
77 let x = data.read_u24().ok_or(InternalError::Eof)?;
78 sign_extend::<24>(x)
79 }
80
81 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}