1use std::io::{self, Seek, SeekFrom, Write};
7use std::slice;
8
9use libc::{c_int, off_t, size_t};
10
11pub trait Wr: Write + Seek {}
12impl<T> Wr for T where T: Write + Seek {}
13
14pub struct RustOTSStream<'a> {
15 pub wr: &'a mut (dyn Wr + 'a),
16 pub error: Option<io::Error>,
17}
18
19#[allow(improper_ctypes)]
20extern "C" {
21 pub fn RustOTS_Process(stream: *mut RustOTSStream, data: *const u8, len: size_t) -> c_int;
22}
23
24#[no_mangle]
25pub unsafe extern "C" fn RustOTSStream_WriteRaw(
26 stream: *mut RustOTSStream,
27 data: *const u8,
28 len: size_t,
29) -> c_int {
30 let buf = slice::from_raw_parts(data, len as usize);
31 match (*stream).wr.write_all(buf) {
33 Ok(()) => 1,
34 Err(e) => {
35 (*stream).error = Some(e);
36 0
37 }
38 }
39}
40
41#[no_mangle]
42pub unsafe extern "C" fn RustOTSStream_Seek(stream: *mut RustOTSStream, position: off_t) -> c_int {
43 match (*stream).wr.seek(SeekFrom::Start(position as u64)) {
44 Ok(_) => 1,
45 _ => 0,
46 }
47}
48
49#[no_mangle]
50pub unsafe extern "C" fn RustOTSStream_Tell(stream: *mut RustOTSStream) -> off_t {
51 match (*stream).wr.seek(SeekFrom::Current(0)) {
52 Err(e) => {
53 panic!("RustOTSStream_Tell: can't seek: {}", e);
56 }
57 Ok(p) => p as off_t,
58 }
59}