1use crate::otf::listener::TokenListener;
2use crate::token::{PrimitiveValue, Signal, Token};
3
4pub fn decode_header<'t, 'b, L>(
5 tokens: &'t [Token],
6 msg_buf: &'b [u8],
7 acting_version: i32,
8 listener: &mut L,
9) -> (&'t [Token], &'b [u8])
10where
11 L: TokenListener,
12{
13 println!(" == decode {msg_buf:02X?}");
14 let Some((tok, rest)) = tokens.split_first() else {
15 return (&[], &[]); };
17 let count = tok.component_token_count as usize;
18 let Some((composite, rest)) = rest.split_at_checked(count - 1) else {
20 return (&[], &[]); };
22 debug_assert_eq!(tok.signal, Signal::BeginComposite);
23 debug_assert_eq!(composite.last().unwrap().signal, Signal::EndComposite);
24 decode_composite(
25 tok,
26 &composite[0],
27 &composite[..count - 2],
28 msg_buf,
29 acting_version,
30 listener,
31 );
32 (rest, &msg_buf[tok.encoded_length as usize..])
33}
34
35pub fn decode_message<'t, 'b, L>(
36 tokens: &'t [Token],
37 msg_buf: &'b [u8],
38 block_length: usize,
39 acting_version: i32,
40 listener: &mut L,
41) -> &'b [u8]
42where
43 L: TokenListener,
44{
45 println!(" == decode {msg_buf:02X?}");
46 let Some((tok, rest)) = tokens.split_first() else {
47 return &[]; };
49 debug_assert_eq!(tok.signal, Signal::BeginMessage);
51 listener.on_begin_message(tok).unwrap();
52
53 let rest = decode_fields(rest, msg_buf, acting_version, listener);
54
55 let end_tok = tokens.last().unwrap();
56 debug_assert_eq!(end_tok.signal, Signal::EndMessage);
57
58 decode_groups(rest, &msg_buf[block_length..], acting_version, listener);
59 listener.on_end_message(end_tok).unwrap();
62 &[]
63}
64
65fn decode_groups<'t, 'b, L>(
66 mut tokens: &'t [Token],
67 mut msg_buf: &'b [u8],
68 acting_version: i32,
69 listener: &mut L,
70) -> &'t [Token]
71where
72 L: TokenListener,
73{
74 println!(" == decode {msg_buf:02X?}");
75 loop {
76 let Some((
77 [
78 begin_tok,
79 dimension_type_comp_tok,
80 block_len_tok,
81 num_in_group_tok,
82 dimension_type_end_comp_tok,
83 ],
84 mut rest,
85 )) = tokens.split_first_chunk()
86 else {
87 println!("no group? {:?}", tokens);
88 break;
89 };
90
91 debug_assert_eq!(begin_tok.signal, Signal::BeginGroup);
93 debug_assert_eq!(dimension_type_comp_tok.signal, Signal::BeginComposite);
94 debug_assert_eq!(block_len_tok.signal, Signal::Encoding);
95 debug_assert_eq!(num_in_group_tok.signal, Signal::Encoding);
96 debug_assert_eq!(dimension_type_end_comp_tok.signal, Signal::EndComposite);
97
98 let is_present = begin_tok.version <= acting_version;
99 let block_len = is_present
100 .then_some(block_len_tok.offset as usize)
101 .unwrap_or(0);
102 let mut num_in_group: usize = 0;
103
104 if is_present {
105 let num: u64 = PrimitiveValue::new(
106 num_in_group_tok.encoding.primitive_type,
107 &msg_buf[num_in_group_tok.offset as usize
108 ..num_in_group_tok.offset as usize + num_in_group_tok.encoded_length as usize],
109 )
110 .try_into()
111 .unwrap();
112 num_in_group = num as usize;
113 msg_buf = &msg_buf[dimension_type_comp_tok.encoded_length as usize..];
114 }
115
116 listener.on_group_header(begin_tok, num_in_group).unwrap();
117
118 for i in 0..num_in_group {
119 listener.on_begin_group(begin_tok, i, num_in_group).unwrap();
120
121 rest = decode_fields(rest, msg_buf, acting_version, listener);
122
123 decode_data(rest, &msg_buf[block_len..], acting_version, listener);
126 break; }
129 break; }
131 &[]
132}
133
134fn decode_data<'t, 'b, L>(
135 mut tokens: &'t [Token],
136 mut msg_buf: &'b [u8],
137 acting_version: i32,
138 listener: &mut L,
139) -> &'t [Token]
140where
141 L: TokenListener,
142{
143 println!(" == decode {msg_buf:02X?}");
144 loop {
145 let Some(([begin_tok, comp_tok, len_tok, var_data_tok], rest)) = tokens.split_first_chunk()
146 else {
147 println!("no vardata? {:?}", tokens);
148 break;
149 };
150 if begin_tok.signal != Signal::BeginVarData {
151 println!(
152 "not begin var data field {:?}@{}",
153 begin_tok.signal, begin_tok.i
154 );
155 break;
156 }
157 debug_assert_eq!(comp_tok.signal, Signal::BeginComposite);
158 debug_assert_eq!(len_tok.signal, Signal::Encoding);
159 debug_assert_eq!(var_data_tok.signal, Signal::Encoding);
160 let is_present = begin_tok.version <= acting_version;
161 let len = is_present.then_some(len_tok.offset as usize).unwrap_or(0);
162 let off = is_present
163 .then_some(var_data_tok.offset as usize)
164 .unwrap_or(0);
165 listener
166 .on_var_data(begin_tok, &msg_buf[off..off + len], var_data_tok)
167 .unwrap();
168 tokens = rest;
169 msg_buf = &msg_buf[off + len..];
170 }
171 &[]
172}
173
174fn decode_fields<'t, 'b, L>(
175 mut tokens: &'t [Token],
176 msg_buf: &'b [u8],
177 acting_version: i32,
178 listener: &mut L,
179) -> &'t [Token]
180where
181 L: TokenListener,
182{
183 loop {
184 let Some(([field_tok, type_tok], rest)) = tokens.split_first_chunk() else {
185 println!("finished tok?? {:?}", tokens);
186 break;
187 };
188 if field_tok.signal != Signal::BeginField {
189 println!("not begin field {:?}@{}", field_tok.signal, field_tok.i);
190 break;
191 }
192
193 let type_token_count = type_tok.component_token_count as usize;
194 let Some((current, next)) = rest.split_at_checked(type_token_count) else {
195 println!("can't split next field");
196 break;
197 };
198 debug_assert_eq!(
199 type_token_count,
200 field_tok.component_token_count as usize - 2
201 );
202 debug_assert_eq!(current[type_token_count - 1].signal, Signal::EndField);
203
204 let off = type_tok.offset as usize;
205 let len = type_tok.encoded_length as usize;
206 let segment = &msg_buf[off..off + len];
207
208 match type_tok.signal {
209 Signal::BeginComposite => {
210 println!(
211 "->- Composite@{}[{type_token_count}] {off} : {type_tok:?}",
212 type_tok.i
213 );
214 debug_assert!(type_token_count >= 2);
215 let Some((inner, _)) = current.split_at_checked(type_token_count - 2) else {
216 println!("no composite");
217 break;
218 };
219 decode_composite(
220 field_tok,
221 type_tok,
222 &inner,
223 segment,
224 acting_version,
225 listener,
226 );
227 debug_assert_eq!(current[type_token_count - 2].signal, Signal::EndComposite);
228 }
229 Signal::BeginEnum => {
230 listener
231 .on_enum(
232 field_tok,
233 type_tok,
234 segment,
235 ¤t[..type_token_count - 2],
236 acting_version,
237 )
238 .unwrap();
239 }
240 Signal::BeginSet => {
241 listener
242 .on_bit_set(
243 field_tok,
244 type_tok,
245 segment,
246 ¤t[..type_token_count - 2],
247 acting_version,
248 )
249 .unwrap();
250 }
251 Signal::Encoding => {
252 let _count = len / type_tok.encoding.primitive_type.size();
253 let end = off + type_tok.encoding.primitive_type.size(); listener
255 .on_encoding(field_tok, segment, type_tok, acting_version)
256 .unwrap();
257 }
258 _ => {
259 println!("unknown type");
260 }
261 }
262 tokens = next;
263 }
264 tokens
265}
266
267fn decode_composite<'b, L>(
268 field_token: &Token,
269 composite_token: &Token,
270 tokens: &[Token],
271 msg_buf: &'b [u8],
272 acting_version: i32,
273 listener: &mut L,
274) -> &'b [u8]
275where
276 L: TokenListener,
277{
278 listener
279 .on_begin_composite(field_token, composite_token, &tokens)
280 .unwrap();
281 println!(
282 "--> Composite {:?} : {msg_buf:?}",
283 tokens
284 .iter()
285 .map(|x| (&x.signal, &x.name))
286 .collect::<Vec<_>>()
287 );
288
289 let mut xtokens = tokens;
290 loop {
291 let Some((type_tok, rest)) = xtokens.split_first() else {
292 break;
293 };
294 let type_token_count = type_tok.component_token_count as usize;
295 match type_tok.signal {
296 Signal::BeginComposite => {
297 println!("Compositeception! {type_tok:?}");
298 let off = type_tok.offset as usize;
299 let len = type_tok.encoded_length as usize;
300 decode_composite(
301 field_token,
302 type_tok,
303 &rest[..type_token_count - 2],
304 &msg_buf[off..off + len],
305 acting_version,
306 listener,
307 );
308 xtokens = &rest[type_token_count - 1..];
309 }
310 Signal::BeginEnum => {
311 let off = type_tok.offset as usize;
312 let len = type_tok.encoded_length as usize;
313 listener
314 .on_enum(
315 field_token,
316 type_tok,
317 &msg_buf[off..off + len],
318 &rest[..type_token_count - 2],
319 acting_version,
320 )
321 .unwrap();
322 xtokens = &rest[type_token_count - 1..];
323 }
324 Signal::BeginSet => {
325 let off = type_tok.offset as usize;
326 let len = type_tok.encoded_length as usize;
327 listener
328 .on_bit_set(
329 field_token,
330 type_tok,
331 &msg_buf[off..off + len],
332 &rest[..type_token_count - 2],
333 acting_version,
334 )
335 .unwrap();
336 xtokens = &rest[type_token_count - 1..];
337 }
338 Signal::Encoding => {
339 let name = &type_tok.name;
341 let s = type_tok.offset as usize;
342 let e = s + type_tok.encoded_length as usize;
343 let seg = &msg_buf[s..e];
344 let p = PrimitiveValue::new(type_tok.encoding.primitive_type, seg);
345 listener
347 .on_encoding(field_token, seg, type_tok, acting_version)
348 .unwrap();
349 xtokens = &rest[type_token_count - 1..];
350 }
351 _ => {
352 panic!(
353 "unknown type in composite {:?}@{}",
354 type_tok.signal, type_tok.i
355 );
356 }
357 }
358 }
359
360 listener.on_end_composite(field_token, &tokens).unwrap();
361 &[]
362}