genet_abi/
io.rs

1use context::Context;
2use error::Error;
3use fixed::MutFixed;
4use layer::{Layer, LayerStack};
5use result::Result;
6use std::{fmt, mem, ptr};
7use string::SafeString;
8use vec::SafeVec;
9
10/// Writer trait.
11pub trait Writer: Send {
12    fn new_worker(&self, ctx: &Context, args: &str) -> Result<Box<WriterWorker>>;
13    fn id(&self) -> &str;
14}
15
16#[repr(C)]
17#[derive(Clone, Copy)]
18pub struct WriterBox {
19    writer: *mut Box<Writer>,
20    id: extern "C" fn(*mut Box<Writer>) -> SafeString,
21    new_worker: extern "C" fn(
22        *mut Box<Writer>,
23        *const Context,
24        SafeString,
25        *mut WriterWorkerBox,
26        *mut Error,
27    ) -> u8,
28}
29
30unsafe impl Send for WriterBox {}
31
32impl WriterBox {
33    pub fn new<T: 'static + Writer>(writer: T) -> WriterBox {
34        let writer: Box<Writer> = Box::new(writer);
35        Self {
36            writer: Box::into_raw(Box::new(writer)),
37            id: abi_writer_id,
38            new_worker: abi_writer_new_worker,
39        }
40    }
41
42    pub fn id(&self) -> SafeString {
43        (self.id)(self.writer)
44    }
45
46    pub fn new_worker(&self, ctx: &Context, args: &str) -> Result<WriterWorkerBox> {
47        let mut out: WriterWorkerBox = unsafe { mem::uninitialized() };
48        let mut err = Error::new("");
49        if (self.new_worker)(self.writer, ctx, SafeString::from(args), &mut out, &mut err) == 1 {
50            Ok(out)
51        } else {
52            mem::forget(out);
53            Err(Box::new(err))
54        }
55    }
56}
57
58extern "C" fn abi_writer_id(writer: *mut Box<Writer>) -> SafeString {
59    SafeString::from(unsafe { (*writer).id() })
60}
61
62extern "C" fn abi_writer_new_worker(
63    writer: *mut Box<Writer>,
64    ctx: *const Context,
65    arg: SafeString,
66    out: *mut WriterWorkerBox,
67    err: *mut Error,
68) -> u8 {
69    let writer = unsafe { &*writer };
70    let ctx = unsafe { &*ctx };
71    match writer.new_worker(ctx, arg.as_str()) {
72        Ok(worker) => {
73            unsafe { ptr::write(out, WriterWorkerBox::new(worker)) };
74            1
75        }
76        Err(e) => {
77            unsafe { *err = Error::new(e.description()) };
78            0
79        }
80    }
81}
82
83/// Reader trait.
84pub trait Reader: Send {
85    fn new_worker(&self, ctx: &Context, arg: &str) -> Result<Box<ReaderWorker>>;
86    fn id(&self) -> &str;
87}
88
89#[repr(C)]
90#[derive(Clone, Copy)]
91pub struct ReaderBox {
92    reader: *mut Box<Reader>,
93    id: extern "C" fn(*mut Box<Reader>) -> SafeString,
94    new_worker: extern "C" fn(
95        *mut Box<Reader>,
96        *const Context,
97        SafeString,
98        *mut ReaderWorkerBox,
99        *mut Error,
100    ) -> u8,
101}
102
103unsafe impl Send for ReaderBox {}
104
105impl ReaderBox {
106    pub fn new<T: 'static + Reader>(reader: T) -> ReaderBox {
107        let reader: Box<Reader> = Box::new(reader);
108        Self {
109            reader: Box::into_raw(Box::new(reader)),
110            id: abi_reader_id,
111            new_worker: abi_reader_new_worker,
112        }
113    }
114
115    pub fn id(&self) -> SafeString {
116        (self.id)(self.reader)
117    }
118
119    pub fn new_worker(&self, ctx: &Context, args: &str) -> Result<ReaderWorkerBox> {
120        let mut out: ReaderWorkerBox = unsafe { mem::uninitialized() };
121        let mut err = Error::new("");
122        if (self.new_worker)(self.reader, ctx, SafeString::from(args), &mut out, &mut err) == 1 {
123            Ok(out)
124        } else {
125            mem::forget(out);
126            Err(Box::new(err))
127        }
128    }
129}
130
131extern "C" fn abi_reader_id(reader: *mut Box<Reader>) -> SafeString {
132    SafeString::from(unsafe { (*reader).id() })
133}
134
135extern "C" fn abi_reader_new_worker(
136    reader: *mut Box<Reader>,
137    ctx: *const Context,
138    arg: SafeString,
139    out: *mut ReaderWorkerBox,
140    err: *mut Error,
141) -> u8 {
142    let reader = unsafe { &*reader };
143    let ctx = unsafe { &*ctx };
144    match reader.new_worker(ctx, arg.as_str()) {
145        Ok(worker) => {
146            unsafe { ptr::write(out, ReaderWorkerBox::new(worker)) };
147            1
148        }
149        Err(e) => {
150            unsafe { *err = Error::new(e.description()) };
151            0
152        }
153    }
154}
155
156/// Writer worker trait.
157pub trait WriterWorker: Send {
158    fn write(&mut self, index: u32, stack: &LayerStack) -> Result<()>;
159    fn end(&mut self) -> Result<()> {
160        Ok(())
161    }
162}
163
164/// Reader worker trait.
165pub trait ReaderWorker: Send {
166    fn read(&mut self) -> Result<Vec<Layer>>;
167}
168
169type WriterFunc =
170    extern "C" fn(*mut Box<WriterWorker>, u32, *const *const Layer, u64, *mut Error) -> u8;
171
172type WriterEndFunc = extern "C" fn(*mut Box<WriterWorker>, *mut Error) -> u8;
173
174pub struct WriterWorkerBox {
175    worker: *mut Box<WriterWorker>,
176    write: WriterFunc,
177    end: WriterEndFunc,
178    drop: extern "C" fn(*mut Box<WriterWorker>),
179}
180
181unsafe impl Send for WriterWorkerBox {}
182
183impl WriterWorkerBox {
184    pub fn new(worker: Box<WriterWorker>) -> WriterWorkerBox {
185        Self {
186            worker: Box::into_raw(Box::new(worker)),
187            write: abi_writer_worker_write,
188            end: abi_writer_worker_end,
189            drop: abi_writer_worker_drop,
190        }
191    }
192
193    pub fn write(&mut self, index: u32, layers: &[MutFixed<Layer>]) -> Result<()> {
194        let mut e = Error::new("");
195        let stack = layers.as_ptr() as *const *const Layer;
196        if (self.write)(self.worker, index, stack, layers.len() as u64, &mut e) == 0 {
197            Err(Box::new(e))
198        } else {
199            Ok(())
200        }
201    }
202
203    pub fn end(&mut self) -> Result<()> {
204        let mut e = Error::new("");
205        if (self.end)(self.worker, &mut e) == 0 {
206            Err(Box::new(e))
207        } else {
208            Ok(())
209        }
210    }
211}
212
213impl fmt::Debug for WriterWorkerBox {
214    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
215        write!(f, "WriterWorkerBox")
216    }
217}
218
219impl Drop for WriterWorkerBox {
220    fn drop(&mut self) {
221        (self.drop)(self.worker);
222    }
223}
224
225type ReaderFunc =
226    extern "C" fn(*mut Box<ReaderWorker>, *mut SafeVec<MutFixed<Layer>>, *mut Error) -> u8;
227
228pub struct ReaderWorkerBox {
229    worker: *mut Box<ReaderWorker>,
230    read: ReaderFunc,
231    drop: extern "C" fn(*mut Box<ReaderWorker>),
232}
233
234unsafe impl Send for ReaderWorkerBox {}
235
236impl ReaderWorkerBox {
237    pub fn new(worker: Box<ReaderWorker>) -> ReaderWorkerBox {
238        Self {
239            worker: Box::into_raw(Box::new(worker)),
240            read: abi_reader_worker_read,
241            drop: abi_reader_worker_drop,
242        }
243    }
244
245    pub fn read(&mut self) -> Result<Vec<MutFixed<Layer>>> {
246        let mut v = SafeVec::new();
247        let mut e = Error::new("");
248        if (self.read)(self.worker, &mut v, &mut e) == 0 {
249            Err(Box::new(e))
250        } else {
251            Ok(v.into_iter().collect())
252        }
253    }
254}
255
256impl fmt::Debug for ReaderWorkerBox {
257    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
258        write!(f, "ReaderWorkerBox")
259    }
260}
261
262impl Drop for ReaderWorkerBox {
263    fn drop(&mut self) {
264        (self.drop)(self.worker);
265    }
266}
267
268extern "C" fn abi_writer_worker_drop(worker: *mut Box<WriterWorker>) {
269    unsafe { Box::from_raw(worker) };
270}
271
272extern "C" fn abi_reader_worker_drop(worker: *mut Box<ReaderWorker>) {
273    unsafe { Box::from_raw(worker) };
274}
275
276extern "C" fn abi_writer_worker_write(
277    worker: *mut Box<WriterWorker>,
278    index: u32,
279    layers: *const *const Layer,
280    len: u64,
281    err: *mut Error,
282) -> u8 {
283    let worker = unsafe { &mut *worker };
284    let stack = unsafe { LayerStack::new(layers, len as usize) };
285    match worker.write(index, &stack) {
286        Ok(()) => 1,
287        Err(e) => {
288            unsafe { *err = Error::new(e.description()) };
289            0
290        }
291    }
292}
293
294extern "C" fn abi_writer_worker_end(worker: *mut Box<WriterWorker>, err: *mut Error) -> u8 {
295    let worker = unsafe { &mut *worker };
296    match worker.end() {
297        Ok(()) => 1,
298        Err(e) => {
299            unsafe { *err = Error::new(e.description()) };
300            0
301        }
302    }
303}
304
305extern "C" fn abi_reader_worker_read(
306    worker: *mut Box<ReaderWorker>,
307    out: *mut SafeVec<MutFixed<Layer>>,
308    err: *mut Error,
309) -> u8 {
310    let worker = unsafe { &mut *worker };
311    match worker.read() {
312        Ok(layers) => {
313            let mut safe = SafeVec::with_capacity(layers.len() as u64);
314            for layer in layers {
315                safe.push(MutFixed::new(layer));
316            }
317            unsafe { *out = safe };
318            1
319        }
320        Err(e) => {
321            unsafe { *err = Error::new(e.description()) };
322            0
323        }
324    }
325}