1#![allow(missing_docs, clippy::derive_partial_eq_without_eq)]
2
3use std::{
4 ffi::{c_void, CString},
5 os::raw,
6};
7
8use crate::{
9 dart_array::DartArray,
10 into_dart::{
11 visit_dart_typed_data_type, DartTypedDataTypeTrait,
12 DartTypedDataTypeVisitor,
13 },
14};
15
16pub type DartPort = i64;
18
19#[repr(i32)]
20#[derive(Copy, Clone, PartialEq, Debug)]
21pub enum DartTypedDataType {
22 ByteData = 0,
23 Int8 = 1,
24 Uint8 = 2,
25 Uint8Clamped = 3,
26 Int16 = 4,
27 Uint16 = 5,
28 Int32 = 6,
29 Uint32 = 7,
30 Int64 = 8,
31 Uint64 = 9,
32 Float32 = 10,
33 Float64 = 11,
34 Float32x4 = 12,
35 Invalid = 13,
36}
37
38#[repr(i32)]
58#[derive(PartialEq, Debug, Clone, Copy)]
59pub enum DartCObjectType {
60 DartNull = 0,
61 DartBool = 1,
62 DartInt32 = 2,
63 DartInt64 = 3,
64 DartDouble = 4,
65 DartString = 5,
66 DartArray = 6,
67 DartTypedData = 7,
68 DartExternalTypedData = 8,
69 DartSendPort = 9,
70 DartCapability = 10,
71 DartNativePointer = 11,
72 DartUnsupported = 12,
73 DartNumberOfTypes = 13,
74}
75
76#[allow(missing_debug_implementations)]
77#[repr(C)]
78pub struct DartCObject {
79 pub ty: DartCObjectType,
80 pub value: DartCObjectValue,
81}
82
83#[allow(missing_debug_implementations)]
84#[repr(C)]
85#[derive(Clone, Copy)]
86pub union DartCObjectValue {
87 pub as_bool: bool,
88 pub as_int32: i32,
89 pub as_int64: i64,
90 pub as_double: f64,
91 pub as_string: *mut raw::c_char,
92 pub as_send_port: DartNativeSendPort,
93 pub as_capability: DartNativeCapability,
94 pub as_array: DartNativeArray,
95 pub as_typed_data: DartNativeTypedData,
96 pub as_external_typed_data: DartNativeExternalTypedData,
97 pub as_native_pointer: DartNativePointer,
98 _bindgen_union_align: [u64; 5usize],
99}
100
101#[repr(C)]
102#[derive(Debug, Copy, Clone)]
103pub struct DartNativeSendPort {
104 pub id: DartPort,
105 pub origin_id: DartPort,
106}
107
108#[repr(C)]
109#[derive(Debug, Copy, Clone)]
110pub struct DartNativeCapability {
111 pub id: i64,
112}
113
114#[repr(C)]
115#[derive(Debug, Copy, Clone)]
116pub struct DartNativeArray {
117 pub length: isize,
118 pub values: *mut *mut DartCObject,
119}
120
121#[repr(C)]
122#[derive(Debug, Copy, Clone)]
123pub struct DartNativeTypedData {
124 pub ty: DartTypedDataType,
125 pub length: isize, pub values: *mut u8,
127}
128
129#[repr(C)]
130#[derive(Debug, Copy, Clone)]
131pub struct DartNativeExternalTypedData {
132 pub ty: DartTypedDataType,
133 pub length: isize, pub data: *mut u8,
135 pub peer: *mut c_void,
136 pub callback: DartHandleFinalizer,
137}
138
139#[repr(C)]
140#[derive(Debug, Copy, Clone)]
141pub struct DartNativePointer {
142 pub ptr: isize,
143 pub size: isize,
144 pub callback: DartHandleFinalizer,
145}
146
147pub type DartHandleFinalizer =
149 unsafe extern "C" fn(isolate_callback_data: *mut c_void, peer: *mut c_void);
150
151#[derive(Debug, Clone)]
154pub struct ZeroCopyBuffer<T>(pub T);
155
156pub type DartPostCObjectFnType =
170 unsafe extern "C" fn(port_id: DartPort, message: *mut DartCObject) -> bool;
171
172impl Drop for DartCObject {
173 fn drop(&mut self) {
174 match self.ty {
175 DartCObjectType::DartString => {
176 let _ = unsafe { CString::from_raw(self.value.as_string) };
177 },
178 DartCObjectType::DartArray => {
179 let _ = DartArray::from(unsafe { self.value.as_array });
180 },
181 DartCObjectType::DartTypedData => {
182 struct MyVisitor<'a>(&'a DartNativeTypedData);
183 impl DartTypedDataTypeVisitor for MyVisitor<'_> {
184 fn visit<T: DartTypedDataTypeTrait>(&self) {
185 if self.0.values.is_null() {
186 return;
187 }
188 let _ = unsafe {
189 Vec::from_raw_parts(
190 self.0.values as *mut T,
191 self.0.length as usize,
192 self.0.length as usize,
193 )
194 };
195 }
196 }
197
198 let v = unsafe { self.value.as_typed_data };
199 visit_dart_typed_data_type(v.ty, &MyVisitor(&v));
200 },
201 DartCObjectType::DartNull
204 | DartCObjectType::DartBool
205 | DartCObjectType::DartInt32
206 | DartCObjectType::DartInt64
207 | DartCObjectType::DartDouble => {
208 },
210 DartCObjectType::DartExternalTypedData => {
211 },
214 DartCObjectType::DartSendPort
215 | DartCObjectType::DartCapability
216 | DartCObjectType::DartUnsupported
217 | DartCObjectType::DartNumberOfTypes => {
218 },
220 DartCObjectType::DartNativePointer => {
221 },
224 }
225 }
226}
227
228#[doc(hidden)]
230pub unsafe fn run_destructors(obj: &DartCObject) {
231 use DartCObjectType::*;
232 match obj.ty {
233 DartExternalTypedData => unsafe {
234 (obj.value.as_external_typed_data.callback)(
235 obj.value.as_external_typed_data.data as *mut c_void,
236 obj.value.as_external_typed_data.peer,
237 )
238 },
239 DartArray => {
240 let items = unsafe {
241 std::slice::from_raw_parts_mut(
242 obj.value.as_array.values,
243 obj.value.as_array.length as usize,
244 )
245 };
246 for item in items {
247 run_destructors(&**item)
248 }
249 },
250 _ => {},
251 }
252}