CFFI + maturin approach

This commit is contained in:
jan 2024-12-21 15:42:50 -08:00
commit bac31e2ce6
3 changed files with 92 additions and 130 deletions

View file

@ -7,21 +7,21 @@ pub mod elements;
pub mod library;
use rust_util::ToInt2BE;
use rust_util::ToInt4BE;
use byteorder::{ByteOrder, BigEndian};
use std::mem::size_of;
macro_rules! mkfun {
( $fname:ident, $tt:ty, $elfn:ident ) => {
#[no_mangle]
pub extern "C" fn $fname(arr: *mut $tt, size: usize) -> $tt {
let sl = unsafe { std::slice::from_raw_parts_mut(arr, size) };
macro_rules! impl_i16be {
( $tt:ty, $arr:ident, $size:ident ) => {
{
let sl = unsafe { std::slice::from_raw_parts_mut($arr, $size) };
for xx in sl.iter_mut() {
let res = <$tt>::$elfn(*xx);
match res {
Err(cc) => return cc,
Ok(cc) => { *xx = cc; },
}
if *xx < i16::MIN as $tt { return *xx }
if *xx > i16::MAX as $tt { return *xx }
let mut buf = [0; size_of::<$tt>()];
BigEndian::write_i16(&mut buf, *xx as i16);
*xx = <$tt>::from_le_bytes(buf);
}
0 as $tt
}
@ -29,91 +29,58 @@ macro_rules! mkfun {
}
mkfun!(f64_to_i16, f64, convert_to_i2be);
mkfun!(f32_to_i16, f32, convert_to_i2be);
mkfun!(i64_to_i16, i64, convert_to_i2be);
mkfun!(u64_to_i16, u64, convert_to_i2be);
mkfun!(i32_to_i16, i32, convert_to_i2be);
mkfun!(u32_to_i16, u32, convert_to_i2be);
mkfun!(i16_to_i16, i16, convert_to_i2be);
mkfun!(u16_to_i16, u16, convert_to_i2be);
macro_rules! impl_i32be {
( $tt:ty, $arr:ident, $size:ident ) => {
{
let sl = unsafe { std::slice::from_raw_parts_mut($arr, $size) };
for xx in sl.iter_mut() {
if *xx < i32::MIN as $tt { return *xx }
if *xx > i32::MAX as $tt { return *xx }
mkfun!(f64_to_i32, f64, convert_to_i4be);
mkfun!(f32_to_i32, f32, convert_to_i4be);
mkfun!(i64_to_i32, i64, convert_to_i4be);
mkfun!(u64_to_i32, u64, convert_to_i4be);
mkfun!(i32_to_i32, i32, convert_to_i4be);
mkfun!(u32_to_i32, u32, convert_to_i4be);
mod rust_util {
use byteorder::{ByteOrder, BigEndian};
use std::mem::size_of;
pub trait ToInt2BE {
fn convert_to_i2be(ii: Self) -> Result<Self, Self> where Self: Sized;
}
pub trait ToInt4BE {
fn convert_to_i4be(ii: Self) -> Result<Self, Self> where Self: Sized;
}
macro_rules! impl_i2be {
( $tt:ty ) => {
impl ToInt2BE for $tt {
fn convert_to_i2be(ii: $tt) -> Result<$tt, $tt> {
if ii < i16::MIN as $tt { return Err(ii); }
if ii > i16::MAX as $tt { return Err(ii); }
let mut buf = [0; size_of::<$tt>()];
BigEndian::write_i16(&mut buf, ii as i16);
Ok(<$tt>::from_le_bytes(buf))
}
let mut buf = [0; size_of::<$tt>()];
BigEndian::write_i32(&mut buf, *xx as i32);
*xx = <$tt>::from_le_bytes(buf);
}
0 as $tt
}
}
macro_rules! impl_i4be {
( $tt:ty ) => {
impl ToInt4BE for $tt {
fn convert_to_i4be(ii: $tt) -> Result<$tt, $tt> {
if ii < i32::MIN as $tt { return Err(ii); }
if ii > i32::MAX as $tt { return Err(ii); }
let mut buf = [0; size_of::<$tt>()];
BigEndian::write_i32(&mut buf, ii as i32);
Ok(<$tt>::from_le_bytes(buf))
}
}
}
}
impl_i2be!(f64);
impl_i4be!(f64);
impl_i2be!(f32);
impl_i4be!(f32);
impl_i2be!(i64);
impl_i4be!(i64);
impl_i2be!(u64);
impl_i4be!(u64);
impl_i2be!(i32);
impl_i4be!(i32);
impl_i2be!(u32);
impl_i4be!(u32);
impl_i2be!(i16);
impl_i2be!(u16);
// Does not fit
//impl_i4be!(i16);
//impl_i4be!(u16);
//
//impl_i2be!(i8);
//impl_i4be!(i8);
//impl_i2be!(u8);
//impl_i4be!(u8);
}
#[no_mangle]
pub extern "C" fn f64_to_i16(arr: *mut f64, size: usize) -> f64 { impl_i16be!(f64, arr, size) }
#[no_mangle]
pub extern "C" fn f64_to_i32(arr: *mut f64, size: usize) -> f64 { impl_i32be!(f64, arr, size) }
#[no_mangle]
pub extern "C" fn f32_to_i16(arr: *mut f32, size: usize) -> f32 { impl_i16be!(f32, arr, size) }
#[no_mangle]
pub extern "C" fn f32_to_i32(arr: *mut f32, size: usize) -> f32 { impl_i32be!(f32, arr, size) }
#[no_mangle]
pub extern "C" fn u64_to_i16(arr: *mut u64, size: usize) -> u64 { impl_i16be!(u64, arr, size) }
#[no_mangle]
pub extern "C" fn u64_to_i32(arr: *mut u64, size: usize) -> u64 { impl_i32be!(u64, arr, size) }
#[no_mangle]
pub extern "C" fn i64_to_i16(arr: *mut i64, size: usize) -> i64 { impl_i16be!(i64, arr, size) }
#[no_mangle]
pub extern "C" fn i64_to_i32(arr: *mut i64, size: usize) -> i64 { impl_i32be!(i64, arr, size) }
#[no_mangle]
pub extern "C" fn u32_to_i16(arr: *mut u32, size: usize) -> u32 { impl_i16be!(u32, arr, size) }
#[no_mangle]
pub extern "C" fn u32_to_i32(arr: *mut u32, size: usize) -> u32 { impl_i32be!(u32, arr, size) }
#[no_mangle]
pub extern "C" fn i32_to_i16(arr: *mut i32, size: usize) -> i32 { impl_i16be!(i32, arr, size) }
#[no_mangle]
pub extern "C" fn i32_to_i32(arr: *mut i32, size: usize) -> i32 { impl_i32be!(i32, arr, size) }
#[no_mangle]
pub extern "C" fn u16_to_i16(arr: *mut u16, size: usize) -> u16 { impl_i16be!(u16, arr, size) }
#[no_mangle]
pub extern "C" fn i16_to_i16(arr: *mut i16, size: usize) -> i16 { impl_i16be!(i16, arr, size) }