use crate::errors::Error;
use crate::ffi::errors::{ErrorHandle, Status};
use crate::ffi::helpers::fields::{Field, Fields};
use crate::ffi::{Buffer, Slice};
use crate::helpers::qpack::{Decoder, Encoder};
#[unsafe(no_mangle)]
pub extern "C" fn soyokaze_qpack_encoder_new() -> *mut Encoder {
Box::into_raw(Box::new(Encoder::new()))
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_qpack_encoder_free(encoder: *mut Encoder) {
if !encoder.is_null() {
drop(unsafe { Box::from_raw(encoder) });
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_qpack_encoder_set_max_capacity(encoder: *mut Encoder, max_capacity: usize, instructions: *mut Buffer) -> bool {
let Some(encoder) = (unsafe { encoder.as_mut() }) else {
return false;
};
if instructions.is_null() {
return false;
}
unsafe {
*instructions = match encoder.set_max_capacity(max_capacity) {
Some(instruction) => Buffer::new(instruction.encode()),
None => Buffer::EMPTY,
};
}
true
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_qpack_encoder_set_capacity_limit(encoder: *mut Encoder, capacity_limit: usize, instructions: *mut Buffer) -> bool {
let Some(encoder) = (unsafe { encoder.as_mut() }) else {
return false;
};
if instructions.is_null() {
return false;
}
unsafe {
*instructions = match encoder.set_capacity_limit(capacity_limit) {
Some(instruction) => Buffer::new(instruction.encode()),
None => Buffer::EMPTY,
};
}
true
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_qpack_encoder_set_max_outstanding_sections(encoder: *mut Encoder, max_sections: usize) -> bool {
let Some(encoder) = (unsafe { encoder.as_mut() }) else {
return false;
};
encoder.set_max_outstanding_sections(max_sections);
true
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_qpack_encoder_set_max_instruction_size(encoder: *mut Encoder, max_size: usize) -> bool {
let Some(encoder) = (unsafe { encoder.as_mut() }) else {
return false;
};
encoder.set_max_instruction_size(max_size);
true
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_qpack_encode(encoder: *mut Encoder, stream_id: u64, fields: *const Field, field_count: usize, block: *mut Buffer, instructions: *mut Buffer) -> bool {
let (Some(encoder), Some(fields)) = (unsafe { encoder.as_mut() }, unsafe { Field::parse_all(fields, field_count) }) else {
return false;
};
if block.is_null() || instructions.is_null() {
return false;
}
let encoded = encoder.encode(stream_id, &fields);
let stream = encoder.take_encoder_stream();
unsafe {
*block = Buffer::new(encoded);
*instructions = if stream.is_empty() { Buffer::EMPTY } else { Buffer::new(stream) };
}
true
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_qpack_encoder_on_decoder_instructions(encoder: *mut Encoder, data: *const u8, data_len: usize, error: *mut *mut ErrorHandle) -> Status {
let Some(encoder) = (unsafe { encoder.as_mut() }) else {
return unsafe { ErrorHandle::raise(error, Status::Invalid) };
};
let Some(data) = (unsafe { Slice::borrow(data, data_len) }) else {
return unsafe { ErrorHandle::raise(error, Status::Invalid) };
};
match encoder.on_decoder_stream(data) {
Ok(()) => Status::Ok,
Err(failure) => unsafe { ErrorHandle::report(error, &Error::from(failure)) },
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_qpack_encoder_cancel(encoder: *mut Encoder, stream_id: u64) -> bool {
let Some(encoder) = (unsafe { encoder.as_mut() }) else {
return false;
};
encoder.cancel(stream_id);
true
}
#[unsafe(no_mangle)]
pub extern "C" fn soyokaze_qpack_decoder_new() -> *mut Decoder {
Box::into_raw(Box::new(Decoder::new()))
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_qpack_decoder_free(decoder: *mut Decoder) {
if !decoder.is_null() {
drop(unsafe { Box::from_raw(decoder) });
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_qpack_decoder_set_max_decoded_size(decoder: *mut Decoder, max_size: usize) -> bool {
let Some(decoder) = (unsafe { decoder.as_mut() }) else {
return false;
};
decoder.set_max_decoded_size(max_size);
true
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_qpack_decoder_set_max_capacity(decoder: *mut Decoder, max_capacity: usize) -> bool {
let Some(decoder) = (unsafe { decoder.as_mut() }) else {
return false;
};
decoder.set_max_capacity(max_capacity);
true
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_qpack_decoder_set_max_instruction_size(decoder: *mut Decoder, max_size: usize) -> bool {
let Some(decoder) = (unsafe { decoder.as_mut() }) else {
return false;
};
decoder.set_max_instruction_size(max_size);
true
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_qpack_decoder_set_max_blocked_streams(decoder: *mut Decoder, max_streams: usize) -> bool {
let Some(decoder) = (unsafe { decoder.as_mut() }) else {
return false;
};
decoder.set_max_blocked_streams(max_streams);
true
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_qpack_decoder_on_encoder_instructions(decoder: *mut Decoder, data: *const u8, data_len: usize, instructions: *mut Buffer, error: *mut *mut ErrorHandle) -> Status {
let Some(decoder) = (unsafe { decoder.as_mut() }) else {
return unsafe { ErrorHandle::raise(error, Status::Invalid) };
};
let Some(data) = (unsafe { Slice::borrow(data, data_len) }) else {
return unsafe { ErrorHandle::raise(error, Status::Invalid) };
};
if instructions.is_null() {
return unsafe { ErrorHandle::raise(error, Status::Invalid) };
}
if let Err(failure) = decoder.on_encoder_stream(data) {
return unsafe { ErrorHandle::report(error, &Error::from(failure)) };
}
let stream = decoder.take_decoder_stream();
unsafe { *instructions = if stream.is_empty() { Buffer::EMPTY } else { Buffer::new(stream) } };
Status::Ok
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn soyokaze_qpack_decode(decoder: *mut Decoder, stream_id: u64, block: *const u8, block_len: usize, out: *mut *mut Fields, instructions: *mut Buffer, error: *mut *mut ErrorHandle) -> Status {
let Some(decoder) = (unsafe { decoder.as_mut() }) else {
return unsafe { ErrorHandle::raise(error, Status::Invalid) };
};
if out.is_null() || instructions.is_null() {
return unsafe { ErrorHandle::raise(error, Status::Invalid) };
}
let Some(block) = (unsafe { Slice::borrow(block, block_len) }) else {
return unsafe { ErrorHandle::raise(error, Status::Invalid) };
};
match decoder.decode(stream_id, block) {
Ok((fields, answer)) => {
unsafe {
*out = Box::into_raw(Box::new(Fields(fields)));
*instructions = match answer {
Some(answer) => Buffer::new(answer.encode()),
None => Buffer::EMPTY,
};
}
Status::Ok
}
Err(failure) => unsafe { ErrorHandle::report(error, &Error::from(failure)) },
}
}