1use simple_sbe::decode::{decode_header, decode_message};
2use simple_sbe::otf::header::MessageHeaderListener;
3use simple_sbe::otf::listener::{TokenListener, TokenListenerError};
4use simple_sbe::token::{
5 ByteOrder, Encoding, Presence, PrimitiveType, PrimitiveValue, Signal, Token,
6};
7use simple_sbe::tokenize;
8use std::borrow::Cow;
9use std::collections::VecDeque;
10use std::env::args;
11use std::fs::File;
12use std::io::Read;
13
14fn main() -> anyhow::Result<()> {
15 let args = args().skip(1).take(2).collect::<Vec<_>>();
16 let mut schema_file = File::open(&args[0])?;
17 let mut message_file = File::open(&args[1])?;
18
19 let mut svbuf = Vec::new();
20 schema_file.read_to_end(&mut svbuf)?;
21
22 let mut msg_buf = Vec::new();
23 message_file.read_to_end(&mut msg_buf)?;
24
25 let tokens = tokenize(&svbuf);
26
27 for t in &tokens {
28 println!("{t:?}");
29 }
30
31 let mut l = MyListener::default();
32 println!("=== header ===");
34 let mut x = MessageHeaderListener::new(&mut l);
35 let (tokens, msg_buf) = decode_header(&tokens, &msg_buf, 0, &mut x);
36 let h = x.into_message_header()?;
37 println!("{h:?}");
38 println!("=== message ===");
39 let msg_buf = decode_message(&tokens, msg_buf, h.block_length, h.version as i32, &mut l);
40
41 Ok(())
42}
43
44#[derive(Default)]
45struct MyListener {
46 named_scope: VecDeque<String>,
47 composite_level: usize,
48}
49
50impl TokenListener for MyListener {
51 fn on_begin_message(&mut self, token: &Token) -> Result<(), TokenListenerError> {
52 self.named_scope.push_back(format!("{}", token.name));
53 Ok(())
54 }
55
56 fn on_end_message(&mut self, token: &Token) -> Result<(), TokenListenerError> {
57 self.named_scope.pop_back();
58 Ok(())
59 }
60
61 fn on_encoding(
62 &mut self,
63 field_token: &Token,
64 buffer: &[u8],
65 type_token: &Token,
66 acting_version: i32,
67 ) -> Result<(), TokenListenerError> {
68 self.print_scope();
70 if self.composite_level > 0 {
71 print!("{}", type_token.name);
72 } else {
73 print!("{}", field_token.name);
74 }
75
76 let np = self.const_or_not_present_value(type_token, field_token.version, acting_version);
77 if np.is_none() {
78 println!(
79 "={} : {buffer:02X?}",
80 buffer
81 .chunks(type_token.encoding.primitive_type.size())
82 .map(|b| format!(
83 "{}",
84 PrimitiveValue::new(type_token.encoding.primitive_type, b)
85 ))
86 .collect::<Vec<_>>()
87 .join(", ")
88 );
89 } else {
90 print!("={np}");
91 for _ in 1..type_token.array_length() {
92 print!(", {np}");
93 }
94 println!(" [const]")
95 }
96
97 Ok(())
98 }
99
100 fn on_enum(
101 &mut self,
102 field_token: &Token,
103 enum_token: &Token,
104 buffer: &[u8],
105 tokens: &[Token],
106 acting_version: i32,
107 ) -> Result<(), TokenListenerError> {
108 let value = PrimitiveValue::new(enum_token.encoding.primitive_type, buffer);
118 let mut name: Cow<str> = "???".into();
119 if matches!(field_token.encoding.presence, Presence::Constant) {
120 name = field_token.encoding.const_value.to_string()[enum_token.name.len() + 1..]
121 .to_string()
122 .into();
123 } else {
124 for t in tokens {
125 if value == t.encoding.const_value {
127 name = (&t.name).into();
128 break;
129 }
130 }
131 }
132 self.print_scope();
133 if self.composite_level > 0 {
134 print!("{}=", enum_token.name);
135 } else {
136 print!("{}=", field_token.name);
137 }
138 println!("{name} : {value:?}");
139
140 Ok(())
141 }
142
143 fn on_bit_set(
144 &mut self,
145 field_token: &Token,
146 set_token: &Token,
147 buffer: &[u8],
148 tokens: &[Token],
149 acting_version: i32,
150 ) -> Result<(), TokenListenerError> {
151 self.print_scope();
152 if self.composite_level > 0 {
153 print!("{}:", set_token.name);
154 } else {
155 print!("{}:", field_token.name);
156 }
157 let value: u64 = PrimitiveValue::new(set_token.encoding.primitive_type, buffer)
158 .try_into()
159 .unwrap();
160 for t in tokens {
161 let pos: u64 = (&t.encoding.const_value).try_into().unwrap();
162 let is_set = (1 << pos & value) != 0;
163 print!(" {}={is_set}", t.name);
164 }
165 println!();
166 Ok(())
168 }
169
170 fn on_begin_composite(
171 &mut self,
172 field_token: &Token,
173 composite_token: &Token,
174 tokens: &[Token],
175 ) -> Result<(), TokenListenerError> {
176 let name = if self.composite_level > 0 {
177 &composite_token.name
178 } else {
179 &field_token.name
180 };
181 self.named_scope.push_back(name.to_owned());
182 self.composite_level += 1;
183 Ok(())
185 }
186
187 fn on_end_composite(
188 &mut self,
189 field_token: &Token,
190 tokens: &[Token],
191 ) -> Result<(), TokenListenerError> {
192 self.composite_level -= 1;
193 let c = self.named_scope.pop_back();
194 println!("-<- Composite {c:?}");
195 debug_assert!(c.is_some());
196 Ok(())
197 }
198
199 fn on_group_header(
200 &mut self,
201 token: &Token,
202 num_in_group: usize,
203 ) -> Result<(), TokenListenerError> {
204 self.print_scope();
205 println!("{} Group Header : numInGroup={num_in_group}", token.name);
206 Ok(())
207 }
208
209 fn on_begin_group(
210 &mut self,
211 token: &Token,
212 group_index: usize,
213 num_in_group: usize,
214 ) -> Result<(), TokenListenerError> {
215 self.named_scope.push_back(format!("{}", token.name));
216 Ok(())
217 }
218
219 fn on_end_group(
220 &mut self,
221 token: &Token,
222 group_index: i32,
223 num_in_group: i32,
224 ) -> Result<(), TokenListenerError> {
225 self.named_scope.pop_back();
226 Ok(())
227 }
228
229 fn on_var_data(
230 &mut self,
231 field_token: &Token,
232 buffer: &[u8],
233 type_token: &Token,
234 ) -> Result<(), TokenListenerError> {
235 println!("VARDATA! {type_token:?}");
236 self.print_scope();
237 println!("{}='{:?}'", field_token.name, buffer);
238 Ok(())
240 }
241}
242
243impl MyListener {
244 fn print_scope(&self) {
245 for s in &self.named_scope {
246 print!("{s}.");
247 }
248 }
249
250 fn const_or_not_present_value<'t>(
251 &self,
252 type_token: &'t Token,
253 field_version: i32,
254 acting_version: i32,
255 ) -> &'t PrimitiveValue {
256 match &type_token.encoding.presence {
257 Presence::Constant => &type_token.encoding.const_value,
258 Presence::Optional if acting_version < field_version => {
259 type_token.encoding.applicable_null_value()
260 }
261 _ => &PrimitiveValue::None,
262 }
263 }
264
265 fn encoding_as_string(
266 &self,
267 type_token: &Token,
268 buffer: &[u8],
269 field_version: i32,
270 acting_version: i32,
271 ) {
272 let v = self.const_or_not_present_value(type_token, field_version, acting_version);
273 if v.is_none() {}
274 }
275}