use crate::ffi::errors::{ErrorHandle, Status};
use crate::ffi::{Buffer, Slice};
use crate::helpers::compression::{Coding, Compression};
use crate::models::Headers;
pub fn coding(code: i32) -> Option<Compression> {
let codings = std::iter::once(Compression::Auto).chain(Compression::CODINGS.iter().copied());
codings.into_iter().find(|compression| *compression as i32 == code)
}
#[unsafe(no_mangle)]
pub extern "C" fn soyokaze_compression_name(compression: i32) -> Slice {
match coding(compression) {
Some(compression) => Slice::text(compression.as_str()),
None => Slice::text(""),
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_compression_parse(token: *const u8, token_len: usize) -> i32 {
match unsafe { Slice::borrow_text(token, token_len) }.and_then(Compression::parse) {
Some(compression) => compression as i32,
None => -1,
}
}
#[unsafe(no_mangle)]
pub extern "C" fn soyokaze_compression_count() -> usize {
Compression::CODINGS.len()
}
#[unsafe(no_mangle)]
pub extern "C" fn soyokaze_compression_coding(index: usize) -> i32 {
match Compression::CODINGS.get(index) {
Some(compression) => *compression as i32,
None => -1,
}
}
#[unsafe(no_mangle)]
pub extern "C" fn soyokaze_compression_accepted_field() -> Slice {
Slice::text(Compression::ACCEPTED)
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_compression_accepted(headers: *const Headers) -> i32 {
let Some(headers) = (unsafe { headers.as_ref() }) else {
return -1;
};
match Compression::accepted(headers.get_all("accept-encoding")) {
Some(compression) => compression as i32,
None => -1,
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_compression_applied(headers: *const Headers) -> i32 {
let Some(headers) = (unsafe { headers.as_ref() }) else {
return -1;
};
match Compression::applied(headers.get_all("content-encoding")) {
Some(compression) => compression as i32,
None => -1,
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_compression_encoded(headers: *const Headers) -> bool {
match unsafe { headers.as_ref() } {
Some(headers) => Compression::encoded(headers.get_all("content-encoding")),
None => false,
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_compression_quality(entry: *const u8, entry_len: usize) -> f32 {
match unsafe { Slice::borrow_text(entry, entry_len) } {
Some(entry) => Coding::parse(entry).quality,
None => -1.0,
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_compression_qvalue(text: *const u8, text_len: usize) -> f32 {
match unsafe { Slice::borrow_text(text, text_len) }.and_then(Coding::qvalue) {
Some(quality) => quality,
None => -1.0,
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_compression_encode(compression: i32, data: *const u8, data_len: usize, out: *mut Buffer, error: *mut *mut ErrorHandle) -> Status {
let (Some(compression), Some(data)) = (coding(compression), unsafe { Slice::borrow(data, data_len) }) else {
return unsafe { ErrorHandle::raise(error, Status::Invalid) };
};
match compression.encode(data) {
Ok(encoded) => {
if !out.is_null() {
unsafe { *out = Buffer::new(encoded.to_vec()) };
}
Status::Ok
}
Err(failure) => unsafe { ErrorHandle::report(error, &failure.into()) },
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_compression_decode(compression: i32, data: *const u8, data_len: usize, max: u64, out: *mut Buffer, error: *mut *mut ErrorHandle) -> Status {
let (Some(compression), Some(data)) = (coding(compression), unsafe { Slice::borrow(data, data_len) }) else {
return unsafe { ErrorHandle::raise(error, Status::Invalid) };
};
match compression.decode(data, max) {
Ok(decoded) => {
if !out.is_null() {
unsafe { *out = Buffer::new(decoded.to_vec()) };
}
Status::Ok
}
Err(failure) => unsafe { ErrorHandle::report(error, &failure.into()) },
}
}