removed cc dep

reimplemented wrapper.c in Rust
ffi
Avril 3 years ago
parent 7226ebdb7b
commit d5c9492c44
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -42,7 +42,6 @@ smallvec = {version = "1.6", features=["union"], optional = true}
tokio = {version = "0.2", optional = true} tokio = {version = "0.2", optional = true}
[build-dependencies] [build-dependencies]
cc = "1.0.68"
rustc_version = "0.2" rustc_version = "0.2"
[dev-dependencies] [dev-dependencies]

@ -1,37 +1,8 @@
extern crate rustc_version; extern crate rustc_version;
extern crate cc;
use std::path::Path;
use rustc_version::{version, version_meta, Channel}; use rustc_version::{version, version_meta, Channel};
const FFI_SRC_DIR: &str = "src/ffi";
//TODO: Replace the wrapper C file with a pure Rust impl in `ffi::cookie::`
fn build_cookie_wrapper(floc: impl AsRef<Path>)
{
let mut builder = cc::Build::new();
// --std=c99 -W -Wall -Werror -pedantic -O3 -flto
builder.flag("--std=c99")
.flag("-W")
.flag("-Wall")
.flag_if_supported("-Wextra")
.flag("-Werror")
.flag("-pedantic")
.flag("-fno-strict-aliasing")
.include("include/")
.opt_level(3)
// .flag_if_supported("-flto") //XXX: For some reason, this makes static linking the library fail.
// Not sure if we want these two. We can check the codegen later.
//.pic(false)
//.use_plt(false)
.file(Path::new(FFI_SRC_DIR).join(floc))
.compile("wrapper");
}
fn main() { fn main() {
// Assert we haven't travelled back in time // Assert we haven't travelled back in time
assert!(version().unwrap().major >= 1); assert!(version().unwrap().major >= 1);
@ -51,8 +22,4 @@ fn main() {
println!("cargo:rustc-cfg=dev"); println!("cargo:rustc-cfg=dev");
} }
} }
build_cookie_wrapper("wrapper.c");
//println!("cargo:rustc-link-lib={}", link);
} }

@ -31,6 +31,8 @@ pub struct CPassthrough
pub struct CSink pub struct CSink
{ {
sink: Sink<CPassthrough>, sink: Sink<CPassthrough>,
//last_err: () //TODO: how to implement this?
} }
#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy)] #[derive(Debug, Clone, PartialEq, Eq, Hash, Copy)]

@ -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…
Cancel
Save