use crate::error::{self, check, Result};
use crate::ffi;
use std::ffi::CStr;
use std::os::raw::c_char;
use std::ptr;
pub unsafe fn cstr_to_optional_string(raw: *mut c_char) -> Option<String> {
if raw.is_null() {
return None;
}
let cstr = unsafe { CStr::from_ptr(raw) };
let s = match cstr.to_str() {
Ok(valid) => valid.to_owned(),
Err(_) => cstr.to_string_lossy().into_owned(),
};
unsafe { ffi::rnp_buffer_destroy(raw as *mut _) };
Some(s)
}
pub unsafe fn cstr_to_string(raw: *mut c_char) -> Result<String> {
unsafe { cstr_to_optional_string(raw) }.ok_or(error::Error::NullPointer)
}
pub fn call_for_string<F>(mut f: F) -> Result<String>
where
F: FnMut(*mut *mut c_char) -> u32,
{
let mut raw: *mut c_char = ptr::null_mut();
let code = f(&mut raw);
check(code)?;
unsafe { cstr_to_string(raw) }
}
pub fn call_for_optional_string<F>(mut f: F) -> Result<Option<String>>
where
F: FnMut(*mut *mut c_char) -> u32,
{
let mut raw: *mut c_char = ptr::null_mut();
let code = f(&mut raw);
if code == error::NOT_FOUND {
return Ok(None);
}
check(code)?;
Ok(unsafe { cstr_to_optional_string(raw) })
}
pub fn call_for_u32<F>(mut f: F) -> Result<u32>
where
F: FnMut(*mut u32) -> u32,
{
let mut n: u32 = 0;
let code = f(&mut n);
check(code)?;
Ok(n)
}
pub fn call_for_u64<F>(mut f: F) -> Result<u64>
where
F: FnMut(*mut u64) -> u32,
{
let mut n: u64 = 0;
let code = f(&mut n);
check(code)?;
Ok(n)
}
pub fn call_for_usize<F>(mut f: F) -> Result<usize>
where
F: FnMut(*mut usize) -> u32,
{
let mut n: usize = 0;
let code = f(&mut n);
check(code)?;
Ok(n)
}
pub fn call_for_bool<F>(mut f: F) -> Result<bool>
where
F: FnMut(*mut bool) -> u32,
{
let mut b: bool = false;
let code = f(&mut b);
check(code)?;
Ok(b)
}
pub fn call_for_owned_bytes<F>(mut f: F) -> Result<Vec<u8>>
where
F: FnMut(*mut *mut u8, *mut usize) -> u32,
{
let mut ptr: *mut u8 = ptr::null_mut();
let mut len: usize = 0;
let code = f(&mut ptr, &mut len);
check(code)?;
if ptr.is_null() {
return Ok(Vec::new());
}
unsafe {
let v = std::slice::from_raw_parts(ptr, len).to_vec();
ffi::rnp_buffer_destroy(ptr as *mut _);
Ok(v)
}
}