use core::ffi::{c_uchar, c_void};
use std::slice;
use crate::Parser;
#[cfg(any(debug_assertions, feature = "debug"))]
pub fn debug(message: String) { unsafe { crate::logger(((message.as_ptr() as u64) << 32) + message.len() as u64) } }
#[unsafe(no_mangle)]
pub fn milo_has_debug() -> bool { cfg!(any(debug_assertions, feature = "debug")) }
#[unsafe(no_mangle)]
pub fn alloc(len: usize) -> *mut c_void {
let buffer = Vec::with_capacity(len);
let (ptr, _, _) = { buffer.into_raw_parts() };
ptr as *mut c_void
}
#[unsafe(no_mangle)]
pub fn dealloc(ptr: *mut c_void, len: usize) {
if ptr.is_null() {
return;
}
unsafe {
let _ = Vec::from_raw_parts(ptr, len, len);
}
}
#[unsafe(no_mangle)]
pub fn create() -> *mut c_void {
let ptr = Box::into_raw(Box::new(Parser::new())) as *mut c_void;
let mut parser = unsafe { Box::from_raw(ptr as *mut Parser) };
parser.ptr = ptr;
let _ = Box::into_raw(parser);
ptr
}
#[unsafe(no_mangle)]
pub fn destroy(parser: *mut c_void) {
if parser.is_null() {
return;
}
unsafe {
let _ = Box::from_raw(parser as *mut Parser);
}
}
#[unsafe(no_mangle)]
pub fn reset(parser: *mut c_void, keep_parsed: bool) { unsafe { (*(parser as *mut Parser)).reset(keep_parsed) } }
#[unsafe(no_mangle)]
pub fn clear(parser: *mut c_void) { unsafe { (*(parser as *mut Parser)).clear() } }
#[unsafe(no_mangle)]
pub fn parse(parser: *mut c_void, data: *const c_uchar, limit: usize) -> usize {
unsafe { (*(parser as *mut Parser)).parse(data, limit) }
}
#[unsafe(no_mangle)]
pub fn parse_with_error(parser: *mut c_void, data: *const c_uchar, limit: usize) -> i32 {
let parser = unsafe { &mut *(parser as *mut Parser) };
let consumed = parser.parse(data, limit) as i32;
if parser.error_code == crate::ERROR_NONE {
consumed
} else {
-(consumed + 1)
}
}
#[unsafe(no_mangle)]
pub fn pause(parser: *mut c_void) { unsafe { (*(parser as *mut Parser)).pause() } }
#[unsafe(no_mangle)]
pub fn resume(parser: *mut c_void) { unsafe { (*(parser as *mut Parser)).resume() } }
#[unsafe(no_mangle)]
pub fn finish(parser: *mut c_void) { unsafe { (*(parser as *mut Parser)).finish() } }
#[unsafe(no_mangle)]
pub fn fail(parser: *mut c_void, code: u8, description_ptr: *const c_uchar, description_len: usize) {
unsafe {
(*(parser as *mut Parser)).fail(
code,
std::str::from_utf8_unchecked(slice::from_raw_parts(description_ptr, description_len)),
);
}
}
#[unsafe(no_mangle)]
pub fn is_autodetect(parser: *const c_void) -> bool { unsafe { (*(parser as *const Parser)).autodetect } }
#[unsafe(no_mangle)]
pub fn is_request(parser: *const c_void) -> bool { unsafe { (*(parser as *const Parser)).is_request } }
#[unsafe(no_mangle)]
pub fn is_paused(parser: *const c_void) -> bool { unsafe { (*(parser as *const Parser)).paused } }
#[unsafe(no_mangle)]
pub fn should_manage_unconsumed(parser: *const c_void) -> bool {
unsafe { (*(parser as *const Parser)).manage_unconsumed }
}
#[unsafe(no_mangle)]
pub fn get_max_start_line_length(parser: *const c_void) -> usize {
unsafe { (*(parser as *const Parser)).max_start_line_length }
}
#[unsafe(no_mangle)]
pub fn get_max_header_length(parser: *const c_void) -> usize {
unsafe { (*(parser as *const Parser)).max_header_length }
}
#[unsafe(no_mangle)]
pub fn should_continue_without_data(parser: *const c_void) -> bool {
unsafe { (*(parser as *const Parser)).continue_without_data }
}
#[unsafe(no_mangle)]
pub fn is_connect(parser: *const c_void) -> bool { unsafe { (*(parser as *const Parser)).is_connect } }
#[unsafe(no_mangle)]
pub fn should_skip_body(parser: *const c_void) -> bool { unsafe { (*(parser as *const Parser)).skip_body } }
#[unsafe(no_mangle)]
pub fn get_state(parser: *const c_void) -> u8 { unsafe { (*(parser as *const Parser)).state } }
#[unsafe(no_mangle)]
pub fn get_position(parser: *const c_void) -> usize { unsafe { (*(parser as *const Parser)).position } }
#[unsafe(no_mangle)]
pub fn get_parsed(parser: *const c_void) -> u64 { unsafe { (*(parser as *const Parser)).parsed } }
#[unsafe(no_mangle)]
pub fn get_error_code(parser: *const c_void) -> u8 { unsafe { (*(parser as *const Parser)).error_code } }
#[unsafe(no_mangle)]
pub fn get_method(parser: *const c_void) -> u8 { unsafe { (*(parser as *const Parser)).method } }
#[unsafe(no_mangle)]
pub fn get_status(parser: *const c_void) -> u32 { unsafe { (*(parser as *const Parser)).status } }
#[unsafe(no_mangle)]
pub fn get_version_major(parser: *const c_void) -> u8 { unsafe { (*(parser as *const Parser)).version_major } }
#[unsafe(no_mangle)]
pub fn get_version_minor(parser: *const c_void) -> u8 { unsafe { (*(parser as *const Parser)).version_minor } }
#[unsafe(no_mangle)]
pub fn has_connection_close(parser: *const c_void) -> bool {
unsafe { (*(parser as *const Parser)).has_connection_close }
}
#[unsafe(no_mangle)]
pub fn has_connection_upgrade(parser: *const c_void) -> bool {
unsafe { (*(parser as *const Parser)).has_connection_upgrade }
}
#[unsafe(no_mangle)]
pub fn get_content_length(parser: *const c_void) -> u64 { unsafe { (*(parser as *const Parser)).content_length } }
#[unsafe(no_mangle)]
pub fn get_chunk_size(parser: *const c_void) -> u64 { unsafe { (*(parser as *const Parser)).chunk_size } }
#[unsafe(no_mangle)]
pub fn get_remaining_content_length(parser: *const c_void) -> u64 {
unsafe { (*(parser as *const Parser)).remaining_content_length }
}
#[unsafe(no_mangle)]
pub fn get_remaining_chunk_size(parser: *const c_void) -> u64 {
unsafe { (*(parser as *const Parser)).remaining_chunk_size }
}
#[unsafe(no_mangle)]
pub fn has_content_length(parser: *const c_void) -> bool { unsafe { (*(parser as *const Parser)).has_content_length } }
#[unsafe(no_mangle)]
pub fn has_transfer_encoding(parser: *const c_void) -> bool {
unsafe { (*(parser as *const Parser)).has_transfer_encoding }
}
#[unsafe(no_mangle)]
pub fn has_chunked_transfer_encoding(parser: *const c_void) -> bool {
unsafe { (*(parser as *const Parser)).has_chunked_transfer_encoding }
}
#[unsafe(no_mangle)]
pub fn has_upgrade(parser: *const c_void) -> bool { unsafe { (*(parser as *const Parser)).has_upgrade } }
#[unsafe(no_mangle)]
pub fn has_trailers(parser: *const c_void) -> bool { unsafe { (*(parser as *const Parser)).has_trailers } }
#[unsafe(no_mangle)]
pub fn get_error_description_raw(parser: *mut c_void) -> u64 {
let parser = unsafe { &(*(parser as *const Parser)) };
let ptr = parser.error_description as u64;
let len = parser.error_description_len as u64;
(ptr << 32) + len
}
#[unsafe(no_mangle)]
pub fn set_should_autodetect(parser: *mut c_void, value: bool) {
unsafe {
(*(parser as *mut Parser)).autodetect = value;
}
}
#[unsafe(no_mangle)]
pub fn set_is_request(parser: *mut c_void, value: bool) {
unsafe {
(*(parser as *mut Parser)).is_request = value;
}
}
#[unsafe(no_mangle)]
pub fn set_should_manage_unconsumed(parser: *mut c_void, value: bool) {
unsafe {
(*(parser as *mut Parser)).manage_unconsumed = value;
}
}
#[unsafe(no_mangle)]
pub fn set_max_start_line_length(parser: *mut c_void, value: usize) {
unsafe {
(*(parser as *mut Parser)).max_start_line_length = value;
}
}
#[unsafe(no_mangle)]
pub fn set_max_header_length(parser: *mut c_void, value: usize) {
unsafe {
(*(parser as *mut Parser)).max_header_length = value;
}
}
#[unsafe(no_mangle)]
pub fn set_should_continue_without_data(parser: *mut c_void, value: bool) {
unsafe {
(*(parser as *mut Parser)).continue_without_data = value;
}
}
#[unsafe(no_mangle)]
pub fn set_should_skip_body(parser: *mut c_void, value: bool) {
unsafe {
(*(parser as *mut Parser)).skip_body = value;
}
}
#[unsafe(no_mangle)]
pub fn set_is_connect(parser: *mut c_void, value: bool) {
unsafe {
(*(parser as *mut Parser)).is_connect = value;
}
}
#[unsafe(no_mangle)]
pub fn set_active_callbacks(parser: *mut c_void, value: u64) {
unsafe {
(*(parser as *mut Parser)).active_callbacks = value;
}
}