1use crate::otf::listener::{TokenListener, TokenListenerError};
2use crate::token::{PrimitiveValue, Token};
3
4#[derive(Debug)]
5pub struct MessageHeader {
6 pub block_length: usize,
7 pub template_id: u64,
8 pub schema_id: u64,
9 pub version: u64,
10}
11
12pub struct MessageHeaderListener<'a, T> {
13 inner: &'a mut T,
14 message_header: MessageHeader,
15 composite_level: usize,
16 block_length_found: bool,
17 template_id_found: bool,
18 schema_id_found: bool,
19 version_found: bool,
20}
21
22impl<'a, T> MessageHeaderListener<'a, T>
23where
24 T: TokenListener,
25{
26 pub fn new(nested: &'a mut T) -> Self {
27 Self {
28 inner: nested,
29 message_header: MessageHeader {
30 block_length: 0,
31 template_id: 0,
32 schema_id: 0,
33 version: 0,
34 },
35 composite_level: 0,
36 block_length_found: false,
37 template_id_found: false,
38 schema_id_found: false,
39 version_found: false,
40 }
41 }
42}
43
44impl<T> MessageHeaderListener<'_, T> {
45 pub fn into_message_header(self) -> Result<MessageHeader, TokenListenerError> {
46 if !self.block_length_found {
47 Err(TokenListenerError::StaticError(
48 "field blockLength not found in header",
49 ))
50 } else if !self.template_id_found {
51 Err(TokenListenerError::StaticError(
52 "field templateId not found in header",
53 ))
54 } else if !self.schema_id_found {
55 Err(TokenListenerError::StaticError(
56 "field schemaId not found in header",
57 ))
58 } else if !self.version_found {
59 Err(TokenListenerError::StaticError(
60 "field version not found in header",
61 ))
62 } else {
63 Ok(self.message_header)
64 }
65 }
66}
67
68impl<T> TokenListener for MessageHeaderListener<'_, T>
69where
70 T: TokenListener,
71{
72 fn on_begin_composite(
73 &mut self,
74 field_token: &Token,
75 composite_token: &Token,
76 tokens: &[Token],
77 ) -> Result<(), TokenListenerError> {
78 self.composite_level += 1;
79 self.inner
80 .on_begin_composite(field_token, composite_token, tokens)
81 }
82
83 fn on_encoding(
84 &mut self,
85 field_token: &Token,
86 buffer: &[u8],
87 type_token: &Token,
88 acting_version: i32,
89 ) -> Result<(), TokenListenerError> {
90 self.inner
91 .on_encoding(field_token, buffer, type_token, acting_version)?;
92
93 if self.composite_level == 1 {
94 match &type_token.name[..] {
95 "blockLength" => {
96 let val: u64 = PrimitiveValue::new(type_token.encoding.primitive_type, buffer)
97 .try_into()
98 .map_err(|e| TokenListenerError::BoxError(Box::new(e)))?;
99 self.message_header.block_length = val
100 .try_into()
101 .map_err(|e| TokenListenerError::BoxError(Box::new(e)))?;
102 self.block_length_found = true;
103 }
104 "templateId" => {
105 self.message_header.template_id =
106 PrimitiveValue::new(type_token.encoding.primitive_type, buffer)
107 .try_into()
108 .map_err(|e| TokenListenerError::BoxError(Box::new(e)))?;
109 self.template_id_found = true;
110 }
111 "schemaId" => {
112 self.message_header.schema_id =
113 PrimitiveValue::new(type_token.encoding.primitive_type, buffer)
114 .try_into()
115 .map_err(|e| TokenListenerError::BoxError(Box::new(e)))?;
116 self.schema_id_found = true;
117 }
118 "version" => {
119 self.message_header.version =
120 PrimitiveValue::new(type_token.encoding.primitive_type, buffer)
121 .try_into()
122 .map_err(|e| TokenListenerError::BoxError(Box::new(e)))?;
123 self.version_found = true;
124 }
125 _ => (),
126 }
127 } else if self.composite_level == 0 {
128 return Err(TokenListenerError::StaticError(
130 "unexpected encoding token while not in composite while decoding header",
131 ));
132 }
133 Ok(())
134 }
135
136 fn on_end_composite(
137 &mut self,
138 field_token: &Token,
139 tokens: &[Token],
140 ) -> Result<(), TokenListenerError> {
141 self.composite_level -= 1;
142 self.inner.on_end_composite(field_token, tokens)
143 }
144
145 fn on_begin_message(&mut self, field_token: &Token) -> Result<(), TokenListenerError> {
146 self.inner.on_begin_message(field_token)?;
147 Err(TokenListenerError::StaticError(
149 "unexpected begin of message token while decoding header header",
150 ))
151 }
152
153 fn on_end_message(&mut self, token: &Token) -> Result<(), TokenListenerError> {
154 self.inner.on_end_message(token)
155 }
156
157 fn on_enum<'a>(
158 &mut self,
159 field_token: &Token,
160 enum_token: &Token,
161 buffer: &[u8],
162 tokens: &[Token],
163 acting_version: i32,
164 ) -> Result<(), TokenListenerError> {
165 self.inner
166 .on_enum(field_token, enum_token, buffer, tokens, acting_version)
167 }
168
169 fn on_bit_set(
170 &mut self,
171 field_token: &Token,
172 set_token: &Token,
173 buffer: &[u8],
174 tokens: &[Token],
175 acting_version: i32,
176 ) -> Result<(), TokenListenerError> {
177 self.inner
178 .on_bit_set(field_token, set_token, buffer, tokens, acting_version)
179 }
180
181 fn on_group_header(
182 &mut self,
183 token: &Token,
184 num_in_group: usize,
185 ) -> Result<(), TokenListenerError> {
186 self.inner.on_group_header(token, num_in_group)
187 }
188
189 fn on_begin_group(
190 &mut self,
191 token: &Token,
192 group_index: usize,
193 num_in_group: usize,
194 ) -> Result<(), TokenListenerError> {
195 self.inner.on_begin_group(token, group_index, num_in_group)
196 }
197
198 fn on_end_group(
199 &mut self,
200 token: &Token,
201 group_index: i32,
202 num_in_group: i32,
203 ) -> Result<(), TokenListenerError> {
204 self.inner.on_end_group(token, group_index, num_in_group)
205 }
206
207 fn on_var_data(
208 &mut self,
209 field_token: &Token,
210 buffer: &[u8],
211 type_token: &Token,
212 ) -> Result<(), TokenListenerError> {
213 self.inner.on_var_data(field_token, buffer, type_token)
214 }
215}