#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct BufferFFI {
pub ptr: *const u8,
pub len: usize,
pub cap: usize,
}
impl BufferFFI {
pub const fn empty() -> Self {
Self {
ptr: core::ptr::null(),
len: 0,
cap: 0,
}
}
pub fn from_slice(data: &[u8]) -> Self {
Self {
ptr: data.as_ptr(),
len: data.len(),
cap: data.len(),
}
}
pub fn is_empty(&self) -> bool {
self.len == 0 || self.ptr.is_null()
}
pub unsafe fn as_slice(&self) -> &[u8] {
if self.is_empty() {
&[]
} else {
unsafe { core::slice::from_raw_parts(self.ptr, self.len) }
}
}
}
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct FieldFFI {
pub offset: usize,
pub size: usize,
pub align: usize,
pub field_type: u8,
}
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct LayoutFFI {
pub fields: *const FieldFFI,
pub field_count: usize,
pub field_names: *const BufferFFI,
pub bitvec_size: usize,
pub static_section_size: usize,
pub alignment: usize,
}
impl LayoutFFI {
pub const fn empty() -> Self {
Self {
fields: core::ptr::null(),
field_count: 0,
field_names: core::ptr::null(),
bitvec_size: 0,
static_section_size: 0,
alignment: 1,
}
}
pub unsafe fn get_field(&self, index: usize) -> Option<&FieldFFI> {
if index < self.field_count && !self.fields.is_null() {
unsafe { Some(&*self.fields.add(index)) }
} else {
None
}
}
pub fn is_defined(&self, encoded: &BufferFFI, index: usize) -> bool {
if index >= self.field_count || encoded.is_empty() {
return false;
}
let byte_index = index / 8;
let bit_index = index % 8;
if byte_index >= self.bitvec_size {
return false;
}
let bitvec_ptr = encoded.ptr;
let byte = unsafe { *bitvec_ptr.add(byte_index) };
(byte & (1 << bit_index)) != 0
}
pub const fn data_offset(&self) -> usize {
self.bitvec_size
}
pub const fn total_static_size(&self) -> usize {
self.bitvec_size + self.static_section_size
}
}
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct RowFFI {
pub number: u64,
pub encoded: BufferFFI,
pub layout: *const LayoutFFI,
}
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FlowDiffType {
Insert = 0,
Update = 1,
Remove = 2,
}
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct FlowDiffFFI {
pub diff_type: FlowDiffType,
pub pre_row: *const RowFFI,
pub post_row: *const RowFFI,
}
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct FlowOriginFFI {
pub origin_type: u8,
pub id: u64,
}
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct FlowChangeFFI {
pub origin: FlowOriginFFI,
pub diff_count: usize,
pub diffs: *const FlowDiffFFI,
pub version: u64,
}
impl FlowChangeFFI {
pub const fn empty() -> Self {
Self {
origin: FlowOriginFFI {
origin_type: 0,
id: 0,
},
diff_count: 0,
diffs: core::ptr::null(),
version: 0,
}
}
}
#[repr(C)]
#[derive(Debug)]
pub struct RowsFFI {
pub count: usize,
pub rows: *mut *const RowFFI,
}
use core::ffi::c_void;
use crate::HostCallbacks;
#[repr(C)]
pub struct FFIContext {
pub txn_ptr: *mut c_void,
pub operator_id: u64,
pub callbacks: HostCallbacks,
}
#[repr(C)]
pub struct StateIteratorFFI {
_opaque: [u8; 0],
}
#[repr(C)]
pub struct StoreIteratorFFI {
_opaque: [u8; 0],
}
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct FFIOperatorColumnDef {
pub name: BufferFFI,
pub base_type: u8,
pub constraint_type: u8,
pub constraint_param1: u32,
pub constraint_param2: u32,
pub description: BufferFFI,
}
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct FFIOperatorColumnDefs {
pub columns: *const FFIOperatorColumnDef,
pub column_count: usize,
}
impl FFIOperatorColumnDefs {
pub const fn empty() -> Self {
Self {
columns: core::ptr::null(),
column_count: 0,
}
}
}