//! Foreign function interface utilities. use crate::durandal::err::*; pub use std::{ffi::*, os::raw::*, ptr::{null, null_mut}}; /// Creates a C string from a literal. #[macro_export] macro_rules! c_str { ($s:expr) => {concat!($s, "\0").as_ptr() as $crate::durandal::ffi::NT}; } impl CStringVec { /// Creates a new empty CStringVec. pub fn new() -> Self { Self{sv: Vec::new(), cv: vec![null()]} } /// Creates a new `CStringVec` from an iterator. pub fn new_from_iter<'a, I: Iterator>(it: I) -> ResultS { let mut v = Self::new(); for st in it { v.push(CString::new(st)?); } Ok(v) } /// Pushes a new `CString`. pub fn push(&mut self, st: CString) { self.cv.insert(self.cv.len() - 1, st.as_ptr()); self.sv.push(st); } /// Returns the FFI pointer. pub fn as_ptr(&self) -> *const NT { self.cv.as_ptr() } /// Returns the FFI pointer mutably. pub fn as_mut_ptr(&mut self) -> *mut NT { self.cv.as_mut_ptr() } } impl Default for CStringVec { fn default() -> Self {Self::new()} } /// An owned null-terminated string vector. #[derive(Debug)] pub struct CStringVec { sv: Vec, cv: Vec, } /// A null-terminated byte string pointer. pub type NT = *const c_char; // EOF