#![allow(clippy::not_unsafe_ptr_arg_deref)]
use core::ptr;
use core::str;
use core::{slice, slice::from_raw_parts};
use std::ffi::{CString, c_char, c_uchar};
use crate::Parser;
use crate::parse;
#[repr(C)]
pub struct CStringWithLength {
pub ptr: *const c_uchar,
pub len: usize,
}
impl CStringWithLength {
fn new(value: &str) -> CStringWithLength {
let cstring = CString::new(value).unwrap();
CStringWithLength {
ptr: cstring.into_raw() as *const c_uchar,
len: value.len(),
}
}
}
impl From<&str> for CStringWithLength {
fn from(value: &str) -> Self { CStringWithLength::new(value) }
}
impl From<CStringWithLength> for &str {
fn from(value: CStringWithLength) -> Self {
unsafe { str::from_utf8_unchecked(slice::from_raw_parts(value.ptr, value.len)) }
}
}
#[unsafe(no_mangle)]
pub extern "C" fn milo_has_debug() -> bool { cfg!(any(debug_assertions, feature = "debug")) }
#[unsafe(no_mangle)]
pub extern "C" fn milo_noop(_parser: &mut Parser, _at: usize, _len: usize) {}
#[unsafe(no_mangle)]
pub extern "C" fn milo_free_string(s: CStringWithLength) {
unsafe {
let _ = CString::from_raw(s.ptr as *mut c_char);
}
}
#[unsafe(no_mangle)]
pub extern "C" fn milo_create() -> *mut Parser { Box::into_raw(Box::new(Parser::new())) }
#[unsafe(no_mangle)]
pub extern "C" fn milo_destroy(parser: *mut Parser) {
if parser.is_null() {
return;
}
unsafe {
let _ = Box::from_raw(parser);
}
}
#[unsafe(no_mangle)]
pub extern "C" fn milo_parse(parser: *mut Parser, data: *const c_uchar, limit: usize) -> usize {
unsafe { (*parser).parse(data, limit) }
}
#[unsafe(no_mangle)]
pub extern "C" fn milo_reset(parser: *mut Parser, keep_parsed: bool) { unsafe { (*parser).reset(keep_parsed) } }
#[unsafe(no_mangle)]
pub extern "C" fn milo_clear(parser: *mut Parser) { unsafe { (*parser).clear() } }
#[unsafe(no_mangle)]
pub extern "C" fn milo_pause(parser: *mut Parser) { unsafe { (*parser).pause() } }
#[unsafe(no_mangle)]
pub extern "C" fn milo_resume(parser: *mut Parser) { unsafe { (*parser).resume() } }
#[unsafe(no_mangle)]
pub extern "C" fn milo_finish(parser: *mut Parser) { unsafe { (*parser).finish() } }
#[unsafe(no_mangle)]
pub extern "C" fn milo_fail(parser: *mut Parser, code: u8, description: CStringWithLength) {
unsafe { (*parser).fail(code, description.into()) };
}
#[unsafe(no_mangle)]
pub extern "C" fn milo_state_string(parser: *mut Parser) -> CStringWithLength {
unsafe { (*parser).state_str().into() }
}
#[unsafe(no_mangle)]
pub extern "C" fn milo_error_code_string(parser: *mut Parser) -> CStringWithLength {
unsafe { (*parser).error_code_str().into() }
}
#[unsafe(no_mangle)]
pub extern "C" fn milo_error_description_string(parser: *mut Parser) -> CStringWithLength {
unsafe { (*parser).error_description_str().into() }
}