1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
use crate::data_provider::DataProvider;
use crate::data_struct_reader::{DataStructReader, ReadEventError};
use crate::event::Event;
use crate::registry::{CoreEventKlassId, EventKlassRegistry};
use crate::registry_updater::RegistryUpdater;

pub struct EventReader {
    data_provider: DataProvider,
}

impl EventReader {
    pub fn new(data_provider: DataProvider) -> EventReader {
        EventReader { data_provider }
    }

    pub fn read_event(
        &mut self,
        registry: &mut EventKlassRegistry,
    ) -> Result<Event, ReadEventError> {
        let base_event = self.read_header(registry)?;

        let klass_id = base_event
            .get_value_u32("type")
            .expect("Cannot find 'type' field in base klass. Registry corrupted?");

        if klass_id == CoreEventKlassId::Base as u32 {
            return Ok(base_event);
        }

        let event = self.read_regular_event(registry, klass_id, base_event)?;

        if klass_id == CoreEventKlassId::KlassInfo as u32
            || klass_id == CoreEventKlassId::FieldInfo as u32
        {
            if let Err(err) = RegistryUpdater::new(registry).update_registry_from_event(&event) {
                return Err(ReadEventError::RegistryUpdateFailed(err.to_owned()));
            }
        }

        Ok(event)
    }

    fn read_regular_event(
        &mut self,
        registry: &EventKlassRegistry,
        klass_id: u32,
        base_event: Event,
    ) -> Result<Event, ReadEventError> {
        let klass = match registry.get_klass_by_id(klass_id) {
            Some(klass) => klass,
            None => return Err(ReadEventError::UnknownKlassId(klass_id)),
        };

        DataStructReader::new(&mut self.data_provider, registry, klass, Some(base_event))
            .read_event()
    }

    fn read_header(&mut self, registry: &mut EventKlassRegistry) -> Result<Event, ReadEventError> {
        let base_event_klass = registry
            .get_klass_by_id(CoreEventKlassId::Base as u32)
            .expect("Can not find Base klass definition!");

        DataStructReader::new(&mut self.data_provider, registry, base_event_klass, None)
            .read_event()
    }
}

#[cfg(test)]
pub mod tests {
    use super::*;
    use hawktracer_parser_test_utilities::FakeDataReader;
    use crate::event_klass::EventKlass;
    use crate::event::DataType;

    #[test]
    fn read_header_should_return_valid_base_event() {
        let data = vec![
            1, 0, 0, 0, // type
            1, 2, 0, 0, 0, 0, 0, 0, // timestamp
            2, 0, 0, 0, 0, 0, 0, 0, // id
        ];
        let mut reg = EventKlassRegistry::new();
        let data_provider = DataProvider::new(Box::new(FakeDataReader::new(data, false)));

        let event = EventReader::new(data_provider)
            .read_header(&mut reg)
            .unwrap();

        assert_eq!(event.get_value_u32(&"type").unwrap(), 1);
        assert_eq!(event.get_value_u64(&"timestamp").unwrap(), 513);
        assert_eq!(event.get_value_u64(&"id").unwrap(), 2);
    }


    #[test]
    fn read_event_should_return_full_event() {
        let data = vec![
            100, 0, 0, 0, // type
            1, 2, 0, 0, 0, 0, 0, 0, // timestamp
            2, 0, 0, 0, 0, 0, 0, 0, // id
            65, 66, 67, 0, // ABC
            45, 1, 0, 0, // 301
        ];
        let mut reg = EventKlassRegistry::new();
        let data_provider = DataProvider::new(Box::new(FakeDataReader::new(data, false)));

        let mut klass = EventKlass::new(100, "foo".to_owned());
        klass.add_field("base".to_owned(), "HT_Event".to_owned(), DataType::Struct);
        klass.add_field("str_field".to_owned(), "char*".to_owned(), DataType::Str);
        klass.add_field("u32_field".to_owned(), "uint32_t".to_owned(), DataType::U32);

        reg.add_klass(klass);

        let event = EventReader::new(data_provider)
            .read_event(&mut reg)
            .unwrap();

        assert_eq!(event.get_klass_id(), 100);

        let base_event = event.get_value_struct(&"base").unwrap();
        assert_eq!(base_event.get_value_u32(&"type").unwrap(), 100);
        assert_eq!(base_event.get_value_u64(&"timestamp").unwrap(), 513);
        assert_eq!(base_event.get_value_u64(&"id").unwrap(), 2);

        assert_eq!(event.get_value_string(&"str_field").unwrap(), "ABC");
        assert_eq!(event.get_value_u32(&"u32_field").unwrap(), 301);
    }
}