You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
69 lines
1.3 KiB
69 lines
1.3 KiB
use std::{ffi::CString, os::raw::c_char, ptr::null}; |
|
|
|
/// Creates a C string from a literal. |
|
#[macro_export] |
|
macro_rules! c_str { |
|
($s:expr) => { |
|
std::concat!($s, "\0").as_ptr() as *const std::os::raw::c_char |
|
}; |
|
} |
|
|
|
/// An owned null-terminated string vector. |
|
#[derive(Debug)] |
|
pub struct CStringVec { |
|
sv: Vec<CString>, |
|
cv: Vec<*const c_char>, |
|
} |
|
|
|
impl Default for CStringVec { |
|
/// Creates a new empty CStringVec. |
|
#[inline] |
|
fn default() -> Self { |
|
Self { sv: Vec::new(), cv: vec![null()] } |
|
} |
|
} |
|
|
|
#[allow(dead_code)] |
|
impl CStringVec { |
|
/// Creates a new `CStringVec` from an iterator. |
|
#[inline] |
|
pub fn new_from_iter<'a, I>(it: I) -> Result<Self, std::ffi::NulError> |
|
where |
|
I: Iterator<Item = &'a str>, |
|
{ |
|
let mut v = Self::default(); |
|
|
|
for st in it { |
|
v.push(CString::new(st)?); |
|
} |
|
|
|
Ok(v) |
|
} |
|
|
|
/// Pushes a new `CString`. |
|
#[inline] |
|
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. |
|
#[inline] |
|
pub fn as_ptr(&self) -> *const *const c_char { |
|
self.cv.as_ptr() |
|
} |
|
|
|
/// Returns the FFI pointer mutably. |
|
#[inline] |
|
pub fn as_mut_ptr(&mut self) -> *mut *const c_char { |
|
self.cv.as_mut_ptr() |
|
} |
|
|
|
/// Returns the length of the vector. |
|
#[inline] |
|
pub fn len(&self) -> usize { |
|
self.sv.len() |
|
} |
|
} |
|
|
|
// EOF
|
|
|