iceoryx2_ffi/api/
sample.rs1#![allow(non_camel_case_types)]
14
15use crate::api::{
16 c_size_t, iox2_publish_subscribe_header_h, iox2_publish_subscribe_header_t,
17 iox2_service_type_e, AssertNonNullHandle, HandleToType, PayloadFfi, UserHeaderFfi,
18};
19
20use iceoryx2::prelude::*;
21use iceoryx2::sample::Sample;
22use iceoryx2_bb_elementary::static_assert::*;
23use iceoryx2_ffi_macros::iceoryx2_ffi;
24
25use core::ffi::c_void;
26use core::mem::ManuallyDrop;
27
28pub(super) union SampleUnion {
31 ipc: ManuallyDrop<Sample<ipc::Service, PayloadFfi, UserHeaderFfi>>,
32 local: ManuallyDrop<Sample<local::Service, PayloadFfi, UserHeaderFfi>>,
33}
34
35impl SampleUnion {
36 pub(super) fn new_ipc(sample: Sample<ipc::Service, PayloadFfi, UserHeaderFfi>) -> Self {
37 Self {
38 ipc: ManuallyDrop::new(sample),
39 }
40 }
41 pub(super) fn new_local(sample: Sample<local::Service, PayloadFfi, UserHeaderFfi>) -> Self {
42 Self {
43 local: ManuallyDrop::new(sample),
44 }
45 }
46}
47
48#[repr(C)]
49#[repr(align(8))] pub struct iox2_sample_storage_t {
51 internal: [u8; 80], }
53
54#[repr(C)]
55#[iceoryx2_ffi(SampleUnion)]
56pub struct iox2_sample_t {
57 service_type: iox2_service_type_e,
58 value: iox2_sample_storage_t,
59 deleter: fn(*mut iox2_sample_t),
60}
61
62impl iox2_sample_t {
63 pub(super) fn init(
64 &mut self,
65 service_type: iox2_service_type_e,
66 value: SampleUnion,
67 deleter: fn(*mut iox2_sample_t),
68 ) {
69 self.service_type = service_type;
70 self.value.init(value);
71 self.deleter = deleter;
72 }
73}
74
75pub struct iox2_sample_h_t;
76pub type iox2_sample_h = *mut iox2_sample_h_t;
78pub type iox2_sample_h_ref = *const iox2_sample_h;
80
81impl AssertNonNullHandle for iox2_sample_h {
82 fn assert_non_null(self) {
83 debug_assert!(!self.is_null());
84 }
85}
86
87impl AssertNonNullHandle for iox2_sample_h_ref {
88 fn assert_non_null(self) {
89 debug_assert!(!self.is_null());
90 unsafe {
91 debug_assert!(!(*self).is_null());
92 }
93 }
94}
95
96impl HandleToType for iox2_sample_h {
97 type Target = *mut iox2_sample_t;
98
99 fn as_type(self) -> Self::Target {
100 self as *mut _ as _
101 }
102}
103
104impl HandleToType for iox2_sample_h_ref {
105 type Target = *mut iox2_sample_t;
106
107 fn as_type(self) -> Self::Target {
108 unsafe { *self as *mut _ as _ }
109 }
110}
111
112#[doc(hidden)]
124#[no_mangle]
125pub unsafe extern "C" fn iox2_sample_move(
126 source_struct_ptr: *mut iox2_sample_t,
127 dest_struct_ptr: *mut iox2_sample_t,
128 dest_handle_ptr: *mut iox2_sample_h,
129) {
130 debug_assert!(!source_struct_ptr.is_null());
131 debug_assert!(!dest_struct_ptr.is_null());
132 debug_assert!(!dest_handle_ptr.is_null());
133
134 let source = &mut *source_struct_ptr;
135 let dest = &mut *dest_struct_ptr;
136
137 dest.service_type = source.service_type;
138 dest.value.init(
139 source
140 .value
141 .as_option_mut()
142 .take()
143 .expect("Source must have a valid sample"),
144 );
145 dest.deleter = source.deleter;
146
147 *dest_handle_ptr = (*dest_struct_ptr).as_handle();
148}
149
150#[no_mangle]
159pub unsafe extern "C" fn iox2_sample_header(
160 handle: iox2_sample_h_ref,
161 header_struct_ptr: *mut iox2_publish_subscribe_header_t,
162 header_handle_ptr: *mut iox2_publish_subscribe_header_h,
163) {
164 handle.assert_non_null();
165 debug_assert!(!header_handle_ptr.is_null());
166
167 fn no_op(_: *mut iox2_publish_subscribe_header_t) {}
168 let mut deleter: fn(*mut iox2_publish_subscribe_header_t) = no_op;
169 let mut storage_ptr = header_struct_ptr;
170 if header_struct_ptr.is_null() {
171 deleter = iox2_publish_subscribe_header_t::dealloc;
172 storage_ptr = iox2_publish_subscribe_header_t::alloc();
173 }
174 debug_assert!(!storage_ptr.is_null());
175
176 let sample = &mut *handle.as_type();
177
178 let header = *match sample.service_type {
179 iox2_service_type_e::IPC => sample.value.as_mut().ipc.header(),
180 iox2_service_type_e::LOCAL => sample.value.as_mut().local.header(),
181 };
182
183 (*storage_ptr).init(header, deleter);
184 *header_handle_ptr = (*storage_ptr).as_handle();
185}
186
187#[no_mangle]
194pub unsafe extern "C" fn iox2_sample_user_header(
195 handle: iox2_sample_h_ref,
196 header_ptr: *mut *const c_void,
197) {
198 handle.assert_non_null();
199 debug_assert!(!header_ptr.is_null());
200
201 let sample = &mut *handle.as_type();
202
203 let header = match sample.service_type {
204 iox2_service_type_e::IPC => sample.value.as_mut().ipc.user_header(),
205 iox2_service_type_e::LOCAL => sample.value.as_mut().local.user_header(),
206 };
207
208 *header_ptr = (header as *const UserHeaderFfi).cast();
209}
210
211#[no_mangle]
219pub unsafe extern "C" fn iox2_sample_payload(
220 handle: iox2_sample_h_ref,
221 payload_ptr: *mut *const c_void,
222 payload_len: *mut c_size_t,
223) {
224 handle.assert_non_null();
225 debug_assert!(!payload_ptr.is_null());
226
227 let sample = &mut *handle.as_type();
228
229 let payload = match sample.service_type {
230 iox2_service_type_e::IPC => sample.value.as_mut().ipc.payload(),
231 iox2_service_type_e::LOCAL => sample.value.as_mut().local.payload(),
232 };
233
234 *payload_ptr = payload.as_ptr().cast();
235 if !payload_len.is_null() {
236 *payload_len = payload.len();
237 }
238}
239
240#[no_mangle]
252pub unsafe extern "C" fn iox2_sample_drop(sample_handle: iox2_sample_h) {
253 debug_assert!(!sample_handle.is_null());
254
255 let sample = &mut *sample_handle.as_type();
256
257 match sample.service_type {
258 iox2_service_type_e::IPC => {
259 ManuallyDrop::drop(&mut sample.value.as_mut().ipc);
260 }
261 iox2_service_type_e::LOCAL => {
262 ManuallyDrop::drop(&mut sample.value.as_mut().local);
263 }
264 }
265 (sample.deleter)(sample);
266}
267
268