use super::*;
pub fn receive_str<'a>(s: *const c_char) -> Result<&'a str> {
if s.is_null() {
inv_arg("unexpected NULL string")
} else {
Ok(unsafe { CStr::from_ptr(s) }.to_str()?)
}
}
pub fn receive_optional_str<'a>(s: *const c_char) -> Result<Option<&'a str>> {
if s.is_null() {
Ok(None)
} else {
Ok(Some(unsafe { CStr::from_ptr(s) }.to_str()?))
}
}
pub fn receive_raw<'a>(obj: *const c_void, obj_size: usize) -> Result<&'a [u8]> {
if obj_size == 0 {
Ok(&[])
} else if obj.is_null() {
inv_arg("unexpected NULL data")
} else {
Ok(unsafe { std::slice::from_raw_parts(obj as *const u8, obj_size) })
}
}
pub fn return_raw(obj_in: &[u8], obj_out: *mut c_void, obj_size: usize) -> Result<ssize_t> {
if obj_size > 0 && obj_out.is_null() {
inv_arg("unexpected NULL buffer")
} else {
let actual_size = obj_in.len();
let copy_size = std::cmp::min(actual_size, obj_size);
if copy_size > 0 {
unsafe {
memcpy(obj_out, obj_in.as_ptr() as *const c_void, copy_size);
}
}
Ok(actual_size as ssize_t)
}
}
pub fn receive_index(len: size_t, index: ssize_t, insert: bool) -> Result<size_t> {
let converted_index = if index < 0 {
if insert {
index + (len as ssize_t) + 1
} else {
index + (len as ssize_t)
}
} else {
index
};
let mut ok = true;
if converted_index < 0 || converted_index as size_t > len {
ok = false;
} else if converted_index as size_t == len {
ok = insert;
}
if ok {
Ok(converted_index as size_t)
} else {
inv_arg(format!("index out of range: {}", index))
}
}
pub fn receive_matrix(
ptr: *const c_double,
matrix_len: size_t,
num_qubits: usize,
) -> Result<Option<Vec<Complex64>>> {
if matrix_len == 0 {
Ok(None)
} else if num_qubits == 0 {
inv_arg("cannot read matrix for 0 qubits")
} else {
let num_entries = 2usize.pow(2 * num_qubits as u32);
if matrix_len != num_entries {
inv_arg("matrix has the wrong number of entries")
} else if ptr.is_null() {
inv_arg("matrix pointer is null")
} else {
let mut vec = Vec::with_capacity(num_entries);
for i in 0..num_entries {
let re: f64 = unsafe { *ptr.add(i * 2) };
let im: f64 = unsafe { *ptr.add(i * 2 + 1) };
vec.push(Complex64::new(re, im));
}
Ok(Some(vec))
}
}
}
pub struct CallbackUserData {
user_free: Option<extern "C" fn(*mut c_void)>,
data: *mut c_void,
}
unsafe impl Send for CallbackUserData {}
impl Drop for CallbackUserData {
fn drop(&mut self) {
if let Some(user_free) = self.user_free {
user_free(self.data);
}
}
}
impl CallbackUserData {
pub fn new(
user_free: Option<extern "C" fn(*mut c_void)>,
data: *mut c_void,
) -> CallbackUserData {
CallbackUserData { user_free, data }
}
pub fn data(&self) -> *mut c_void {
self.data
}
}