hawktracer_parser/
data_struct_reader.rs

1use crate::data_provider::{DataError, DataProvider};
2use crate::event::{DataType, Event, Value};
3use crate::event_klass::{EventKlass, EventKlassField};
4use crate::registry::EventKlassRegistry;
5
6#[derive(Debug, PartialEq)]
7pub enum ReadEventError {
8    DataError(DataError),
9    UnknownKlass(String),
10    UnknownKlassId(u32),
11    RegistryUpdateFailed(String),
12}
13
14pub struct DataStructReader<'a> {
15    data_provider: &'a mut DataProvider,
16    registry: &'a EventKlassRegistry,
17    base_event: Option<Event>,
18    klass: &'a EventKlass,
19}
20
21macro_rules! get_integer {
22    ($self: ident, $type: ty, $size: expr, $data_type: ident) => {{
23        let mut buffer: [u8; $size] = [0; $size];
24        match $self.data_provider.read_bytes(&mut buffer) {
25            Ok(()) => unsafe {
26                Ok(Value::$data_type(
27                    std::mem::transmute::<[u8; $size], $type>(buffer),
28                ))
29            },
30            Err(err) => Err(ReadEventError::DataError(err)),
31        }
32    }};
33}
34
35impl<'a> DataStructReader<'a> {
36    pub fn new(
37        data_provider: &'a mut DataProvider,
38        registry: &'a EventKlassRegistry,
39        klass: &'a EventKlass,
40        base_event: Option<Event>,
41    ) -> DataStructReader<'a> {
42        DataStructReader {
43            data_provider,
44            registry,
45            base_event,
46            klass,
47        }
48    }
49
50    pub fn read_event(&mut self) -> Result<Event, ReadEventError> {
51        self.read_event_internal(self.klass)
52    }
53
54    fn read_event_internal(&mut self, klass: &EventKlass) -> Result<Event, ReadEventError> {
55        let mut values: std::collections::HashMap<String, Value> = std::collections::HashMap::new();
56        for field in klass.get_fields() {
57            values.insert(field.get_name().clone(), self.read_field(&field)?);
58        }
59
60        Ok(Event::new(klass.get_id(), values))
61    }
62
63    fn read_field(&mut self, field: &EventKlassField) -> Result<Value, ReadEventError> {
64        match field.get_data_type() {
65            DataType::U8 => get_integer!(self, u8, 1, U8),
66            DataType::I8 => get_integer!(self, i8, 1, I8),
67            DataType::U16 => get_integer!(self, u16, 2, U16),
68            DataType::I16 => get_integer!(self, i16, 2, I16),
69            DataType::U32 => get_integer!(self, u32, 4, U32),
70            DataType::I32 => get_integer!(self, i32, 4, I32),
71            DataType::U64 => get_integer!(self, u64, 8, U64),
72            DataType::I64 => get_integer!(self, i64, 8, I64),
73            DataType::Str => self.read_string(),
74            DataType::Struct => self.read_struct(field),
75        }
76    }
77
78    fn read_struct(&mut self, field: &EventKlassField) -> Result<Value, ReadEventError> {
79        if field.get_type_name() == "HT_Event" && field.get_name() == "base" {
80            let base_event = std::mem::replace(&mut self.base_event, None);
81            Ok(Value::Struct(base_event.expect(
82                "Base event must be provided for non-base events.",
83            )))
84        } else if let Some(klass) = self.registry.get_klass_by_name(field.get_type_name()) {
85            match self.read_event_internal(klass) {
86                Ok(value) => Ok(Value::Struct(value)),
87                Err(err) => Err(err),
88            }
89        } else {
90            Err(ReadEventError::UnknownKlass(field.get_type_name().clone()))
91        }
92    }
93
94    fn read_string(&mut self) -> Result<Value, ReadEventError> {
95        match self.data_provider.read_string() {
96            Ok(data) => Ok(Value::Str(data)),
97            Err(err) => Err(ReadEventError::DataError(err)),
98        }
99    }
100}
101
102#[cfg(test)]
103mod tests {
104    use super::*;
105    use hawktracer_parser_test_utilities::FakeDataReader;
106
107    fn value_from_bytes(buff: Vec<u8>, data_type: DataType) -> Value {
108        let mut data_provider = DataProvider::new(Box::new(FakeDataReader::new(buff, false)));
109        let klass = EventKlass::new(99, "foo".to_owned());
110        DataStructReader::new(&mut data_provider, &EventKlassRegistry::new(), &klass, None)
111            .read_field(&EventKlassField::new(
112                "foo".to_owned(),
113                "bar".to_owned(),
114                data_type,
115            ))
116            .unwrap()
117    }
118
119    #[test]
120    fn read_field_value() {
121        assert_eq!(value_from_bytes(vec![255], DataType::I8), Value::I8(-1));
122        assert_eq!(value_from_bytes(vec![52], DataType::I8), Value::I8(52));
123        assert_eq!(value_from_bytes(vec![240], DataType::U8), Value::U8(240));
124
125        assert_eq!(value_from_bytes(vec![5, 1], DataType::I16), Value::I16(261));
126        assert_eq!(
127            value_from_bytes(vec![50, 200], DataType::I16),
128            Value::I16(-14286)
129        );
130        assert_eq!(
131            value_from_bytes(vec![240, 52], DataType::U16),
132            Value::U16(13552)
133        );
134
135        assert_eq!(
136            value_from_bytes(vec![10, 16, 42, 169], DataType::I32),
137            Value::I32(-1456861174)
138        );
139        assert_eq!(
140            value_from_bytes(vec![255, 255, 255, 127], DataType::I32),
141            Value::I32(2147483647)
142        );
143        assert_eq!(
144            value_from_bytes(vec![140, 23, 50, 190], DataType::U32),
145            Value::U32(3190953868)
146        );
147
148        assert_eq!(
149            value_from_bytes(vec![253, 255, 255, 255, 255, 255, 255, 255], DataType::I64),
150            Value::I64(-3)
151        );
152        assert_eq!(
153            value_from_bytes(vec![2, 0, 0, 0, 0, 0, 0, 29], DataType::I64),
154            Value::I64(2089670227099910146)
155        );
156        assert_eq!(
157            value_from_bytes(vec![1, 2, 3, 4, 5, 6, 7, 8], DataType::U64),
158            Value::U64(578437695752307201)
159        );
160
161        assert_eq!(
162            value_from_bytes(vec![65, 66, 67, 0], DataType::Str),
163            Value::Str("ABC".to_owned())
164        );
165    }
166
167    #[test]
168    fn data_struct_reader_should_convert_valid_byte_stream_to_event() {
169        let mut child_klass = EventKlass::new(99, "ChildKlass".to_owned());
170        child_klass.add_field("i8_field".to_owned(), "int8_t".to_owned(), DataType::I8);
171
172        let mut klass = EventKlass::new(100, "foo".to_owned());
173        klass.add_field(
174            "child_klass".to_owned(),
175            "ChildKlass".to_owned(),
176            DataType::Struct,
177        );
178        klass.add_field("str_field".to_owned(), "char*".to_owned(), DataType::Str);
179        klass.add_field("u32_field".to_owned(), "uint32_t".to_owned(), DataType::U32);
180
181        let data = vec![
182            128, // -128
183            65, 66, 67, 0, // ABC
184            45, 1, 0, 0, // 301
185        ];
186
187        let mut reg = EventKlassRegistry::new();
188        reg.add_klass(child_klass);
189
190        let mut data_provider = DataProvider::new(Box::new(FakeDataReader::new(data, false)));
191        let mut reader = DataStructReader::new(&mut data_provider, &reg, &klass, None);
192
193        let res = reader.read_event().unwrap();
194        assert_eq!(res.get_klass_id(), 100);
195        match res.get_raw_value(&"child_klass").unwrap() {
196            Value::Struct(event) => {
197                assert_eq!(event.get_raw_value(&"i8_field").unwrap(), &Value::I8(-128))
198            }
199            _ => assert!(false),
200        };
201        assert_eq!(
202            res.get_raw_value(&"str_field").unwrap(),
203            &Value::Str("ABC".to_owned())
204        );
205        assert_eq!(res.get_raw_value(&"u32_field").unwrap(), &Value::U32(301));
206    }
207
208    #[test]
209    fn reader_should_fail_for_invalid_klass() {
210        let mut klass = EventKlass::new(100, "foo".to_owned());
211        klass.add_field(
212            "child_klass".to_owned(),
213            "UnknownKlass".to_owned(),
214            DataType::Struct,
215        );
216
217        let data = vec![
218            128, // -128
219            65, 66, 67, 0, // ABC
220            45, 1, 0, 0, // 301
221        ];
222
223        let reg = EventKlassRegistry::new();
224
225        let mut data_provider = DataProvider::new(Box::new(FakeDataReader::new(data, false)));
226        let mut reader = DataStructReader::new(&mut data_provider, &reg, &klass, None);
227
228        assert_eq!(
229            ReadEventError::UnknownKlass("UnknownKlass".to_owned()),
230            reader.read_event().unwrap_err()
231        );
232    }
233
234    #[test]
235    fn reader_should_fail_for_invalid_string() {
236        let data = vec![65, 66, 67];
237
238        let mut data_provider = DataProvider::new(Box::new(FakeDataReader::new(data, false)));
239        let err = DataStructReader::new(
240            &mut data_provider,
241            &EventKlassRegistry::new(),
242            &EventKlass::new(100, "foo".to_owned()),
243            None,
244        )
245        .read_string()
246        .unwrap_err();
247
248        assert_eq!(ReadEventError::DataError(DataError::EndOfStream), err);
249    }
250}