Skip to content

Commit

Permalink
[#490] Calculate number of elements of slice samples in C binding
Browse files Browse the repository at this point in the history
  • Loading branch information
orecham committed Nov 1, 2024
1 parent 0e22135 commit 1da7cbd
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 53 deletions.
4 changes: 2 additions & 2 deletions iceoryx2-ffi/cxx/include/iox2/publisher.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,8 @@ inline auto Publisher<S, Payload, UserHeader>::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)));
Expand Down
9 changes: 3 additions & 6 deletions iceoryx2-ffi/cxx/include/iox2/sample.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,8 @@ template <ServiceType S, typename Payload, typename UserHeader>
template <typename T, typename>
inline auto Sample<S, Payload, UserHeader>::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<const Payload*>(ptr);
}
Expand All @@ -141,11 +140,9 @@ template <ServiceType S, typename Payload, typename UserHeader>
template <typename T, typename>
inline auto Sample<S, Payload, UserHeader>::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<const typename Payload::ValueType*>(ptr), number_of_elements);
}
Expand Down
20 changes: 6 additions & 14 deletions iceoryx2-ffi/cxx/include/iox2/sample_mut.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,10 +197,8 @@ template <ServiceType S, typename Payload, typename UserHeader>
template <typename T, typename>
inline auto SampleMut<S, Payload, UserHeader>::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<const Payload*>(ptr);
}
Expand All @@ -209,10 +207,8 @@ template <ServiceType S, typename Payload, typename UserHeader>
template <typename T, typename>
inline auto SampleMut<S, Payload, UserHeader>::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<Payload*>(ptr);
}
Expand All @@ -221,11 +217,9 @@ template <ServiceType S, typename Payload, typename UserHeader>
template <typename T, typename>
inline auto SampleMut<S, Payload, UserHeader>::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<typename Payload::ValueType*>(const_cast<void*>(ptr)), number_of_elements);
}
Expand All @@ -234,11 +228,9 @@ template <ServiceType S, typename Payload, typename UserHeader>
template <typename T, typename>
inline auto SampleMut<S, Payload, UserHeader>::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<typename Payload::ValueType*>(const_cast<void*>(ptr)), number_of_elements);
}
Expand Down
45 changes: 34 additions & 11 deletions iceoryx2-ffi/ffi/src/api/sample.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!
Expand Down
84 changes: 64 additions & 20 deletions iceoryx2-ffi/ffi/src/api/sample_mut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down

0 comments on commit 1da7cbd

Please sign in to comment.