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 {
10 fn parse(raw_event: &RawEvent<'a>) -> Result<Self, PayloadFromBytesError>;
12}
13
14pub trait LengthField: TryFrom<usize, Error = TryFromIntError> {
15 fn read(buf: &mut &[u8]) -> Option<usize>;
16
17 fn to_usize(&self) -> usize;
18}
19
20impl LengthField for u16 {
21 #[inline]
22 fn read(buf: &mut &[u8]) -> Option<usize> {
23 let len = buf.split_off(..size_of::<u16>())?;
24 Some(u16::from_ne_bytes(len.try_into().unwrap()) as usize)
25 }
26
27 #[inline]
28 fn to_usize(&self) -> usize {
29 *self as usize
30 }
31}
32
33impl LengthField for u32 {
34 #[inline]
35 fn read(buf: &mut &[u8]) -> Option<usize> {
36 let len = buf.split_off(..size_of::<u32>())?;
37 Some(u32::from_ne_bytes(len.try_into().unwrap()) as usize)
38 }
39
40 #[inline]
41 fn to_usize(&self) -> usize {
42 *self as usize
43 }
44}
45
46pub struct ParamIter<'a, T: LengthField> {
53 lengths: &'a [u8],
54 params: &'a [u8],
55 length_type: PhantomData<T>,
56}
57
58impl<'a, T: LengthField> Iterator for ParamIter<'a, T> {
59 type Item = Result<&'a [u8], FromBytesError>;
60
61 #[inline]
62 fn next(&mut self) -> Option<Self::Item> {
63 let len = T::read(&mut self.lengths)?;
64 match self.params.split_off(..len) {
65 Some(param) => Some(Ok(param)),
66 None => Some(Err(FromBytesError::TruncatedField {
67 wanted: len,
68 got: self.params.len(),
69 })),
70 }
71 }
72}
73
74impl<'a, T: LengthField> ParamIter<'a, T> {
75 #[inline]
77 pub fn next_field<U>(&mut self) -> Result<U, FromBytesError>
78 where
79 U: FromBytes<'a>,
80 {
81 let mut maybe_next_field = self.next().transpose()?;
82 let val = FromBytes::from_maybe_bytes(maybe_next_field.as_mut())?;
83 if let Some(buf) = maybe_next_field {
84 if !buf.is_empty() {
85 return Err(FromBytesError::LeftoverData);
86 }
87 }
88
89 Ok(val)
90 }
91}
92
93#[derive(Debug)]
99pub struct RawEvent<'a> {
100 pub metadata: EventMetadata,
102
103 pub len: u32,
105
106 pub event_type: u16,
108
109 pub nparams: u32,
111
112 pub payload: &'a [u8],
117}
118
119impl<'e> RawEvent<'e> {
120 #[inline]
121 fn from_impl(mut buf: &[u8]) -> Option<RawEvent<'_>> {
122 let ts_buf = buf.split_off(..8)?;
123 let ts = u64::from_ne_bytes(ts_buf.try_into().unwrap());
124
125 let tid_buf = buf.split_off(..8)?;
126 let tid = i64::from_ne_bytes(tid_buf.try_into().unwrap());
127
128 let len_buf = buf.split_off(..4)?;
129 let len = u32::from_ne_bytes(len_buf.try_into().unwrap());
130
131 let event_type_buf = buf.split_off(..2)?;
132 let event_type = u16::from_ne_bytes(event_type_buf.try_into().unwrap());
133
134 let nparams_buf = buf.split_off(..4)?;
135 let nparams = u32::from_ne_bytes(nparams_buf.try_into().unwrap());
136
137 Some(RawEvent {
138 metadata: EventMetadata { ts, tid },
139 len,
140 event_type,
141 nparams,
142 payload: buf,
143 })
144 }
145
146 #[inline]
150 pub fn from(buf: &[u8]) -> std::io::Result<RawEvent<'_>> {
151 Self::from_impl(buf).ok_or(std::io::ErrorKind::InvalidData.into())
152 }
153
154 #[inline]
181 pub fn trim(&mut self) -> Option<&'e [u8]> {
182 let payload_len = self.len as usize - 26;
183 self.payload.split_off(payload_len..)
184 }
185
186 #[inline]
191 pub fn scan(mut buf: &'e [u8]) -> impl Iterator<Item = Result<RawEvent<'e>, std::io::Error>> {
192 std::iter::from_fn(move || {
193 if buf.is_empty() {
194 return None;
195 }
196 match Self::from(buf) {
197 Ok(mut raw_event) => {
198 if let Some(tail) = raw_event.trim() {
199 buf = tail;
200 }
201 Some(Ok(raw_event))
202 }
203
204 Err(err) => Some(Err(err)),
205 }
206 })
207 }
208
209 #[inline]
218 pub unsafe fn from_ptr<'a>(buf: *const u8) -> std::io::Result<RawEvent<'a>> {
219 let len_buf = unsafe { std::slice::from_raw_parts(buf.offset(16), 4) };
220 let len = u32::from_ne_bytes(len_buf.try_into().unwrap());
221
222 let buf: &'a [u8] = unsafe { std::slice::from_raw_parts(buf, len as usize) };
223 Self::from(buf)
224 }
225
226 #[inline]
231 pub fn load<'a, T: FromRawEvent<'e>>(&'a self) -> Result<Event<T>, PayloadFromBytesError> {
232 #[allow(clippy::question_mark)]
233 let params = match T::parse(self) {
234 Ok(p) => p,
235 Err(e) => return Err(e),
236 };
237 Ok(Event {
238 metadata: self.metadata.clone(),
239 params,
240 })
241 }
242
243 #[inline]
247 pub fn params<T: LengthField>(&self) -> Result<ParamIter<'e, T>, PayloadFromBytesError> {
248 let length_size = size_of::<T>();
249 let ll = self.nparams as usize * length_size;
250
251 if self.payload.len() < ll {
252 return Err(PayloadFromBytesError::TruncatedEvent {
253 wanted: ll,
254 got: self.payload.len(),
255 });
256 }
257
258 let (lengths, params) = self.payload.split_at(ll);
259
260 Ok(ParamIter {
261 lengths,
262 params,
263 length_type: PhantomData,
264 })
265 }
266}
267
268impl<'a, 'b> From<&'a RawEvent<'b>> for RawEvent<'b> {
269 #[inline]
270 fn from(event: &'a RawEvent<'b>) -> Self {
271 Self {
272 metadata: event.metadata.clone(),
273 len: event.len,
274 event_type: event.event_type,
275 nparams: event.nparams,
276 payload: event.payload,
277 }
278 }
279}
280
281impl EventToBytes for RawEvent<'_> {
282 #[inline]
283 fn binary_size(&self) -> usize {
284 self.len as usize
285 }
286
287 #[inline]
288 fn write<W: Write>(&self, mut writer: W) -> std::io::Result<()> {
289 self.metadata
290 .write_header(self.len, self.event_type, self.nparams, &mut writer)?;
291 writer.write_all(self.payload)
292 }
293}
294
295impl AnyEventPayload for RawEvent<'_> {
296 const SOURCES: &'static [Option<&'static str>] = &[];
297 const EVENT_TYPES: &'static [u16] = &[];
298}