use crate::ffi::errors::{ErrorHandle, Status};
use crate::ffi::helpers::fields::Fields as FieldSection;
use crate::ffi::{Buffer as Octets, Slice};
use crate::models::{Message, Version};
use crate::protocol::common::{Buffer, Fields};
#[unsafe(no_mangle)]
pub extern "C" fn soyokaze_read_buffer_default_chunk_size() -> usize {
Buffer::DEFAULT_CHUNK_SIZE
}
#[unsafe(no_mangle)]
pub extern "C" fn soyokaze_read_buffer_chunk_ramp() -> usize {
Buffer::CHUNK_RAMP
}
#[unsafe(no_mangle)]
pub extern "C" fn soyokaze_read_buffer_oversized(capacity: usize, len: usize, idle_capacity: usize) -> bool {
Buffer::oversized(capacity, len, idle_capacity)
}
#[unsafe(no_mangle)]
pub extern "C" fn soyokaze_read_buffer_new() -> *mut Buffer {
Box::into_raw(Box::new(Buffer::new()))
}
#[unsafe(no_mangle)]
pub extern "C" fn soyokaze_read_buffer_with_chunk_size(chunk_size: usize) -> *mut Buffer {
Box::into_raw(Box::new(Buffer::with_chunk_size(chunk_size.min(Buffer::MAXIMUM_CHUNK_SIZE))))
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_read_buffer_free(buffer: *mut Buffer) {
if !buffer.is_null() {
drop(unsafe { Box::from_raw(buffer) });
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_read_buffer_chunk_size(buffer: *const Buffer) -> usize {
unsafe { buffer.as_ref() }.map_or(0, |buffer| buffer.chunk_size())
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_read_buffer_set_chunk_size(buffer: *mut Buffer, chunk_size: usize) -> bool {
let Some(buffer) = (unsafe { buffer.as_mut() }) else {
return false;
};
buffer.set_chunk_size(chunk_size);
true
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_read_buffer_len(buffer: *const Buffer) -> usize {
unsafe { buffer.as_ref() }.map_or(0, |buffer| buffer.len())
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_read_buffer_is_empty(buffer: *const Buffer) -> bool {
unsafe { buffer.as_ref() }.is_none_or(|buffer| buffer.is_empty())
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_read_buffer_eof(buffer: *const Buffer) -> bool {
unsafe { buffer.as_ref() }.is_some_and(|buffer| buffer.eof())
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_read_buffer_capacity(buffer: *const Buffer) -> usize {
unsafe { buffer.as_ref() }.map_or(0, |buffer| buffer.capacity())
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_read_buffer_bytes(buffer: *const Buffer) -> Slice {
match unsafe { buffer.as_ref() } {
Some(buffer) => Slice::new(buffer.as_slice()),
None => Slice::ABSENT,
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_read_buffer_extend(buffer: *mut Buffer, data: *const u8, data_len: usize) -> bool {
let (Some(buffer), Some(data)) = (unsafe { buffer.as_mut() }, unsafe { Slice::borrow(data, data_len) }) else {
return false;
};
buffer.as_bytes_mut().extend_from_slice(data);
true
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_read_buffer_consume(buffer: *mut Buffer, count: usize) -> bool {
let Some(buffer) = (unsafe { buffer.as_mut() }) else {
return false;
};
buffer.consume(count);
true
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_read_buffer_take(buffer: *mut Buffer, count: usize) -> Octets {
match unsafe { buffer.as_mut() } {
Some(buffer) => Octets::new(buffer.take(count).to_vec()),
None => Octets::EMPTY,
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_read_buffer_reclaim(buffer: *mut Buffer, idle_capacity: usize) -> bool {
let Some(buffer) = (unsafe { buffer.as_mut() }) else {
return false;
};
buffer.reclaim(idle_capacity);
true
}
#[unsafe(no_mangle)]
pub extern "C" fn soyokaze_pseudo_request_count() -> usize {
Fields::PSEUDO_REQUEST.len()
}
#[unsafe(no_mangle)]
pub extern "C" fn soyokaze_pseudo_request_name(index: usize) -> Slice {
Slice::maybe(Fields::PSEUDO_REQUEST.get(index).copied())
}
#[unsafe(no_mangle)]
pub extern "C" fn soyokaze_pseudo_response_count() -> usize {
Fields::PSEUDO_RESPONSE.len()
}
#[unsafe(no_mangle)]
pub extern "C" fn soyokaze_pseudo_response_name(index: usize) -> Slice {
Slice::maybe(Fields::PSEUDO_RESPONSE.get(index).copied())
}
#[unsafe(no_mangle)]
pub extern "C" fn soyokaze_connection_specific_count() -> usize {
Fields::CONNECTION_SPECIFIC.len()
}
#[unsafe(no_mangle)]
pub extern "C" fn soyokaze_connection_specific_name(index: usize) -> Slice {
Slice::maybe(Fields::CONNECTION_SPECIFIC.get(index).copied())
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_connection_specific(name: *const u8, name_len: usize) -> bool {
match unsafe { Slice::borrow_text(name, name_len) } {
Some(name) => Fields::connection_specific(name),
None => false,
}
}
#[unsafe(no_mangle)]
pub extern "C" fn soyokaze_pseudo_status(status_code: u16) -> Octets {
Octets::new(Fields::status(status_code).into_bytes())
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_fields_of_message(message: *const Message, out: *mut *mut FieldSection, error: *mut *mut ErrorHandle) -> Status {
let Some(message) = (unsafe { message.as_ref() }) else {
return unsafe { ErrorHandle::raise(error, Status::Invalid) };
};
match Fields::of(message) {
Ok(fields) => {
if !out.is_null() {
unsafe { *out = Box::into_raw(Box::new(FieldSection(fields))) };
}
Status::Ok
}
Err(failure) => unsafe { ErrorHandle::report(error, &failure) },
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_fields_to_message(fields: *const FieldSection, version: i32, out: *mut *mut Message, error: *mut *mut ErrorHandle) -> Status {
let version = Version::of(version);
let Some(fields) = (unsafe { fields.as_ref() }) else {
return unsafe { ErrorHandle::raise(error, Status::Invalid) };
};
match Fields::message(&fields.0, version) {
Ok(message) => {
if !out.is_null() {
unsafe { *out = Box::into_raw(Box::new(message)) };
}
Status::Ok
}
Err(failure) => unsafe { ErrorHandle::report(error, &failure) },
}
}