falco_event/events/
raw_event.rs1use crate::events::payload::PayloadFromBytesError;
2use crate::events::{AnyEventPayload, Event, EventMetadata, EventToBytes};
3use crate::fields::{FromBytes, 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
61impl<'a, T: LengthField> ParamIter<'a, T> {
62 #[inline]
63 pub fn next_field<U>(&mut self) -> Result<U, FromBytesError>
64 where
65 U: FromBytes<'a>,
66 {
67 let mut maybe_next_field = self.next().transpose()?;
68 let val = FromBytes::from_maybe_bytes(maybe_next_field.as_mut())?;
69 if let Some(buf) = maybe_next_field {
70 if !buf.is_empty() {
71 return Err(FromBytesError::LeftoverData);
72 }
73 }
74
75 Ok(val)
76 }
77}
78
79#[derive(Debug)]
80pub struct RawEvent<'a> {
81 pub metadata: EventMetadata,
82 pub len: u32,
83 pub event_type: u16,
84 pub nparams: u32,
85 pub payload: &'a [u8],
86}
87
88impl<'e> RawEvent<'e> {
89 fn from_impl(mut buf: &[u8]) -> Option<RawEvent<'_>> {
90 let ts_buf = buf.split_off(..8)?;
91 let ts = u64::from_ne_bytes(ts_buf.try_into().unwrap());
92
93 let tid_buf = buf.split_off(..8)?;
94 let tid = i64::from_ne_bytes(tid_buf.try_into().unwrap());
95
96 let len_buf = buf.split_off(..4)?;
97 let len = u32::from_ne_bytes(len_buf.try_into().unwrap());
98
99 let event_type_buf = buf.split_off(..2)?;
100 let event_type = u16::from_ne_bytes(event_type_buf.try_into().unwrap());
101
102 let nparams_buf = buf.split_off(..4)?;
103 let nparams = u32::from_ne_bytes(nparams_buf.try_into().unwrap());
104
105 Some(RawEvent {
106 metadata: EventMetadata { ts, tid },
107 len,
108 event_type,
109 nparams,
110 payload: buf,
111 })
112 }
113
114 pub fn from(buf: &[u8]) -> std::io::Result<RawEvent<'_>> {
118 Self::from_impl(buf).ok_or(std::io::ErrorKind::InvalidData.into())
119 }
120
121 pub fn trim(&mut self) -> Option<&'e [u8]> {
148 let payload_len = self.len as usize - 26;
149 self.payload.split_off(payload_len..)
150 }
151
152 pub fn scan(mut buf: &'e [u8]) -> impl Iterator<Item = Result<RawEvent<'e>, std::io::Error>> {
157 std::iter::from_fn(move || {
158 if buf.is_empty() {
159 return None;
160 }
161 match Self::from(buf) {
162 Ok(mut raw_event) => {
163 if let Some(tail) = raw_event.trim() {
164 buf = tail;
165 }
166 Some(Ok(raw_event))
167 }
168
169 Err(err) => Some(Err(err)),
170 }
171 })
172 }
173
174 pub unsafe fn from_ptr<'a>(buf: *const u8) -> std::io::Result<RawEvent<'a>> {
183 let len_buf = unsafe { std::slice::from_raw_parts(buf.offset(16), 4) };
184 let len = u32::from_ne_bytes(len_buf.try_into().unwrap());
185
186 let buf: &'a [u8] = unsafe { std::slice::from_raw_parts(buf, len as usize) };
187 Self::from(buf)
188 }
189
190 pub fn load<'a, T: FromRawEvent<'e>>(&'a self) -> Result<Event<T>, PayloadFromBytesError> {
191 #[allow(clippy::question_mark)]
192 let params = match T::parse(self) {
193 Ok(p) => p,
194 Err(e) => return Err(e),
195 };
196 Ok(Event {
197 metadata: self.metadata.clone(),
198 params,
199 })
200 }
201
202 pub fn params<T: LengthField>(&self) -> Result<ParamIter<'e, T>, PayloadFromBytesError> {
206 let length_size = size_of::<T>();
207 let ll = self.nparams as usize * length_size;
208
209 if self.payload.len() < ll {
210 return Err(PayloadFromBytesError::TruncatedEvent {
211 wanted: ll,
212 got: self.payload.len(),
213 });
214 }
215
216 let (lengths, params) = self.payload.split_at(ll);
217
218 Ok(ParamIter {
219 lengths,
220 params,
221 length_type: PhantomData,
222 })
223 }
224}
225
226impl<'a, 'b> From<&'a RawEvent<'b>> for RawEvent<'b> {
227 fn from(event: &'a RawEvent<'b>) -> Self {
228 Self {
229 metadata: event.metadata.clone(),
230 len: event.len,
231 event_type: event.event_type,
232 nparams: event.nparams,
233 payload: event.payload,
234 }
235 }
236}
237
238impl EventToBytes for RawEvent<'_> {
239 fn binary_size(&self) -> usize {
240 self.len as usize
241 }
242
243 fn write<W: Write>(&self, mut writer: W) -> std::io::Result<()> {
244 self.metadata
245 .write_header(self.len, self.event_type, self.nparams, &mut writer)?;
246 writer.write_all(self.payload)
247 }
248}
249
250impl AnyEventPayload for RawEvent<'_> {
251 const SOURCES: &'static [Option<&'static str>] = &[];
252 const EVENT_TYPES: &'static [u16] = &[];
253}