1use std::convert::Infallible;
2use std::fmt::{Debug, Display, Formatter};
3use std::ops::FromResidual;
4
5use flatbuffers::FlatBufferBuilder;
6#[cfg(debug_assertions)]
7use tracing::error;
8
9#[no_mangle]
10pub extern "C" fn no_mangle_types(_: Buffer, _: FFIResult) {
11 unimplemented!()
12}
13
14#[no_mangle]
15pub extern "C" fn free_buffer(free_type: OriginType, free_ptr: usize) {
16 unsafe {
17 match free_type {
18 OriginType::Vec => {
19 #[cfg(debug_assertions)] println!("OriginType::Vec, free_ptr={}", free_ptr);
20 let ptr = free_ptr as *mut Vec<u8>;
21 if ptr.is_null() {
22 return;
23 }
24 let _ = Box::from_raw(ptr);
25 }
26 OriginType::FlatBuffer => {
27 #[cfg(debug_assertions)] println!("OriginType::FlatBuffer, free_ptr={}", free_ptr);
28 let ptr = free_ptr as *mut FlatBufferBuilder;
29 if ptr.is_null() {
30 return;
31 }
32 let _ = Box::from_raw(ptr);
33 }
34 };
35 }
36}
37
38pub fn callback<'a, Request, Response, F>(_ffi_method_name: &'static str, method_fn: F, args: &'a mut Buffer) -> FFIResult
39 where Request: ABIRequest<'a>,
40 Response: ABIResponse,
41 F: Fn(Request) -> ABIResult<Response> {
42 let args_obj = match Request::try_from_bytes(args.read_mut().unwrap_or_default()) {
43 Ok(args_obj) => args_obj,
44 Err(err) => return FFIResult::err(ResultCode::Decode, Some(err)),
45 };
46
47 #[cfg(debug_assertions)]
48 let txt = format!("invoking method={}, args_obj={:?}", _ffi_method_name, args_obj);
49
50 let res_obj: ABIResult<Response> = method_fn(args_obj);
51
52 #[cfg(debug_assertions)]
53 let txt = format!("{}, abi_result={:?}", txt, res_obj);
54
55 let res = FFIResult::from(res_obj);
56
57 #[cfg(debug_assertions)]
58 println!("{}, ffi_result={:?}", txt, res);
59
60 res
61}
62
63#[derive(Copy, Clone, Debug)]
64#[repr(C)]
65pub struct Buffer {
66 pub ptr: *mut u8,
67 pub len: usize,
68 pub cap: usize,
69}
70
71impl Display for Buffer {
72 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
73 write!(f, "{:?}", self.read())
74 }
75}
76
77impl Buffer {
78 pub const fn null() -> Self {
79 Self {
80 ptr: std::ptr::null_mut(),
81 len: 0,
82 cap: 0,
83 }
84 }
85
86 pub fn read(&self) -> Option<&[u8]> {
90 if self.is_empty() {
91 None
92 } else {
93 unsafe { Some(std::slice::from_raw_parts(self.ptr, self.len)) }
94 }
95 }
96
97 pub fn read_mut(&mut self) -> Option<&mut [u8]> {
101 if self.is_empty() {
102 None
103 } else {
104 unsafe { Some(std::slice::from_raw_parts_mut(self.ptr, self.len)) }
105 }
106 }
107
108
109 pub(crate) fn is_empty(&self) -> bool {
110 self.ptr.is_null() || self.len == 0 || self.cap == 0
111 }
112}
113
114#[derive(Copy, Clone, Debug)]
115#[repr(C)]
116pub struct LeakBuffer {
117 pub(crate) free_type: OriginType,
118 pub(crate) free_ptr: usize,
119 pub(crate) buffer: Buffer,
120}
121
122
123impl LeakBuffer {
124 pub unsafe fn mem_free(self) {
125 free_buffer(self.free_type, self.free_ptr)
126 }
127
128 pub const fn null() -> Self {
129 Self {
130 free_type: OriginType::Vec,
131 free_ptr: 0,
132 buffer: Buffer::null(),
133 }
134 }
135
136 pub(crate) fn from_vec(mut v: Vec<u8>) -> Self {
138 let mut buf = Self {
139 free_type: OriginType::Vec,
140 free_ptr: 0,
141 buffer: Buffer {
142 ptr: v.as_mut_ptr(),
143 len: v.len(),
144 cap: v.capacity(),
145 },
146 };
147 buf.free_ptr = Box::into_raw(Box::new(v)) as usize;
148 buf
150 }
151 pub(crate) fn is_empty(&self) -> bool {
152 self.free_ptr == 0 || self.buffer.is_empty()
153 }
154 pub fn read(&self) -> Option<&[u8]> {
155 if self.is_empty() {
156 None
157 } else {
158 unsafe { Some(std::slice::from_raw_parts(self.buffer.ptr, self.buffer.len)) }
159 }
160 }
161 pub fn read_mut(&mut self) -> Option<&mut [u8]> {
162 if self.is_empty() {
163 None
164 } else {
165 unsafe { Some(std::slice::from_raw_parts_mut(self.buffer.ptr, self.buffer.len)) }
166 }
167 }
168 pub fn buffer(&self) -> Buffer {
181 self.buffer
182 }
183}
184
185
186#[derive(Debug, Clone, Copy)]
187#[repr(C)]
188pub enum ResultCode {
189 NoError = 0,
190 Decode = 1,
191 Encode = 2,
192}
193
194#[allow(dead_code)]
195#[derive(Debug, Clone, Copy)]
196#[repr(C)]
197pub enum OriginType {
198 Vec = 0,
199 FlatBuffer = 1,
200}
201
202#[derive(Debug)]
203#[repr(C)]
204pub struct FFIResult {
205 pub code: ResultCode,
206 pub data: LeakBuffer,
207}
208
209impl FFIResult {
210 pub fn ok(data: LeakBuffer) -> Self {
211 Self { code: ResultCode::NoError, data }
212 }
213 pub(crate) fn err<E: Debug>(code: ResultCode, _err: Option<E>) -> Self {
214 #[cfg(debug_assertions)]{
215 if let Some(err) = _err {
216 error!("{:?}", err);
217 }
218 }
219 Self { code, data: LeakBuffer::null() }
220 }
221}
222
223pub type ABIResult<T> = Result<T, ResultCode>;
224
225impl<T: ABIResponse> From<ABIResult<T>> for FFIResult {
226 fn from(value: ABIResult<T>) -> Self {
227 match value {
228 Ok(v) => match v.try_into_buffer() {
229 Ok(v) => Self::ok(v),
230 Err(e) => Self::err(ResultCode::Encode, Some(e)),
231 },
232 Err(e) => Self::err(ResultCode::Encode, Some(e))
233 }
234 }
235}
236
237impl<'a, T: ABIRequest<'a>> From<&'a mut FFIResult> for ABIResult<T> {
238 fn from(value: &'a mut FFIResult) -> Self {
239 match value.code {
240 ResultCode::NoError => {
241 ABIRequest::try_from_bytes(value.data.read_mut().unwrap_or_default())
242 .map_err(|_err| {
243 #[cfg(debug_assertions)]{
244 error!("{:?}", _err);
245 }
246 ResultCode::Decode
247 })
248 }
249 code => Err(code)
250 }
251 }
252}
253
254pub trait ABIMessage<'a>: ABIRequest<'a> + ABIResponse {}
255
256pub trait ABIRequest<'a>: Debug {
257 type DecodeError: Debug;
258 fn try_from_bytes(buf: &'a mut [u8]) -> Result<Self, Self::DecodeError> where Self: Sized;
259}
260
261pub trait ABIResponse: Debug {
262 type EncodeError: Debug;
263 const ORIGIN_TYPE_FOR_FREE: OriginType;
264 fn try_into_buffer(self) -> Result<LeakBuffer, Self::EncodeError>;
265}
266
267impl FromResidual<Result<Infallible, ResultCode>> for FFIResult {
268 fn from_residual(residual: Result<Infallible, ResultCode>) -> Self {
269 Self { code: residual.unwrap_err(), data: LeakBuffer::null() }
270 }
271}
272
273#[test]
274fn test_free() {
275 let buf = LeakBuffer::from_vec(vec![0, 1, 2, 3, 4, 5, 6, 7, 8]);
276 println!("{:?}", buf.read());
277 {
278 println!("{:?}", unsafe { Vec::from_raw_parts(buf.buffer.ptr, buf.buffer.len, buf.buffer.cap) });
279 }
280 println!("{:?}", buf.read());
281}