genet_abi/
decoder.rs

1use context::Context;
2use error::Error;
3use fixed::MutFixed;
4use layer::{Layer, LayerStack, Parent};
5use result::Result;
6use std::ptr;
7
8/// Execution type.
9#[repr(u8)]
10#[derive(Clone, PartialEq, Debug)]
11pub enum ExecType {
12    ParallelSync = 0,
13    SerialSync = 1,
14    SerialAsync = 2,
15}
16
17/// Dissection status.
18#[derive(Debug)]
19pub enum Status {
20    Done,
21    Skip,
22}
23
24/// Decoder worker trait.
25pub trait Worker {
26    fn decode(&mut self, &mut Context, &LayerStack, &mut Parent) -> Result<Status>;
27}
28
29#[repr(C)]
30pub struct WorkerBox {
31    decode: extern "C" fn(
32        *mut WorkerBox,
33        *mut Context,
34        *const *const Layer,
35        u64,
36        *mut Parent,
37        *mut Error,
38    ) -> u8,
39    worker: *mut Box<Worker>,
40}
41
42impl WorkerBox {
43    fn new(worker: Box<Worker>) -> WorkerBox {
44        Self {
45            decode: abi_decode,
46            worker: Box::into_raw(Box::new(worker)),
47        }
48    }
49
50    pub fn decode(
51        &mut self,
52        ctx: &mut Context,
53        layers: &[MutFixed<Layer>],
54        layer: &mut Parent,
55    ) -> Result<bool> {
56        let stack = layers.as_ptr() as *const *const Layer;
57        let mut error = Error::new("");
58        let result = (self.decode)(self, ctx, stack, layers.len() as u64, layer, &mut error);
59        match result {
60            2 => Ok(true),
61            1 => Ok(false),
62            _ => Err(Box::new(error)),
63        }
64    }
65}
66
67extern "C" fn abi_decode(
68    worker: *mut WorkerBox,
69    ctx: *mut Context,
70    layers: *const *const Layer,
71    len: u64,
72    layer: *mut Parent,
73    error: *mut Error,
74) -> u8 {
75    let worker = unsafe { &mut *((*worker).worker) };
76    let ctx = unsafe { &mut (*ctx) };
77    let mut layer = unsafe { &mut *layer };
78    let stack = unsafe { LayerStack::new(layers, len as usize) };
79    match worker.decode(ctx, &stack, &mut layer) {
80        Ok(stat) => match stat {
81            Status::Done => 2,
82            Status::Skip => 1,
83        },
84        Err(err) => {
85            unsafe {
86                ptr::write(error, Error::new(err.description()));
87            }
88            0
89        }
90    }
91}
92
93/// Decoder trait.
94pub trait Decoder: DecoderClone + Send {
95    fn new_worker(&self, &Context) -> Box<Worker>;
96    fn execution_type(&self) -> ExecType;
97}
98
99pub trait DecoderClone {
100    fn clone_box(&self) -> Box<Decoder>;
101    fn into_box(self) -> Box<Decoder>;
102}
103
104impl<T> DecoderClone for T
105where
106    T: 'static + Decoder + Clone,
107{
108    fn clone_box(&self) -> Box<Decoder> {
109        Box::new(self.clone())
110    }
111
112    fn into_box(self) -> Box<Decoder> {
113        Box::new(self)
114    }
115}
116
117impl Clone for Box<Decoder> {
118    fn clone(&self) -> Box<Decoder> {
119        self.clone_box()
120    }
121}
122
123#[repr(C)]
124#[derive(Clone, Copy)]
125pub struct DecoderBox {
126    new_worker: extern "C" fn(*mut DecoderBox, *const Context) -> WorkerBox,
127    execution_type: extern "C" fn(*const DecoderBox) -> u8,
128    decoder: *mut Box<Decoder>,
129}
130
131unsafe impl Send for DecoderBox {}
132
133impl DecoderBox {
134    pub fn new<T: 'static + Decoder>(diss: T) -> DecoderBox {
135        let diss: Box<Decoder> = Box::new(diss);
136        Self {
137            new_worker: abi_new_worker,
138            execution_type: abi_execution_type,
139            decoder: Box::into_raw(Box::new(diss)),
140        }
141    }
142
143    pub fn new_worker(&mut self, ctx: &Context) -> WorkerBox {
144        (self.new_worker)(self, ctx)
145    }
146
147    pub fn execution_type(&self) -> ExecType {
148        match (self.execution_type)(self) {
149            1 => ExecType::SerialSync,
150            2 => ExecType::SerialAsync,
151            _ => ExecType::ParallelSync,
152        }
153    }
154}
155
156extern "C" fn abi_new_worker(diss: *mut DecoderBox, ctx: *const Context) -> WorkerBox {
157    let diss = unsafe { &mut *((*diss).decoder) };
158    let ctx = unsafe { &(*ctx) };
159    WorkerBox::new(diss.new_worker(ctx))
160}
161
162extern "C" fn abi_execution_type(diss: *const DecoderBox) -> u8 {
163    let diss = unsafe { &*((*diss).decoder) };
164    diss.execution_type() as u8
165}
166
167#[cfg(test)]
168mod tests {
169    use context::Context;
170    use decoder::{Decoder, DecoderBox, ExecType, Status, Worker};
171    use fixed::Fixed;
172    use fnv::FnvHashMap;
173    use layer::{Layer, LayerClass, LayerStack, Parent};
174    use result::Result;
175    use slice::ByteSlice;
176    use token::Token;
177
178    #[test]
179    fn decode() {
180        struct TestWorker {}
181
182        impl Worker for TestWorker {
183            fn decode(
184                &mut self,
185                _ctx: &mut Context,
186                _stack: &LayerStack,
187                parent: &mut Parent,
188            ) -> Result<Status> {
189                let class = Fixed::new(LayerClass::builder(Token::from(1234)).build());
190                let layer = Layer::new(class, ByteSlice::new());
191                parent.add_child(layer);
192                Ok(Status::Done)
193            }
194        }
195
196        #[derive(Clone)]
197        struct TestDecoder {}
198
199        impl Decoder for TestDecoder {
200            fn new_worker(&self, _ctx: &Context) -> Box<Worker> {
201                Box::new(TestWorker {})
202            }
203
204            fn execution_type(&self) -> ExecType {
205                ExecType::ParallelSync
206            }
207        }
208
209        let mut ctx = Context::new(FnvHashMap::default());
210        let mut diss = DecoderBox::new(TestDecoder {});
211        let mut worker = diss.new_worker(&ctx);
212
213        let class = Fixed::new(LayerClass::builder(Token::null()).build());
214        let mut layer = Layer::new(class, ByteSlice::new());
215        let mut layer = Parent::from_mut_ref(&mut layer);
216
217        assert_eq!(worker.decode(&mut ctx, &[], &mut layer).unwrap(), true);
218    }
219}