falco_event/events/
raw_event.rs1use crate::events::payload::PayloadFromBytesError;
2use crate::events::{Event, EventMetadata, EventToBytes};
3use crate::fields::FromBytesError;
4use std::io::Write;
5use std::marker::PhantomData;
6use std::num::TryFromIntError;
7
8pub trait FromRawEvent<'a>: Sized {
9 fn parse(raw_event: &RawEvent<'a>) -> Result<Self, PayloadFromBytesError>;
10}
11
12pub trait LengthField: TryFrom<usize, Error = TryFromIntError> {
13 fn read(buf: &mut &[u8]) -> Option<usize>;
14
15 fn to_usize(&self) -> usize;
16}
17
18impl LengthField for u16 {
19 fn read(buf: &mut &[u8]) -> Option<usize> {
20 let len = buf.split_off(..size_of::<u16>())?;
21 Some(u16::from_ne_bytes(len.try_into().unwrap()) as usize)
22 }
23
24 fn to_usize(&self) -> usize {
25 *self as usize
26 }
27}
28
29impl LengthField for u32 {
30 fn read(buf: &mut &[u8]) -> Option<usize> {
31 let len = buf.split_off(..size_of::<u32>())?;
32 Some(u32::from_ne_bytes(len.try_into().unwrap()) as usize)
33 }
34
35 fn to_usize(&self) -> usize {
36 *self as usize
37 }
38}
39
40pub struct ParamIter<'a, T: LengthField> {
41 lengths: &'a [u8],
42 params: &'a [u8],
43 length_type: PhantomData<T>,
44}
45
46impl<'a, T: LengthField> Iterator for ParamIter<'a, T> {
47 type Item = Result<&'a [u8], FromBytesError>;
48
49 fn next(&mut self) -> Option<Self::Item> {
50 let len = T::read(&mut self.lengths)?;
51 match self.params.split_off(..len) {
52 Some(param) => Some(Ok(param)),
53 None => Some(Err(FromBytesError::TruncatedField {
54 wanted: len,
55 got: self.params.len(),
56 })),
57 }
58 }
59}
60
61#[derive(Debug)]
62pub struct RawEvent<'a> {
63 pub metadata: EventMetadata,
64 pub len: u32,
65 pub event_type: u16,
66 pub nparams: u32,
67 pub payload: &'a [u8],
68}
69
70impl<'e> RawEvent<'e> {
71 fn from_impl(mut buf: &[u8]) -> Option<RawEvent> {
72 let ts_buf = buf.split_off(..8)?;
73 let ts = u64::from_ne_bytes(ts_buf.try_into().unwrap());
74
75 let tid_buf = buf.split_off(..8)?;
76 let tid = i64::from_ne_bytes(tid_buf.try_into().unwrap());
77
78 let len_buf = buf.split_off(..4)?;
79 let len = u32::from_ne_bytes(len_buf.try_into().unwrap());
80
81 let event_type_buf = buf.split_off(..2)?;
82 let event_type = u16::from_ne_bytes(event_type_buf.try_into().unwrap());
83
84 let nparams_buf = buf.split_off(..4)?;
85 let nparams = u32::from_ne_bytes(nparams_buf.try_into().unwrap());
86
87 Some(RawEvent {
88 metadata: EventMetadata { ts, tid },
89 len,
90 event_type,
91 nparams,
92 payload: buf,
93 })
94 }
95
96 pub fn from(buf: &[u8]) -> std::io::Result<RawEvent> {
100 Self::from_impl(buf).ok_or(std::io::ErrorKind::InvalidData.into())
101 }
102
103 pub fn trim(&mut self) -> Option<&'e [u8]> {
130 let payload_len = self.len as usize - 26;
131 self.payload.split_off(payload_len..)
132 }
133
134 pub fn scan(mut buf: &'e [u8]) -> impl Iterator<Item = Result<RawEvent<'e>, std::io::Error>> {
139 std::iter::from_fn(move || {
140 if buf.is_empty() {
141 return None;
142 }
143 match Self::from(buf) {
144 Ok(mut raw_event) => {
145 if let Some(tail) = raw_event.trim() {
146 buf = tail;
147 }
148 Some(Ok(raw_event))
149 }
150
151 Err(err) => Some(Err(err)),
152 }
153 })
154 }
155
156 pub unsafe fn from_ptr<'a>(buf: *const u8) -> std::io::Result<RawEvent<'a>> {
165 let len_buf = unsafe { std::slice::from_raw_parts(buf.offset(16), 4) };
166 let len = u32::from_ne_bytes(len_buf.try_into().unwrap());
167
168 let buf: &'a [u8] = unsafe { std::slice::from_raw_parts(buf, len as usize) };
169 Self::from(buf)
170 }
171
172 pub fn load<'a, T: FromRawEvent<'e>>(&'a self) -> Result<Event<T>, PayloadFromBytesError> {
173 #[allow(clippy::question_mark)]
174 let params = match T::parse(self) {
175 Ok(p) => p,
176 Err(e) => return Err(e),
177 };
178 Ok(Event {
179 metadata: self.metadata.clone(),
180 params,
181 })
182 }
183
184 pub fn params<T: LengthField>(&self) -> Result<ParamIter<'e, T>, PayloadFromBytesError> {
188 let length_size = size_of::<T>();
189 let ll = self.nparams as usize * length_size;
190
191 if self.payload.len() < ll {
192 return Err(PayloadFromBytesError::TruncatedEvent {
193 wanted: ll,
194 got: self.payload.len(),
195 });
196 }
197
198 let (lengths, params) = self.payload.split_at(ll);
199
200 Ok(ParamIter {
201 lengths,
202 params,
203 length_type: PhantomData,
204 })
205 }
206}
207
208impl EventToBytes for RawEvent<'_> {
209 fn binary_size(&self) -> usize {
210 self.len as usize
211 }
212
213 fn write<W: Write>(&self, mut writer: W) -> std::io::Result<()> {
214 self.metadata
215 .write_header(self.len, self.event_type, self.nparams, &mut writer)?;
216 writer.write_all(self.payload)
217 }
218}