iceoryx2_ffi/api/
sample_mut.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, IntoCInt, UserHeaderFfi, IOX2_OK,
18};
19
20use iceoryx2::prelude::*;
21use iceoryx2::sample_mut_uninit::SampleMutUninit;
22use iceoryx2_bb_elementary::static_assert::*;
23use iceoryx2_ffi_macros::iceoryx2_ffi;
24
25use core::ffi::{c_int, c_void};
26use core::mem::ManuallyDrop;
27
28use super::UninitPayloadFfi;
29
30pub(super) union SampleMutUninitUnion {
33 ipc: ManuallyDrop<SampleMutUninit<ipc::Service, UninitPayloadFfi, UserHeaderFfi>>,
34 local: ManuallyDrop<SampleMutUninit<local::Service, UninitPayloadFfi, UserHeaderFfi>>,
35}
36
37impl SampleMutUninitUnion {
38 pub(super) fn new_ipc(
39 sample: SampleMutUninit<ipc::Service, UninitPayloadFfi, UserHeaderFfi>,
40 ) -> Self {
41 Self {
42 ipc: ManuallyDrop::new(sample),
43 }
44 }
45 pub(super) fn new_local(
46 sample: SampleMutUninit<local::Service, UninitPayloadFfi, UserHeaderFfi>,
47 ) -> Self {
48 Self {
49 local: ManuallyDrop::new(sample),
50 }
51 }
52}
53
54#[repr(C)]
55#[repr(align(8))] pub struct iox2_sample_mut_storage_t {
57 internal: [u8; 56], }
59
60#[repr(C)]
61#[iceoryx2_ffi(SampleMutUninitUnion)]
62pub struct iox2_sample_mut_t {
63 service_type: iox2_service_type_e,
64 value: iox2_sample_mut_storage_t,
65 deleter: fn(*mut iox2_sample_mut_t),
66}
67
68impl iox2_sample_mut_t {
69 pub(super) fn init(
70 &mut self,
71 service_type: iox2_service_type_e,
72 value: SampleMutUninitUnion,
73 deleter: fn(*mut iox2_sample_mut_t),
74 ) {
75 self.service_type = service_type;
76 self.value.init(value);
77 self.deleter = deleter;
78 }
79}
80
81pub struct iox2_sample_mut_h_t;
82pub type iox2_sample_mut_h = *mut iox2_sample_mut_h_t;
84pub type iox2_sample_mut_h_ref = *const iox2_sample_mut_h;
86
87impl AssertNonNullHandle for iox2_sample_mut_h {
88 fn assert_non_null(self) {
89 debug_assert!(!self.is_null());
90 }
91}
92
93impl AssertNonNullHandle for iox2_sample_mut_h_ref {
94 fn assert_non_null(self) {
95 debug_assert!(!self.is_null());
96 unsafe {
97 debug_assert!(!(*self).is_null());
98 }
99 }
100}
101
102impl HandleToType for iox2_sample_mut_h {
103 type Target = *mut iox2_sample_mut_t;
104
105 fn as_type(self) -> Self::Target {
106 self as *mut _ as _
107 }
108}
109
110impl HandleToType for iox2_sample_mut_h_ref {
111 type Target = *mut iox2_sample_mut_t;
112
113 fn as_type(self) -> Self::Target {
114 unsafe { *self as *mut _ as _ }
115 }
116}
117
118#[doc(hidden)]
130#[no_mangle]
131pub unsafe extern "C" fn iox2_sample_mut_move(
132 source_struct_ptr: *mut iox2_sample_mut_t,
133 dest_struct_ptr: *mut iox2_sample_mut_t,
134 dest_handle_ptr: *mut iox2_sample_mut_h,
135) {
136 debug_assert!(!source_struct_ptr.is_null());
137 debug_assert!(!dest_struct_ptr.is_null());
138 debug_assert!(!dest_handle_ptr.is_null());
139
140 let source = &mut *source_struct_ptr;
141 let dest = &mut *dest_struct_ptr;
142
143 dest.service_type = source.service_type;
144 dest.value.init(
145 source
146 .value
147 .as_option_mut()
148 .take()
149 .expect("Source must have a valid sample"),
150 );
151 dest.deleter = source.deleter;
152
153 *dest_handle_ptr = (*dest_struct_ptr).as_handle();
154}
155
156#[no_mangle]
163pub unsafe extern "C" fn iox2_sample_mut_user_header(
164 handle: iox2_sample_mut_h_ref,
165 header_ptr: *mut *const c_void,
166) {
167 handle.assert_non_null();
168 debug_assert!(!header_ptr.is_null());
169
170 let sample = &mut *handle.as_type();
171
172 let header = match sample.service_type {
173 iox2_service_type_e::IPC => sample.value.as_mut().ipc.user_header(),
174 iox2_service_type_e::LOCAL => sample.value.as_mut().local.user_header(),
175 };
176
177 *header_ptr = (header as *const UserHeaderFfi).cast();
178}
179
180#[no_mangle]
189pub unsafe extern "C" fn iox2_sample_mut_header(
190 handle: iox2_sample_mut_h_ref,
191 header_struct_ptr: *mut iox2_publish_subscribe_header_t,
192 header_handle_ptr: *mut iox2_publish_subscribe_header_h,
193) {
194 handle.assert_non_null();
195 debug_assert!(!header_handle_ptr.is_null());
196
197 fn no_op(_: *mut iox2_publish_subscribe_header_t) {}
198 let mut deleter: fn(*mut iox2_publish_subscribe_header_t) = no_op;
199 let mut storage_ptr = header_struct_ptr;
200 if header_struct_ptr.is_null() {
201 deleter = iox2_publish_subscribe_header_t::dealloc;
202 storage_ptr = iox2_publish_subscribe_header_t::alloc();
203 }
204 debug_assert!(!storage_ptr.is_null());
205
206 let sample = &mut *handle.as_type();
207
208 let header = *match sample.service_type {
209 iox2_service_type_e::IPC => sample.value.as_mut().ipc.header(),
210 iox2_service_type_e::LOCAL => sample.value.as_mut().local.header(),
211 };
212
213 (*storage_ptr).init(header, deleter);
214 *header_handle_ptr = (*storage_ptr).as_handle();
215}
216
217#[no_mangle]
224pub unsafe extern "C" fn iox2_sample_mut_user_header_mut(
225 handle: iox2_sample_mut_h_ref,
226 header_ptr: *mut *mut c_void,
227) {
228 handle.assert_non_null();
229 debug_assert!(!header_ptr.is_null());
230
231 let sample = &mut *handle.as_type();
232
233 let header = match sample.service_type {
234 iox2_service_type_e::IPC => sample.value.as_mut().ipc.user_header_mut(),
235 iox2_service_type_e::LOCAL => sample.value.as_mut().local.user_header_mut(),
236 };
237
238 *header_ptr = (header as *mut UserHeaderFfi).cast();
239}
240
241#[no_mangle]
249pub unsafe extern "C" fn iox2_sample_mut_payload_mut(
250 handle: iox2_sample_mut_h_ref,
251 payload_ptr: *mut *mut c_void,
252 payload_len: *mut c_size_t,
253) {
254 handle.assert_non_null();
255 debug_assert!(!payload_ptr.is_null());
256
257 let sample = &mut *handle.as_type();
258
259 let payload = match sample.service_type {
260 iox2_service_type_e::IPC => sample.value.as_mut().ipc.payload_mut(),
261 iox2_service_type_e::LOCAL => sample.value.as_mut().local.payload_mut(),
262 };
263
264 *payload_ptr = payload.as_mut_ptr().cast();
265 if !payload_len.is_null() {
266 *payload_len = payload.len();
267 }
268}
269
270#[no_mangle]
278pub unsafe extern "C" fn iox2_sample_mut_payload(
279 handle: iox2_sample_mut_h_ref,
280 payload_ptr: *mut *const c_void,
281 payload_len: *mut c_size_t,
282) {
283 handle.assert_non_null();
284 debug_assert!(!payload_ptr.is_null());
285
286 let sample = &mut *handle.as_type();
287
288 let payload = match sample.service_type {
289 iox2_service_type_e::IPC => sample.value.as_mut().ipc.payload(),
290 iox2_service_type_e::LOCAL => sample.value.as_mut().local.payload(),
291 };
292
293 *payload_ptr = payload.as_ptr().cast();
294 if !payload_len.is_null() {
295 *payload_len = payload.len();
296 }
297}
298
299#[no_mangle]
307pub unsafe extern "C" fn iox2_sample_mut_send(
308 sample_handle: iox2_sample_mut_h,
309 number_of_recipients: *mut c_size_t,
310) -> c_int {
311 debug_assert!(!sample_handle.is_null());
312
313 let sample_struct = &mut *sample_handle.as_type();
314 let service_type = sample_struct.service_type;
315
316 let sample = sample_struct
317 .value
318 .as_option_mut()
319 .take()
320 .unwrap_or_else(|| panic!("Trying to send an already sent sample!"));
321 (sample_struct.deleter)(sample_struct);
322
323 match service_type {
324 iox2_service_type_e::IPC => {
325 let sample = ManuallyDrop::into_inner(sample.ipc);
326 match sample.assume_init().send() {
327 Ok(v) => {
328 if !number_of_recipients.is_null() {
329 *number_of_recipients = v;
330 }
331 }
332 Err(e) => {
333 return e.into_c_int();
334 }
335 }
336 }
337 iox2_service_type_e::LOCAL => {
338 let sample = ManuallyDrop::into_inner(sample.local);
339 match sample.assume_init().send() {
340 Ok(v) => {
341 if !number_of_recipients.is_null() {
342 *number_of_recipients = v;
343 }
344 }
345 Err(e) => {
346 return e.into_c_int();
347 }
348 }
349 }
350 }
351
352 IOX2_OK
353}
354
355#[no_mangle]
367pub unsafe extern "C" fn iox2_sample_mut_drop(sample_handle: iox2_sample_mut_h) {
368 debug_assert!(!sample_handle.is_null());
369
370 let sample = &mut *sample_handle.as_type();
371
372 match sample.service_type {
373 iox2_service_type_e::IPC => {
374 ManuallyDrop::drop(&mut sample.value.as_mut().ipc);
375 }
376 iox2_service_type_e::LOCAL => {
377 ManuallyDrop::drop(&mut sample.value.as_mut().local);
378 }
379 }
380 (sample.deleter)(sample);
381}
382
383