1use context::Context;
2use error::Error;
3use fixed::MutFixed;
4use layer::{Layer, LayerStack, Parent};
5use result::Result;
6use std::ptr;
7
8#[repr(u8)]
10#[derive(Clone, PartialEq, Debug)]
11pub enum ExecType {
12 ParallelSync = 0,
13 SerialSync = 1,
14 SerialAsync = 2,
15}
16
17#[derive(Debug)]
19pub enum Status {
20 Done,
21 Skip,
22}
23
24pub 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
93pub 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}