1use std::{
2 convert::{TryFrom, TryInto},
3 ops::Range,
4};
5
6use crate::{Arg, DecodeError, FormatSliceElement, Table};
7use byteorder::{ReadBytesExt, LE};
8use defmt_parser::{get_max_bitfield_range, Fragment, Parameter, Type};
9
10pub(crate) struct Decoder<'t, 'b> {
11 table: &'t Table,
12 pub bytes: &'b [u8],
13}
14
15impl<'t, 'b> Decoder<'t, 'b> {
16 pub fn new(table: &'t Table, bytes: &'b [u8]) -> Self {
17 Self { table, bytes }
18 }
19
20 fn prepare_params(&self, params: &mut Vec<Parameter>) {
22 merge_bitfields(params);
24
25 params.sort_by(|a, b| a.index.cmp(&b.index));
27 params.dedup_by(|a, b| a.index == b.index);
28 }
29
30 fn get_format(&mut self) -> Result<&'t str, DecodeError> {
32 let index = self.bytes.read_u16::<LE>()? as usize;
33 let format = self
34 .table
35 .get_without_level(index)
36 .map_err(|_| DecodeError::Malformed)?;
37
38 Ok(format)
39 }
40
41 fn get_variant(&mut self, format: &'t str) -> Result<&'t str, DecodeError> {
42 assert!(format.contains('|'));
43 let num_variants = format.chars().filter(|c| *c == '|').count();
46
47 let discriminant: usize = if u8::try_from(num_variants).is_ok() {
48 self.bytes.read_u8()?.into()
49 } else if u16::try_from(num_variants).is_ok() {
50 self.bytes.read_u16::<LE>()?.into()
51 } else if u32::try_from(num_variants).is_ok() {
52 self.bytes
53 .read_u32::<LE>()?
54 .try_into()
55 .map_err(|_| DecodeError::Malformed)?
56 } else if u64::try_from(num_variants).is_ok() {
57 self.bytes
58 .read_u64::<LE>()?
59 .try_into()
60 .map_err(|_| DecodeError::Malformed)?
61 } else {
62 return Err(DecodeError::Malformed);
63 };
64
65 format
66 .split('|')
67 .nth(discriminant)
68 .ok_or(DecodeError::Malformed)
69 }
70
71 fn decode_format_slice(
72 &mut self,
73 num_elements: usize,
74 ) -> Result<Vec<FormatSliceElement<'t>>, DecodeError> {
75 let format = self.get_format()?;
76 let is_enum = format.contains('|');
77
78 let mut elements = Vec::with_capacity(num_elements);
79 for _i in 0..num_elements {
80 let format = if is_enum {
81 self.get_variant(format)?
82 } else {
83 format
84 };
85 let args = self.decode_format(format)?;
86 elements.push(FormatSliceElement { format, args });
87 }
88
89 Ok(elements)
90 }
91
92 pub fn decode_format(&mut self, format: &str) -> Result<Vec<Arg<'t>>, DecodeError> {
94 let mut args = vec![]; let mut params = defmt_parser::parse(format, defmt_parser::ParserMode::ForwardsCompatible)
96 .map_err(|_| DecodeError::Malformed)?
97 .iter()
98 .filter_map(|frag| match frag {
99 Fragment::Parameter(param) => Some(param.clone()),
100 Fragment::Literal(_) => None,
101 })
102 .collect::<Vec<_>>();
103
104 self.prepare_params(&mut params);
105
106 for param in ¶ms {
107 match ¶m.ty {
108 Type::I8 => args.push(Arg::Ixx(self.bytes.read_i8()? as i128)),
109 Type::I16 => args.push(Arg::Ixx(self.bytes.read_i16::<LE>()? as i128)),
110 Type::I32 => args.push(Arg::Ixx(self.bytes.read_i32::<LE>()? as i128)),
111 Type::I64 => args.push(Arg::Ixx(self.bytes.read_i64::<LE>()? as i128)),
112 Type::I128 => args.push(Arg::Ixx(self.bytes.read_i128::<LE>()?)),
113 Type::Isize => args.push(Arg::Ixx(self.bytes.read_i32::<LE>()? as i128)),
114 Type::U8 => args.push(Arg::Uxx(self.bytes.read_u8()? as u128)),
115 Type::U16 => args.push(Arg::Uxx(self.bytes.read_u16::<LE>()? as u128)),
116 Type::U32 => args.push(Arg::Uxx(self.bytes.read_u32::<LE>()? as u128)),
117 Type::U64 => args.push(Arg::Uxx(self.bytes.read_u64::<LE>()? as u128)),
118 Type::U128 => args.push(Arg::Uxx(self.bytes.read_u128::<LE>()?)),
119 Type::Usize => args.push(Arg::Uxx(self.bytes.read_u32::<LE>()? as u128)),
120 Type::F32 => args.push(Arg::F32(f32::from_bits(self.bytes.read_u32::<LE>()?))),
121 Type::F64 => args.push(Arg::F64(f64::from_bits(self.bytes.read_u64::<LE>()?))),
122 Type::Bool => args.push(Arg::Bool(match self.bytes.read_u8()? {
123 0 => false,
124 1 => true,
125 _ => return Err(DecodeError::Malformed),
126 })),
127 Type::FormatSlice => {
128 let num_elements = self.bytes.read_u32::<LE>()? as usize;
129 let elements = self.decode_format_slice(num_elements)?;
130 args.push(Arg::FormatSlice { elements });
131 }
132 Type::Format => {
133 let format = self.get_format()?;
134
135 if format.contains('|') {
136 let variant = self.get_variant(format)?;
138 let inner_args = self.decode_format(variant)?;
139 args.push(Arg::Format {
140 format: variant,
141 args: inner_args,
142 });
143 } else {
144 let inner_args = self.decode_format(format)?;
145 args.push(Arg::Format {
146 format,
147 args: inner_args,
148 });
149 }
150 }
151 Type::BitField(range) => {
152 let lowest_byte = range.start / 8;
153 let highest_byte = (range.end - 1) / 8; let size_after_truncation = highest_byte - lowest_byte + 1; let mut data = match size_after_truncation {
157 1 => self.bytes.read_u8()? as u128,
158 2 => self.bytes.read_u16::<LE>()? as u128,
159 3..=4 => self.bytes.read_u32::<LE>()? as u128,
160 5..=8 => self.bytes.read_u64::<LE>()? as u128,
161 9..=16 => self.bytes.read_u128::<LE>()?,
162 _ => unreachable!(),
163 };
164
165 data <<= lowest_byte * 8;
166
167 args.push(Arg::Uxx(data));
168 }
169 Type::Str => {
170 let str_len = self.bytes.read_u32::<LE>()? as usize;
171 let mut arg_str_bytes = vec![];
172
173 for _ in 0..str_len {
175 arg_str_bytes.push(self.bytes.read_u8()?);
176 }
177
178 let arg_str =
180 String::from_utf8(arg_str_bytes).map_err(|_| DecodeError::Malformed)?;
181
182 args.push(Arg::Str(arg_str));
183 }
184 Type::IStr => {
185 let str_index = self.bytes.read_u16::<LE>()? as usize;
186
187 let string = self
188 .table
189 .get_without_level(str_index)
190 .map_err(|_| DecodeError::Malformed)?;
191
192 args.push(Arg::IStr(string));
193 }
194 Type::U8Slice => {
195 let num_elements = self.bytes.read_u32::<LE>()? as usize;
197 let mut arg_slice = vec![];
198
199 for _ in 0..num_elements {
201 arg_slice.push(self.bytes.read_u8()?);
202 }
203 args.push(Arg::Slice(arg_slice.to_vec()));
204 }
205 Type::U8Array(len) => {
206 let mut arg_slice = vec![];
207 for _ in 0..*len {
209 arg_slice.push(self.bytes.read_u8()?);
210 }
211 args.push(Arg::Slice(arg_slice.to_vec()));
212 }
213 Type::FormatArray(len) => {
214 let elements = self.decode_format_slice(*len)?;
215 args.push(Arg::FormatSlice { elements });
216 }
217 Type::Char => {
218 let data = self.bytes.read_u32::<LE>()?;
219 let c = std::char::from_u32(data).ok_or(DecodeError::Malformed)?;
220 args.push(Arg::Char(c));
221 }
222 Type::Debug | Type::Display => {
223 let end = self
226 .bytes
227 .iter()
228 .position(|b| *b == 0xff)
229 .ok_or(DecodeError::UnexpectedEof)?;
230 let data = core::str::from_utf8(&self.bytes[..end])
231 .map_err(|_| DecodeError::Malformed)?;
232 self.bytes = &self.bytes[end + 1..];
233
234 args.push(Arg::Preformatted(data.into()));
235 }
236 Type::FormatSequence => {
237 let mut seq_args = Vec::new();
238 loop {
239 let index = self.bytes.read_u16::<LE>()? as usize;
240 if index == 0 {
241 break;
242 }
243
244 let format = self
245 .table
246 .get_without_level(index)
247 .map_err(|_| DecodeError::Malformed)?;
248
249 let inner_args = self.decode_format(format)?;
250 seq_args.push(Arg::Format {
251 format,
252 args: inner_args,
253 });
254 }
255 args.push(Arg::FormatSequence { args: seq_args })
256 }
257 }
258 }
259
260 Ok(args)
261 }
262}
263
264fn merge_bitfields(params: &mut Vec<Parameter>) {
267 if params.is_empty() {
268 return;
269 }
270
271 let mut merged_bitfields = Vec::new();
272
273 let max_index: usize = *params.iter().map(|param| ¶m.index).max().unwrap();
274
275 for index in 0..=max_index {
276 let mut bitfields_with_index = params
277 .iter()
278 .filter(
279 |param| matches!((param.index, ¶m.ty), (i, Type::BitField(_)) if i == index),
280 )
281 .peekable();
282
283 if bitfields_with_index.peek().is_some() {
284 let (smallest, largest) = get_max_bitfield_range(bitfields_with_index).unwrap();
285
286 merged_bitfields.push(Parameter {
288 index,
289 ty: Type::BitField(Range {
290 start: smallest,
291 end: largest,
292 }),
293 hint: None, });
295
296 let mut i = 0;
299 while i != params.len() {
300 match ¶ms[i].ty {
301 Type::BitField(_) => {
302 if params[i].index == index {
303 params.remove(i);
304 } else {
305 i += 1; }
307 }
308 _ => {
309 i += 1; }
311 }
312 }
313 }
314 }
315
316 params.append(&mut merged_bitfields);
318}
319
320#[cfg(test)]
321mod tests {
322 use super::*;
323
324 #[test]
325 fn merge_bitfields_simple() {
326 let mut params = vec![
327 Parameter {
328 index: 0,
329 ty: Type::BitField(0..3),
330 hint: None,
331 },
332 Parameter {
333 index: 0,
334 ty: Type::BitField(4..7),
335 hint: None,
336 },
337 ];
338
339 merge_bitfields(&mut params);
340 assert_eq!(
341 params,
342 vec![Parameter {
343 index: 0,
344 ty: Type::BitField(0..7),
345 hint: None,
346 }]
347 );
348 }
349
350 #[test]
351 fn merge_bitfields_overlap() {
352 let mut params = vec![
353 Parameter {
354 index: 0,
355 ty: Type::BitField(1..3),
356 hint: None,
357 },
358 Parameter {
359 index: 0,
360 ty: Type::BitField(2..5),
361 hint: None,
362 },
363 ];
364
365 merge_bitfields(&mut params);
366 assert_eq!(
367 params,
368 vec![Parameter {
369 index: 0,
370 ty: Type::BitField(1..5),
371 hint: None,
372 }]
373 );
374 }
375
376 #[test]
377 fn merge_bitfields_multiple_indices() {
378 let mut params = vec![
379 Parameter {
380 index: 0,
381 ty: Type::BitField(0..3),
382 hint: None,
383 },
384 Parameter {
385 index: 1,
386 ty: Type::BitField(1..3),
387 hint: None,
388 },
389 Parameter {
390 index: 1,
391 ty: Type::BitField(4..5),
392 hint: None,
393 },
394 ];
395
396 merge_bitfields(&mut params);
397 assert_eq!(
398 params,
399 vec![
400 Parameter {
401 index: 0,
402 ty: Type::BitField(0..3),
403 hint: None,
404 },
405 Parameter {
406 index: 1,
407 ty: Type::BitField(1..5),
408 hint: None,
409 }
410 ]
411 );
412 }
413
414 #[test]
415 fn merge_bitfields_overlap_non_consecutive_indices() {
416 let mut params = vec![
417 Parameter {
418 index: 0,
419 ty: Type::BitField(0..3),
420 hint: None,
421 },
422 Parameter {
423 index: 1,
424 ty: Type::U8,
425 hint: None,
426 },
427 Parameter {
428 index: 2,
429 ty: Type::BitField(1..4),
430 hint: None,
431 },
432 Parameter {
433 index: 2,
434 ty: Type::BitField(4..5),
435 hint: None,
436 },
437 ];
438
439 merge_bitfields(&mut params);
440 assert_eq!(
442 params,
443 vec![
444 Parameter {
445 index: 1,
446 ty: Type::U8,
447 hint: None,
448 },
449 Parameter {
450 index: 0,
451 ty: Type::BitField(0..3),
452 hint: None,
453 },
454 Parameter {
455 index: 2,
456 ty: Type::BitField(1..5),
457 hint: None,
458 }
459 ]
460 );
461 }
462}