falco_plugin/plugin/tables/vtable/
reader.rs1use crate::plugin::error::last_error::LastError;
2use crate::plugin::tables::vtable::TableError;
3use crate::plugin::tables::vtable::TableError::BadVtable;
4use falco_plugin_api::{
5 ss_plugin_bool, ss_plugin_rc, ss_plugin_state_data, ss_plugin_table_entry_t,
6 ss_plugin_table_field_t, ss_plugin_table_iterator_func_t, ss_plugin_table_iterator_state_t,
7 ss_plugin_table_reader_vtable_ext, ss_plugin_table_t,
8};
9use std::marker::PhantomData;
10
11pub trait TableReader: private::TableReaderImpl {}
16
17impl<T: private::TableReaderImpl> TableReader for T {}
18
19pub(crate) mod private {
20 use super::*;
21 pub trait TableReaderImpl {
22 type Error: std::error::Error + Send + Sync + 'static;
23
24 unsafe fn get_table_name(
25 &self,
26 t: *mut ss_plugin_table_t,
27 ) -> Result<*const ::std::os::raw::c_char, Self::Error>;
28
29 unsafe fn get_table_size(&self, t: *mut ss_plugin_table_t) -> Result<u64, Self::Error>;
30
31 unsafe fn get_table_entry(
32 &self,
33 t: *mut ss_plugin_table_t,
34 key: *const ss_plugin_state_data,
35 ) -> Result<*mut ss_plugin_table_entry_t, Self::Error>;
36
37 unsafe fn read_entry_field(
38 &self,
39 t: *mut ss_plugin_table_t,
40 e: *mut ss_plugin_table_entry_t,
41 f: *const ss_plugin_table_field_t,
42 out: *mut ss_plugin_state_data,
43 ) -> Result<ss_plugin_rc, Self::Error>;
44
45 fn release_table_entry_fn(
46 &self,
47 ) -> Option<
48 unsafe extern "C-unwind" fn(t: *mut ss_plugin_table_t, e: *mut ss_plugin_table_entry_t),
49 >;
50
51 fn iterate_entries_fn(
52 &self,
53 ) -> Result<
54 unsafe extern "C-unwind" fn(
55 t: *mut ss_plugin_table_t,
56 it: ss_plugin_table_iterator_func_t,
57 s: *mut ss_plugin_table_iterator_state_t,
58 ) -> ss_plugin_bool,
59 Self::Error,
60 >;
61
62 fn last_error(&self) -> &LastError;
63 }
64}
65
66#[derive(Debug)]
71pub struct LazyTableReader<'t> {
72 reader_ext: &'t ss_plugin_table_reader_vtable_ext,
73 pub(in crate::plugin::tables) last_error: LastError,
74}
75
76impl<'t> LazyTableReader<'t> {
77 pub(crate) fn new(
78 reader_ext: &'t ss_plugin_table_reader_vtable_ext,
79 last_error: LastError,
80 ) -> Self {
81 LazyTableReader {
82 reader_ext,
83 last_error,
84 }
85 }
86
87 pub fn validate(&self) -> Result<ValidatedTableReader, TableError> {
94 Ok(ValidatedTableReader {
95 get_table_name: self
96 .reader_ext
97 .get_table_name
98 .ok_or(BadVtable("get_table_name"))?,
99 get_table_size: self
100 .reader_ext
101 .get_table_size
102 .ok_or(BadVtable("get_table_size"))?,
103 get_table_entry: self
104 .reader_ext
105 .get_table_entry
106 .ok_or(BadVtable("get_table_entry"))?,
107 read_entry_field: self
108 .reader_ext
109 .read_entry_field
110 .ok_or(BadVtable("read_entry_field"))?,
111 release_table_entry: self
112 .reader_ext
113 .release_table_entry
114 .ok_or(BadVtable("release_table_entry"))?,
115 iterate_entries: self
116 .reader_ext
117 .iterate_entries
118 .ok_or(BadVtable("iterate_entries"))?,
119 last_error: self.last_error.clone(),
120 lifetime: PhantomData,
121 })
122 }
123}
124
125impl private::TableReaderImpl for LazyTableReader<'_> {
126 type Error = TableError;
127
128 unsafe fn get_table_name(
129 &self,
130 t: *mut ss_plugin_table_t,
131 ) -> Result<*const ::std::os::raw::c_char, Self::Error> {
132 Ok(unsafe {
133 self.reader_ext
134 .get_table_name
135 .ok_or(BadVtable("get_table_name"))?(t)
136 })
137 }
138
139 unsafe fn get_table_size(&self, t: *mut ss_plugin_table_t) -> Result<u64, Self::Error> {
140 Ok(unsafe {
141 self.reader_ext
142 .get_table_size
143 .ok_or(BadVtable("get_table_size"))?(t)
144 })
145 }
146
147 unsafe fn get_table_entry(
148 &self,
149 t: *mut ss_plugin_table_t,
150 key: *const ss_plugin_state_data,
151 ) -> Result<*mut ss_plugin_table_entry_t, Self::Error> {
152 Ok(unsafe {
153 self.reader_ext
154 .get_table_entry
155 .ok_or(BadVtable("get_table_entry"))?(t, key)
156 })
157 }
158
159 unsafe fn read_entry_field(
160 &self,
161 t: *mut ss_plugin_table_t,
162 e: *mut ss_plugin_table_entry_t,
163 f: *const ss_plugin_table_field_t,
164 out: *mut ss_plugin_state_data,
165 ) -> Result<ss_plugin_rc, Self::Error> {
166 Ok(unsafe {
167 self.reader_ext
168 .read_entry_field
169 .ok_or(BadVtable("read_entry_field"))?(t, e, f, out)
170 })
171 }
172
173 fn release_table_entry_fn(
174 &self,
175 ) -> Option<
176 unsafe extern "C-unwind" fn(t: *mut ss_plugin_table_t, e: *mut ss_plugin_table_entry_t),
177 > {
178 self.reader_ext.release_table_entry
179 }
180
181 fn iterate_entries_fn(
182 &self,
183 ) -> Result<
184 unsafe extern "C-unwind" fn(
185 t: *mut ss_plugin_table_t,
186 it: ss_plugin_table_iterator_func_t,
187 s: *mut ss_plugin_table_iterator_state_t,
188 ) -> ss_plugin_bool,
189 TableError,
190 > {
191 self.reader_ext
192 .iterate_entries
193 .ok_or(BadVtable("iterate_entries"))
194 }
195
196 fn last_error(&self) -> &LastError {
197 &self.last_error
198 }
199}
200
201#[derive(Debug)]
206pub struct ValidatedTableReader<'t> {
207 pub(in crate::plugin::tables) get_table_name:
208 unsafe extern "C-unwind" fn(t: *mut ss_plugin_table_t) -> *const ::std::os::raw::c_char,
209 pub(in crate::plugin::tables) get_table_size:
210 unsafe extern "C-unwind" fn(t: *mut ss_plugin_table_t) -> u64,
211 pub(in crate::plugin::tables) get_table_entry:
212 unsafe extern "C-unwind" fn(
213 t: *mut ss_plugin_table_t,
214 key: *const ss_plugin_state_data,
215 ) -> *mut ss_plugin_table_entry_t,
216 pub(in crate::plugin::tables) read_entry_field: unsafe extern "C-unwind" fn(
217 t: *mut ss_plugin_table_t,
218 e: *mut ss_plugin_table_entry_t,
219 f: *const ss_plugin_table_field_t,
220 out: *mut ss_plugin_state_data,
221 )
222 -> ss_plugin_rc,
223 pub(in crate::plugin::tables) release_table_entry:
224 unsafe extern "C-unwind" fn(t: *mut ss_plugin_table_t, e: *mut ss_plugin_table_entry_t),
225 pub(in crate::plugin::tables) iterate_entries: unsafe extern "C-unwind" fn(
226 t: *mut ss_plugin_table_t,
227 it: ss_plugin_table_iterator_func_t,
228 s: *mut ss_plugin_table_iterator_state_t,
229 )
230 -> ss_plugin_bool,
231
232 pub(in crate::plugin::tables) last_error: LastError,
233 lifetime: PhantomData<&'t ()>,
234}
235
236impl private::TableReaderImpl for ValidatedTableReader<'_> {
237 type Error = std::convert::Infallible;
238
239 unsafe fn get_table_name(
240 &self,
241 t: *mut ss_plugin_table_t,
242 ) -> Result<*const ::std::os::raw::c_char, Self::Error> {
243 unsafe { Ok((self.get_table_name)(t)) }
244 }
245
246 unsafe fn get_table_size(&self, t: *mut ss_plugin_table_t) -> Result<u64, Self::Error> {
247 unsafe { Ok((self.get_table_size)(t)) }
248 }
249
250 unsafe fn get_table_entry(
251 &self,
252 t: *mut ss_plugin_table_t,
253 key: *const ss_plugin_state_data,
254 ) -> Result<*mut ss_plugin_table_entry_t, Self::Error> {
255 unsafe { Ok((self.get_table_entry)(t, key)) }
256 }
257
258 unsafe fn read_entry_field(
259 &self,
260 t: *mut ss_plugin_table_t,
261 e: *mut ss_plugin_table_entry_t,
262 f: *const ss_plugin_table_field_t,
263 out: *mut ss_plugin_state_data,
264 ) -> Result<ss_plugin_rc, Self::Error> {
265 unsafe { Ok((self.read_entry_field)(t, e, f, out)) }
266 }
267
268 fn release_table_entry_fn(
269 &self,
270 ) -> Option<unsafe extern "C-unwind" fn(*mut ss_plugin_table_t, *mut ss_plugin_table_entry_t)>
271 {
272 Some(self.release_table_entry)
273 }
274
275 fn iterate_entries_fn(
276 &self,
277 ) -> Result<
278 unsafe extern "C-unwind" fn(
279 *mut ss_plugin_table_t,
280 ss_plugin_table_iterator_func_t,
281 *mut ss_plugin_table_iterator_state_t,
282 ) -> ss_plugin_bool,
283 Self::Error,
284 > {
285 Ok(self.iterate_entries)
286 }
287
288 fn last_error(&self) -> &LastError {
289 &self.last_error
290 }
291}