parent
7226ebdb7b
commit
d5c9492c44
@ -1,14 +1,114 @@
|
|||||||
|
#![allow(non_camel_case_types)]
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use libc::{c_void, FILE};
|
use std::{
|
||||||
|
slice,
|
||||||
|
};
|
||||||
|
use libc::{
|
||||||
|
c_void,
|
||||||
|
c_char,
|
||||||
|
c_int,
|
||||||
|
off64_t,
|
||||||
|
ssize_t,
|
||||||
|
size_t,
|
||||||
|
|
||||||
|
FILE,
|
||||||
|
};
|
||||||
|
|
||||||
//TODO: Remove `wrapper.c`, implement it in Rust here
|
//TODO: Remove `wrapper.c`, implement it in Rust here
|
||||||
|
|
||||||
//FILE* _cc20c_create(cc20_sink_t* restrict sink)
|
type cookie_read_function_t = Option<extern "C" fn (cookie: *mut c_void, buf: *mut c_char , size: size_t) -> ssize_t>;
|
||||||
|
type cookie_write_function_t = Option<extern "C" fn (cookie: *mut c_void, buf: *const c_char, size: size_t) -> ssize_t>;
|
||||||
|
type cookie_seek_function_t = Option<extern "C" fn (cookie: *mut c_void, offset: *mut off64_t, whence: c_int) -> c_int>;
|
||||||
|
type cookie_close_function_t = Option<extern "C" fn (cookie: *mut c_void) -> c_int>;
|
||||||
|
|
||||||
|
const _: [u8; 8] = [0u8; std::mem::size_of::<cookie_read_function_t>()];
|
||||||
|
|
||||||
|
// `fopencookie` API
|
||||||
|
#[derive(Debug, Clone, Copy, Default)]
|
||||||
|
#[repr(C)]
|
||||||
|
struct cookie_io_functions_t
|
||||||
|
{
|
||||||
|
read: cookie_read_function_t,
|
||||||
|
write: cookie_write_function_t,
|
||||||
|
seek: cookie_seek_function_t,
|
||||||
|
close: cookie_close_function_t,
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn _cc20c_create(sink: *mut c_void) -> *mut FILE;
|
fn fopencookie(cookie: *mut c_void, mode: *const c_char, funcs: cookie_io_functions_t) -> *mut FILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)] unsafe fn ref_cookie<'a>(cookie: *mut c_void) -> Option<&'a mut CSink>
|
||||||
|
{
|
||||||
|
if cookie.is_null() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(&mut *(cookie as *mut CSink))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! unwrap {
|
||||||
|
(? $expr:expr, $or:expr) => {
|
||||||
|
if let Some(val) = $expr {
|
||||||
|
val
|
||||||
|
} else {
|
||||||
|
return $or;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" fn read(_cookie: *mut c_void, _buf: *mut c_char, _size: size_t) -> ssize_t
|
||||||
|
{
|
||||||
|
-1
|
||||||
|
}
|
||||||
|
extern "C" fn write(cookie: *mut c_void, buf: *const c_char, size: size_t) -> ssize_t
|
||||||
|
{
|
||||||
|
//Remember: Cannot return -1 here
|
||||||
|
no_unwind!({
|
||||||
|
if buf.is_null() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
let sink = unwrap!(? unsafe { ref_cookie(cookie) }, 0);
|
||||||
|
let buf = unsafe { slice::from_raw_parts(buf as *const u8, size) };
|
||||||
|
|
||||||
|
match sink.sink.write(buf) {
|
||||||
|
Ok(n) if n < ssize_t::MAX as usize => n as ssize_t,
|
||||||
|
Err(_er) => {
|
||||||
|
//sink.last_err_code =
|
||||||
|
//sink.last_err = Some(
|
||||||
|
0
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
// TODO
|
||||||
|
// Write succeeded, but wrote more than `isize::MAX`.
|
||||||
|
0
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}).unwrap_or(0)
|
||||||
|
}
|
||||||
|
extern "C" fn seek(_cookie: *mut c_void, _offset: *mut off64_t, _whence: c_int) -> c_int
|
||||||
|
{
|
||||||
|
-1
|
||||||
|
}
|
||||||
|
extern "C" fn close(cookie: *mut c_void) -> c_int
|
||||||
|
{
|
||||||
|
let sink = if cookie.is_null() {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
cookie as *mut CSink
|
||||||
|
};
|
||||||
|
let sink = unsafe { interop::take(sink) };
|
||||||
|
drop(sink);
|
||||||
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)] pub unsafe fn create(raw_sink: *mut CSink) -> *mut FILE
|
#[inline(always)] pub unsafe fn create(raw_sink: *mut CSink) -> *mut FILE
|
||||||
{
|
{
|
||||||
_cc20c_create(raw_sink as *mut c_void)
|
fopencookie(raw_sink as *mut c_void, b"wb\0" as *const u8 as *const c_char, cookie_io_functions_t {
|
||||||
|
read: Some(read),
|
||||||
|
write: Some(write),
|
||||||
|
seek: Some(seek),
|
||||||
|
close: Some(close),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,52 +0,0 @@
|
|||||||
#define _GNU_SOURCE
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <cc20.h>
|
|
||||||
|
|
||||||
#define IGNORE(v) ((void)(v))
|
|
||||||
|
|
||||||
static ssize_t cc20c_read(void* cookie, char* buffer, size_t size)
|
|
||||||
{
|
|
||||||
IGNORE(cookie);
|
|
||||||
IGNORE(buffer);
|
|
||||||
IGNORE(size);
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t cc20c_write(void* cookie, const char* buffer, size_t size)
|
|
||||||
{
|
|
||||||
cc20_result_t res = cc20_write(buffer, &size, cookie);
|
|
||||||
IGNORE(res); // TODO: set an error flag `res` in `cookie` (i.e. `CSink`)
|
|
||||||
return (ssize_t) size;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cc20c_seek(void* cookie, off64_t* pos, int w)
|
|
||||||
{
|
|
||||||
IGNORE(cookie);
|
|
||||||
IGNORE(pos);
|
|
||||||
IGNORE(w);
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cc20c_close(void* cookie)
|
|
||||||
{
|
|
||||||
struct cc20_metadata meta ={0};
|
|
||||||
cc20_close_sink(cookie, &meta);
|
|
||||||
if(meta.backing) fclose(meta.backing);
|
|
||||||
else return -1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE* _cc20c_create(cc20_sink_t* restrict sink)
|
|
||||||
{
|
|
||||||
return fopencookie(sink, "wb", (cookie_io_functions_t){
|
|
||||||
.read = &cc20c_read,
|
|
||||||
.write = &cc20c_write,
|
|
||||||
.seek = &cc20c_seek,
|
|
||||||
.close = &cc20c_close,
|
|
||||||
});
|
|
||||||
}
|
|
Loading…
Reference in new issue