falco_plugin/tables/vtable/
reader.rs1use crate::error::last_error::LastError;
2use crate::tables::vtable::TableError;
3use crate::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(crate) 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(crate) get_table_name:
208 unsafe extern "C-unwind" fn(t: *mut ss_plugin_table_t) -> *const ::std::os::raw::c_char,
209 pub(crate) get_table_size: unsafe extern "C-unwind" fn(t: *mut ss_plugin_table_t) -> u64,
210 pub(crate) get_table_entry: unsafe extern "C-unwind" fn(
211 t: *mut ss_plugin_table_t,
212 key: *const ss_plugin_state_data,
213 ) -> *mut ss_plugin_table_entry_t,
214 pub(crate) read_entry_field: unsafe extern "C-unwind" fn(
215 t: *mut ss_plugin_table_t,
216 e: *mut ss_plugin_table_entry_t,
217 f: *const ss_plugin_table_field_t,
218 out: *mut ss_plugin_state_data,
219 ) -> ss_plugin_rc,
220 pub(crate) release_table_entry:
221 unsafe extern "C-unwind" fn(t: *mut ss_plugin_table_t, e: *mut ss_plugin_table_entry_t),
222 pub(crate) iterate_entries: unsafe extern "C-unwind" fn(
223 t: *mut ss_plugin_table_t,
224 it: ss_plugin_table_iterator_func_t,
225 s: *mut ss_plugin_table_iterator_state_t,
226 ) -> ss_plugin_bool,
227
228 pub(crate) last_error: LastError,
229 lifetime: PhantomData<&'t ()>,
230}
231
232impl private::TableReaderImpl for ValidatedTableReader<'_> {
233 type Error = std::convert::Infallible;
234
235 unsafe fn get_table_name(
236 &self,
237 t: *mut ss_plugin_table_t,
238 ) -> Result<*const ::std::os::raw::c_char, Self::Error> {
239 unsafe { Ok((self.get_table_name)(t)) }
240 }
241
242 unsafe fn get_table_size(&self, t: *mut ss_plugin_table_t) -> Result<u64, Self::Error> {
243 unsafe { Ok((self.get_table_size)(t)) }
244 }
245
246 unsafe fn get_table_entry(
247 &self,
248 t: *mut ss_plugin_table_t,
249 key: *const ss_plugin_state_data,
250 ) -> Result<*mut ss_plugin_table_entry_t, Self::Error> {
251 unsafe { Ok((self.get_table_entry)(t, key)) }
252 }
253
254 unsafe fn read_entry_field(
255 &self,
256 t: *mut ss_plugin_table_t,
257 e: *mut ss_plugin_table_entry_t,
258 f: *const ss_plugin_table_field_t,
259 out: *mut ss_plugin_state_data,
260 ) -> Result<ss_plugin_rc, Self::Error> {
261 unsafe { Ok((self.read_entry_field)(t, e, f, out)) }
262 }
263
264 fn release_table_entry_fn(
265 &self,
266 ) -> Option<unsafe extern "C-unwind" fn(*mut ss_plugin_table_t, *mut ss_plugin_table_entry_t)>
267 {
268 Some(self.release_table_entry)
269 }
270
271 fn iterate_entries_fn(
272 &self,
273 ) -> Result<
274 unsafe extern "C-unwind" fn(
275 *mut ss_plugin_table_t,
276 ss_plugin_table_iterator_func_t,
277 *mut ss_plugin_table_iterator_state_t,
278 ) -> ss_plugin_bool,
279 Self::Error,
280 > {
281 Ok(self.iterate_entries)
282 }
283
284 fn last_error(&self) -> &LastError {
285 &self.last_error
286 }
287}