From 1da7cbdd758349495d6392413dfd4bee92885fbf Mon Sep 17 00:00:00 2001 From: Jeff Ithier Date: Fri, 1 Nov 2024 14:23:24 +0100 Subject: [PATCH] [#490] Calculate number of elements of slice samples in C binding --- iceoryx2-ffi/cxx/include/iox2/publisher.hpp | 4 +- iceoryx2-ffi/cxx/include/iox2/sample.hpp | 9 +-- iceoryx2-ffi/cxx/include/iox2/sample_mut.hpp | 20 ++--- iceoryx2-ffi/ffi/src/api/sample.rs | 45 ++++++++--- iceoryx2-ffi/ffi/src/api/sample_mut.rs | 84 +++++++++++++++----- 5 files changed, 109 insertions(+), 53 deletions(-) diff --git a/iceoryx2-ffi/cxx/include/iox2/publisher.hpp b/iceoryx2-ffi/cxx/include/iox2/publisher.hpp index f7f479a80..f678c3343 100644 --- a/iceoryx2-ffi/cxx/include/iox2/publisher.hpp +++ b/iceoryx2-ffi/cxx/include/iox2/publisher.hpp @@ -223,8 +223,8 @@ inline auto Publisher::loan_slice(const uint64_t number_ } auto sample_init = std::move(sample_uninit.value()); - for (auto it = sample_init.payload_slice().begin(); it != sample_init.payload_slice().end(); ++it) { - new (it) typename T::ValueType(); + for (auto& item : sample_init.payload_slice()) { + new (&item) typename T::ValueType(); } return iox::ok(assume_init(std::move(sample_init))); diff --git a/iceoryx2-ffi/cxx/include/iox2/sample.hpp b/iceoryx2-ffi/cxx/include/iox2/sample.hpp index e83c24261..ee7d8590a 100644 --- a/iceoryx2-ffi/cxx/include/iox2/sample.hpp +++ b/iceoryx2-ffi/cxx/include/iox2/sample.hpp @@ -130,9 +130,8 @@ template template inline auto Sample::payload() const -> const Payload& { const void* ptr = nullptr; - size_t number_of_bytes = 0; - iox2_sample_payload(&m_handle, &ptr, &number_of_bytes); + iox2_sample_payload(&m_handle, &ptr, nullptr); return *static_cast(ptr); } @@ -141,11 +140,9 @@ template template inline auto Sample::payload_slice() const -> Payload { const void* ptr = nullptr; - size_t number_of_bytes = 0; + size_t number_of_elements = 0; - iox2_sample_payload(&m_handle, &ptr, &number_of_bytes); - - size_t number_of_elements = number_of_bytes / sizeof(typename Payload::ValueType); + iox2_sample_payload(&m_handle, &ptr, &number_of_elements); return Payload(static_cast(ptr), number_of_elements); } diff --git a/iceoryx2-ffi/cxx/include/iox2/sample_mut.hpp b/iceoryx2-ffi/cxx/include/iox2/sample_mut.hpp index 81d1f3e3b..7219eb245 100644 --- a/iceoryx2-ffi/cxx/include/iox2/sample_mut.hpp +++ b/iceoryx2-ffi/cxx/include/iox2/sample_mut.hpp @@ -197,10 +197,8 @@ template template inline auto SampleMut::payload() const -> const Payload& { const void* ptr = nullptr; - size_t number_of_bytes = 0; - iox2_sample_mut_payload(&m_handle, &ptr, &number_of_bytes); - IOX_ASSERT(sizeof(Payload) <= number_of_bytes, ""); + iox2_sample_mut_payload(&m_handle, &ptr, nullptr); return *static_cast(ptr); } @@ -209,10 +207,8 @@ template template inline auto SampleMut::payload_mut() -> Payload& { void* ptr = nullptr; - size_t number_of_bytes = 0; - iox2_sample_mut_payload_mut(&m_handle, &ptr, &number_of_bytes); - IOX_ASSERT(sizeof(Payload) <= number_of_bytes, ""); + iox2_sample_mut_payload_mut(&m_handle, &ptr, nullptr); return *static_cast(ptr); } @@ -221,11 +217,9 @@ template template inline auto SampleMut::payload_slice() const -> const Payload { const void* ptr = nullptr; - size_t number_of_bytes = 0; + size_t number_of_elements = 0; - iox2_sample_mut_payload(&m_handle, &ptr, &number_of_bytes); - - size_t number_of_elements = number_of_bytes / sizeof(typename Payload::ValueType); + iox2_sample_mut_payload(&m_handle, &ptr, &number_of_elements); return Payload(static_cast(const_cast(ptr)), number_of_elements); } @@ -234,11 +228,9 @@ template template inline auto SampleMut::payload_slice_mut() -> Payload { void* ptr = nullptr; - size_t number_of_bytes = 0; - - iox2_sample_mut_payload_mut(&m_handle, &ptr, &number_of_bytes); + size_t number_of_elements = 0; - size_t number_of_elements = number_of_bytes / sizeof(typename Payload::ValueType); + iox2_sample_mut_payload_mut(&m_handle, &ptr, &number_of_elements); return Payload(static_cast(const_cast(ptr)), number_of_elements); } diff --git a/iceoryx2-ffi/ffi/src/api/sample.rs b/iceoryx2-ffi/ffi/src/api/sample.rs index 2c676ab2d..8ff309456 100644 --- a/iceoryx2-ffi/ffi/src/api/sample.rs +++ b/iceoryx2-ffi/ffi/src/api/sample.rs @@ -214,28 +214,51 @@ pub unsafe extern "C" fn iox2_sample_user_header( /// /// * `handle` obtained by [`iox2_subscriber_receive()`](crate::iox2_subscriber_receive()) /// * `payload_ptr` a valid, non-null pointer pointing to a [`*const c_void`] pointer. -/// * `number_of_bytes` (optional) either a null poitner or a valid pointer pointing to a [`c_size_t`] with -/// the number of bytes used by the sample. +/// * `number_of_elements` (optional) either a null poitner or a valid pointer pointing to a [`c_size_t`] with +/// the number of elements of the underlying type #[no_mangle] pub unsafe extern "C" fn iox2_sample_payload( handle: iox2_sample_h_ref, payload_ptr: *mut *const c_void, - number_of_bytes: *mut c_size_t, + number_of_elements: *mut c_size_t, ) { handle.assert_non_null(); debug_assert!(!payload_ptr.is_null()); let sample = &mut *handle.as_type(); - let payload = match sample.service_type { - iox2_service_type_e::IPC => sample.value.as_mut().ipc.payload(), - iox2_service_type_e::LOCAL => sample.value.as_mut().local.payload(), + match sample.service_type { + iox2_service_type_e::IPC => { + let element_size = sample + .value + .as_mut() + .ipc + .header() + .payload_type_layout() + .size(); + let payload = sample.value.as_mut().ipc.payload(); + + *payload_ptr = payload.as_ptr().cast(); + if !number_of_elements.is_null() { + *number_of_elements = payload.len() / element_size; + } + } + iox2_service_type_e::LOCAL => { + let element_size = sample + .value + .as_mut() + .local + .header() + .payload_type_layout() + .size(); + let payload = sample.value.as_mut().local.payload(); + + *payload_ptr = payload.as_ptr().cast(); + if !number_of_elements.is_null() { + *number_of_elements = payload.len() / element_size; + } + } }; - - *payload_ptr = payload.as_ptr().cast(); - if !number_of_bytes.is_null() { - *number_of_bytes = payload.len(); - } } /// This function needs to be called to destroy the sample! diff --git a/iceoryx2-ffi/ffi/src/api/sample_mut.rs b/iceoryx2-ffi/ffi/src/api/sample_mut.rs index cbbea22f3..17cba1f51 100644 --- a/iceoryx2-ffi/ffi/src/api/sample_mut.rs +++ b/iceoryx2-ffi/ffi/src/api/sample_mut.rs @@ -249,58 +249,102 @@ pub unsafe extern "C" fn iox2_sample_mut_user_header_mut( pub unsafe extern "C" fn iox2_sample_mut_payload_mut( handle: iox2_sample_mut_h_ref, payload_ptr: *mut *mut c_void, - payload_len: *mut c_size_t, + number_of_elements: *mut c_size_t, ) { handle.assert_non_null(); debug_assert!(!payload_ptr.is_null()); let sample = &mut *handle.as_type(); - let payload = match sample.service_type { - iox2_service_type_e::IPC => sample.value.as_mut().ipc.payload_mut(), - iox2_service_type_e::LOCAL => sample.value.as_mut().local.payload_mut(), + match sample.service_type { + iox2_service_type_e::IPC => { + let element_size = sample + .value + .as_mut() + .ipc + .header() + .payload_type_layout() + .size(); + let payload = sample.value.as_mut().ipc.payload_mut(); + *payload_ptr = payload.as_mut_ptr().cast(); + if !number_of_elements.is_null() { + *number_of_elements = payload.len() / element_size; + } + } + iox2_service_type_e::LOCAL => { + let element_size = sample + .value + .as_mut() + .local + .header() + .payload_type_layout() + .size(); + let payload = sample.value.as_mut().local.payload_mut(); + *payload_ptr = payload.as_mut_ptr().cast(); + if !number_of_elements.is_null() { + *number_of_elements = payload.len() / element_size; + } + } }; - - *payload_ptr = payload.as_mut_ptr().cast(); - if !payload_len.is_null() { - *payload_len = payload.len(); - } } /// Acquires the samples payload. /// /// # Safety /// -/// * `handle` obtained by [`iox2_publisher_loan()`](crate::iox2_publisher_loan()) +/// * `handle` obtained by [`iox2_publisher_loan_slice_uninit()`](crate::iox2_publisher_loan_slice_uninit()) /// * `payload_ptr` a valid, non-null pointer pointing to a [`*const c_void`] pointer. /// * `payload_len` (optional) either a null poitner or a valid pointer pointing to a [`c_size_t`]. #[no_mangle] pub unsafe extern "C" fn iox2_sample_mut_payload( handle: iox2_sample_mut_h_ref, payload_ptr: *mut *const c_void, - payload_len: *mut c_size_t, + number_of_elements: *mut c_size_t, ) { handle.assert_non_null(); debug_assert!(!payload_ptr.is_null()); let sample = &mut *handle.as_type(); - let payload = match sample.service_type { - iox2_service_type_e::IPC => sample.value.as_mut().ipc.payload(), - iox2_service_type_e::LOCAL => sample.value.as_mut().local.payload(), + match sample.service_type { + iox2_service_type_e::IPC => { + let element_size = sample + .value + .as_mut() + .ipc + .header() + .payload_type_layout() + .size(); + let payload = sample.value.as_mut().ipc.payload_mut(); + + *payload_ptr = payload.as_mut_ptr().cast(); + if !number_of_elements.is_null() { + *number_of_elements = payload.len() / element_size; + } + } + iox2_service_type_e::LOCAL => { + let element_size = sample + .value + .as_mut() + .local + .header() + .payload_type_layout() + .size(); + let payload = sample.value.as_mut().local.payload_mut(); + + *payload_ptr = payload.as_mut_ptr().cast(); + if !number_of_elements.is_null() { + *number_of_elements = payload.len() / element_size; + } + } }; - - *payload_ptr = payload.as_ptr().cast(); - if !payload_len.is_null() { - *payload_len = payload.len(); - } } /// Takes the ownership of the sample and sends it /// /// # Safety /// -/// * `handle` obtained by [`iox2_publisher_loan()`](crate::iox2_publisher_loan()) +/// * `handle` obtained by [`iox2_publisher_loan_slice_uninit()`](crate::iox2_publisher_loan_slice_uninit()) /// * `number_of_recipients`, can be null or must point to a valid [`c_size_t`] to store the number /// of subscribers that received the sample #[no_mangle]