pub mod key;
pub mod row;
use crate::{YAD, Version, Row};
use std::ffi::{CStr, CString};
use std::ptr;
#[unsafe(no_mangle)]
pub extern "C" fn version_new(major: u8, minor: u8, patch: u8, beta: u8) -> *mut Version {
Box::into_raw(Box::new(Version { major, minor, patch, beta }))
}
#[unsafe(no_mangle)]
pub extern "C" fn version_free(version: *mut Version) {
unsafe { if !version.is_null() { let _ = Box::from_raw(version); } }
}
#[unsafe(no_mangle)]
pub extern "C" fn version_serialize(version: *const Version, out_bytes: *mut u8) {
unsafe {
if version.is_null() || out_bytes.is_null() { return; }
let bytes = (*version).serialize();
ptr::copy_nonoverlapping(bytes.as_ptr(), out_bytes, bytes.len());
}
}
#[unsafe(no_mangle)]
pub extern "C" fn version_deserialize(bytes: *const u8) -> *mut Version {
unsafe {
if bytes.is_null() { return ptr::null_mut(); }
let slice = std::slice::from_raw_parts(bytes, 5).to_vec();
match Version::deserialize(slice) {
Ok(ver) => Box::into_raw(Box::new(ver)),
Err(_) => ptr::null_mut(),
}
}
}
#[unsafe(no_mangle)]
pub extern "C" fn yad_new_empty(version: *const Version) -> *mut YAD {
unsafe {
if version.is_null() { return ptr::null_mut(); }
Box::into_raw(Box::new(YAD::new_empty((*version).clone())))
}
}
#[unsafe(no_mangle)]
pub extern "C" fn yad_new(version: *const Version, rows: *const *mut Row, rows_len: usize) -> *mut YAD {
unsafe {
if version.is_null() { return ptr::null_mut(); }
let mut vec_rows = Vec::with_capacity(rows_len);
if !rows.is_null() {
for i in 0..rows_len {
let row_ptr = *rows.add(i);
if !row_ptr.is_null() { vec_rows.push((*row_ptr).clone()); }
}
}
Box::into_raw(Box::new(YAD::new((*version).clone(), vec_rows)))
}
}
#[unsafe(no_mangle)]
pub extern "C" fn yad_free(yad: *mut YAD) {
unsafe { if !yad.is_null() { let _ = Box::from_raw(yad); } }
}
#[unsafe(no_mangle)]
pub extern "C" fn yad_insert_row(yad: *mut YAD, row: *mut Row) {
unsafe {
if yad.is_null() || row.is_null() { return; }
let yad = &mut *yad;
let row = &*row;
yad.rows.insert(row.name.clone(), row.clone());
}
}
#[unsafe(no_mangle)]
pub extern "C" fn yad_remove_row(yad: *mut YAD, name: *const i8) -> *mut Row {
unsafe {
if yad.is_null() || name.is_null() { return ptr::null_mut(); }
let cstr = match CStr::from_ptr(name).to_str() { Ok(s) => s, Err(_) => return ptr::null_mut() };
match (*yad).rows.remove(cstr) {
Some(row) => Box::into_raw(Box::new(row)),
None => ptr::null_mut(),
}
}
}
#[unsafe(no_mangle)]
pub extern "C" fn yad_serialize(yad: *const YAD, out_bytes: *mut u8, max_len: usize) -> usize {
unsafe {
if yad.is_null() || out_bytes.is_null() { return 0; }
let yad = &*yad;
match yad.serialize() {
Ok(vec) => {
let len = vec.len().min(max_len);
ptr::copy_nonoverlapping(vec.as_ptr(), out_bytes, len);
len
}
Err(_) => 0,
}
}
}
#[unsafe(no_mangle)]
pub extern "C" fn yad_deserialize(bytes: *const u8, len: usize) -> *mut YAD {
unsafe {
if bytes.is_null() || len == 0 { return ptr::null_mut(); }
let vec = std::slice::from_raw_parts(bytes, len).to_vec();
match YAD::deserialize(vec) {
Ok(yad) => Box::into_raw(Box::new(yad)),
Err(_) => ptr::null_mut(),
}
}
}
#[unsafe(no_mangle)]
pub extern "C" fn yad_get_row(yad: *const YAD, name: *const i8) -> *mut Row {
unsafe {
if yad.is_null() || name.is_null() { return ptr::null_mut(); }
let cstr = match CStr::from_ptr(name).to_str() { Ok(s) => s, Err(_) => return ptr::null_mut() };
match (*yad).rows.get(cstr) {
Some(row) => Box::into_raw(Box::new(row.clone())),
None => ptr::null_mut(),
}
}
}
#[unsafe(no_mangle)]
pub extern "C" fn yad_remove_row_by_name(yad: *mut YAD, name: *const i8) -> *mut Row {
unsafe {
if yad.is_null() || name.is_null() { return ptr::null_mut(); }
let cstr = match CStr::from_ptr(name).to_str() { Ok(s) => s, Err(_) => return ptr::null_mut() };
match (*yad).rows.remove(cstr) {
Some(row) => Box::into_raw(Box::new(row)),
None => ptr::null_mut(),
}
}
}
#[unsafe(no_mangle)]
pub extern "C" fn yad_set_row(yad: *mut YAD, row: *mut Row) {
unsafe {
if yad.is_null() || row.is_null() { return; }
let yad = &mut *yad;
let row = &*row;
yad.rows.insert(row.name.clone(), row.clone());
}
}
#[unsafe(no_mangle)]
pub extern "C" fn yad_row_count(yad: *const YAD) -> usize {
unsafe {
if yad.is_null() {
return 0;
}
(*yad).rows.len()
}
}
#[unsafe(no_mangle)]
pub extern "C" fn yad_row_names(yad: *const YAD) -> *mut *mut i8 {
unsafe {
if yad.is_null() {
return ptr::null_mut();
}
let yad = &*yad;
let mut cstrings: Vec<*mut i8> = Vec::with_capacity(yad.rows.len());
for row_name in yad.rows.keys() {
let cstr = CString::new(row_name.as_str()).unwrap_or_else(|_| CString::new("").unwrap());
cstrings.push(cstr.into_raw());
}
let ptr_array = cstrings.into_boxed_slice();
Box::into_raw(ptr_array) as *mut *mut i8
}
}
#[unsafe(no_mangle)]
pub extern "C" fn yad_row_names_free(names: *mut *mut i8, count: usize) {
unsafe {
if names.is_null() {
return;
}
let names_slice = std::slice::from_raw_parts_mut(names, count);
for &mut name_ptr in names_slice {
if !name_ptr.is_null() {
let _ = CString::from_raw(name_ptr);
}
}
}
}