Skip to main content

simple_sbe/otf/
header.rs

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            // something is wrong, let's catch it early
129            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        // something is wrong, let's catch it early
148        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}