#![allow(unsafe_code, clippy::missing_safety_doc)]
use std::ffi::CStr;
use std::os::raw::c_char;
use crate::catalog::Catalog;
use super::strings::to_c_string;
use super::{clear_last_error, set_last_error};
#[no_mangle]
pub unsafe extern "C" fn xmloxide_parse_catalog(input: *const c_char) -> *mut Catalog {
clear_last_error();
if input.is_null() {
set_last_error("null input pointer");
return std::ptr::null_mut();
}
let c_str = unsafe { CStr::from_ptr(input) };
let Ok(s) = c_str.to_str() else {
set_last_error("invalid UTF-8");
return std::ptr::null_mut();
};
match Catalog::parse(s) {
Ok(cat) => Box::into_raw(Box::new(cat)),
Err(e) => {
set_last_error(&e.message);
std::ptr::null_mut()
}
}
}
#[no_mangle]
pub unsafe extern "C" fn xmloxide_free_catalog(catalog: *mut Catalog) {
if !catalog.is_null() {
unsafe {
drop(Box::from_raw(catalog));
}
}
}
#[no_mangle]
pub unsafe extern "C" fn xmloxide_catalog_resolve_system(
catalog: *const Catalog,
system_id: *const c_char,
) -> *mut c_char {
if catalog.is_null() || system_id.is_null() {
return std::ptr::null_mut();
}
let catalog = unsafe { &*catalog };
let c_id = unsafe { CStr::from_ptr(system_id) };
let Ok(id_str) = c_id.to_str() else {
return std::ptr::null_mut();
};
match catalog.resolve_system(id_str) {
Some(resolved) => to_c_string(&resolved),
None => std::ptr::null_mut(),
}
}
#[no_mangle]
pub unsafe extern "C" fn xmloxide_catalog_resolve_public(
catalog: *const Catalog,
public_id: *const c_char,
) -> *mut c_char {
if catalog.is_null() || public_id.is_null() {
return std::ptr::null_mut();
}
let catalog = unsafe { &*catalog };
let c_id = unsafe { CStr::from_ptr(public_id) };
let Ok(id_str) = c_id.to_str() else {
return std::ptr::null_mut();
};
match catalog.resolve_public(id_str) {
Some(resolved) => to_c_string(&resolved),
None => std::ptr::null_mut(),
}
}
#[no_mangle]
pub unsafe extern "C" fn xmloxide_catalog_resolve_uri(
catalog: *const Catalog,
uri: *const c_char,
) -> *mut c_char {
if catalog.is_null() || uri.is_null() {
return std::ptr::null_mut();
}
let catalog = unsafe { &*catalog };
let c_uri = unsafe { CStr::from_ptr(uri) };
let Ok(uri_str) = c_uri.to_str() else {
return std::ptr::null_mut();
};
match catalog.resolve_uri(uri_str) {
Some(resolved) => to_c_string(&resolved),
None => std::ptr::null_mut(),
}
}