From ff9e7dcc80437254a7515fa2fa58ce5e638a68b3 Mon Sep 17 00:00:00 2001 From: Jeff Ithier Date: Tue, 5 Nov 2024 18:17:09 +0100 Subject: [PATCH] [#490] Fix C/C++ examples with slices --- examples/c/domains/src/publisher.c | 2 +- examples/c/publish_subscribe/src/publisher.c | 2 +- .../src/publisher.c | 2 +- .../src/publisher.cpp | 6 +- .../src/subscriber.cpp | 7 +- .../cxx/include/iox2/sample_mut_uninit.hpp | 9 +- .../src/service_publish_subscribe_tests.cpp | 99 +++++++++++++++++++ 7 files changed, 116 insertions(+), 11 deletions(-) diff --git a/examples/c/domains/src/publisher.c b/examples/c/domains/src/publisher.c index d0e164454..0ffefc71c 100644 --- a/examples/c/domains/src/publisher.c +++ b/examples/c/domains/src/publisher.c @@ -99,7 +99,7 @@ int main(int argc, char** argv) { // loan sample iox2_sample_mut_h sample = NULL; - if (iox2_publisher_loan(&publisher, NULL, &sample) != IOX2_OK) { + if (iox2_publisher_loan_slice_uninit(&publisher, NULL, &sample, 1) != IOX2_OK) { printf("Failed to loan sample\n"); goto drop_publisher; } diff --git a/examples/c/publish_subscribe/src/publisher.c b/examples/c/publish_subscribe/src/publisher.c index e3282b2bd..ead151e30 100644 --- a/examples/c/publish_subscribe/src/publisher.c +++ b/examples/c/publish_subscribe/src/publisher.c @@ -79,7 +79,7 @@ int main(void) { // loan sample iox2_sample_mut_h sample = NULL; - if (iox2_publisher_loan(&publisher, NULL, &sample) != IOX2_OK) { + if (iox2_publisher_loan_slice_uninit(&publisher, NULL, &sample, 1) != IOX2_OK) { printf("Failed to loan sample\n"); goto drop_publisher; } diff --git a/examples/c/publish_subscribe_with_user_header/src/publisher.c b/examples/c/publish_subscribe_with_user_header/src/publisher.c index 3e13075c8..b5b7d9103 100644 --- a/examples/c/publish_subscribe_with_user_header/src/publisher.c +++ b/examples/c/publish_subscribe_with_user_header/src/publisher.c @@ -92,7 +92,7 @@ int main(void) { // loan sample iox2_sample_mut_h sample = NULL; - if (iox2_publisher_loan(&publisher, NULL, &sample) != IOX2_OK) { + if (iox2_publisher_loan_slice_uninit(&publisher, NULL, &sample, 1) != IOX2_OK) { printf("Failed to loan sample\n"); goto drop_publisher; } diff --git a/examples/cxx/publish_subscribe_dynamic_data/src/publisher.cpp b/examples/cxx/publish_subscribe_dynamic_data/src/publisher.cpp index bae023812..706e8317c 100644 --- a/examples/cxx/publish_subscribe_dynamic_data/src/publisher.cpp +++ b/examples/cxx/publish_subscribe_dynamic_data/src/publisher.cpp @@ -41,9 +41,7 @@ auto main() -> int { auto counter = 1; while (node.wait(CYCLE_TIME).has_value()) { - counter += 1; - - auto required_memory_size = (8 + counter) % 16; // NOLINT + auto required_memory_size = counter % 16; // NOLINT auto sample = publisher.loan_slice_uninit(required_memory_size).expect("acquire sample"); sample.write_from_fn([&](auto byte_idx) { return (byte_idx + counter) % 255; }); // NOLINT @@ -51,6 +49,8 @@ auto main() -> int { send(std::move(initialized_sample)).expect("send successful"); std::cout << "Send sample " << counter << "..." << std::endl; + + counter++; } std::cout << "exit" << std::endl; diff --git a/examples/cxx/publish_subscribe_dynamic_data/src/subscriber.cpp b/examples/cxx/publish_subscribe_dynamic_data/src/subscriber.cpp index fee340f43..593d00f35 100644 --- a/examples/cxx/publish_subscribe_dynamic_data/src/subscriber.cpp +++ b/examples/cxx/publish_subscribe_dynamic_data/src/subscriber.cpp @@ -17,6 +17,7 @@ #include "iox2/service_type.hpp" #include +#include #include constexpr iox::units::Duration CYCLE_TIME = iox::units::Duration::fromSeconds(1); @@ -35,9 +36,9 @@ auto main() -> int { while (node.wait(CYCLE_TIME).has_value()) { auto sample = subscriber.receive().expect("receive succeeds"); while (sample.has_value()) { - std::cout << "received " << sample->payload().size() << " bytes: "; - for (auto byte : sample->payload()) { - std::cout << std::hex << byte << " "; + std::cout << "received " << std::dec << static_cast(sample->payload_slice().size()) << " bytes: "; + for (auto byte : sample->payload_slice()) { + std::cout << std::setw(2) << std::setfill('0') << std::hex << static_cast(byte) << " "; } std::cout << std::endl; sample = subscriber.receive().expect("receive succeeds"); diff --git a/iceoryx2-ffi/cxx/include/iox2/sample_mut_uninit.hpp b/iceoryx2-ffi/cxx/include/iox2/sample_mut_uninit.hpp index ec4020063..afa0d8985 100644 --- a/iceoryx2-ffi/cxx/include/iox2/sample_mut_uninit.hpp +++ b/iceoryx2-ffi/cxx/include/iox2/sample_mut_uninit.hpp @@ -173,13 +173,18 @@ template template inline void SampleMutUninit::write_from_fn( const iox::function& initializer) { - IOX_TODO(); + auto slice = payload_slice_mut(); + std::cout << slice.size() << std::endl; + for (uint64_t i = 0; i < slice.number_of_elements(); ++i) { + slice[i] = initializer(i); + } } template template inline void SampleMutUninit::write_from_slice(const T& value) { - IOX_TODO(); + auto dest = payload_slice_mut(); + std::memcpy(dest.begin(), value.begin(), std::min(dest.size(), value.size()) * sizeof(typename T::ValueType)); } } // namespace iox2 diff --git a/iceoryx2-ffi/cxx/tests/src/service_publish_subscribe_tests.cpp b/iceoryx2-ffi/cxx/tests/src/service_publish_subscribe_tests.cpp index 6b1dacdb3..d0020d656 100644 --- a/iceoryx2-ffi/cxx/tests/src/service_publish_subscribe_tests.cpp +++ b/iceoryx2-ffi/cxx/tests/src/service_publish_subscribe_tests.cpp @@ -248,6 +248,105 @@ TYPED_TEST(ServicePublishSubscribeTest, slice_copy_send_receive_works) { ASSERT_THAT(iterations, Eq(SLICE_MAX_LENGTH)); } +TYPED_TEST(ServicePublishSubscribeTest, write_from_fn_send_receive_works) { + constexpr ServiceType SERVICE_TYPE = TestFixture::TYPE; + constexpr auto SLICE_MAX_LENGTH = 10; + + constexpr uint64_t DEFAULT_VALUE_A = 42; + constexpr uint64_t DEFAULT_VALUE_B = 777; + constexpr uint64_t DEFAULT_VALUE_Z = 21; + struct MyNestedStruct { + uint64_t a { DEFAULT_VALUE_A }; + uint64_t b { DEFAULT_VALUE_B }; + }; + struct MyStruct { + uint64_t z { DEFAULT_VALUE_Z }; + MyNestedStruct data; + }; + + const auto service_name = iox2_testing::generate_service_name(); + + auto node = NodeBuilder().create().expect(""); + auto service = + node.service_builder(service_name).template publish_subscribe>().create().expect(""); + + auto sut_publisher = service.publisher_builder().max_slice_len(SLICE_MAX_LENGTH).create().expect(""); + auto sut_subscriber = service.subscriber_builder().create().expect(""); + + auto send_sample = sut_publisher.loan_slice_uninit(SLICE_MAX_LENGTH).expect(""); + send_sample.write_from_fn([](auto index) { + std::cout << index << std::endl; + return MyStruct { DEFAULT_VALUE_Z + index, + MyNestedStruct { DEFAULT_VALUE_A + index, DEFAULT_VALUE_B + index } }; + }); + send(assume_init(std::move(send_sample))).expect(""); + + auto recv_result = sut_subscriber.receive().expect(""); + ASSERT_TRUE(recv_result.has_value()); + auto recv_sample = std::move(recv_result.value()); + + auto iterations = 0; + for (const auto& item : recv_sample.payload_slice()) { + ASSERT_THAT(item.z, Eq(DEFAULT_VALUE_Z + iterations)); + ASSERT_THAT(item.data.a, Eq(DEFAULT_VALUE_A + iterations)); + ASSERT_THAT(item.data.b, Eq(DEFAULT_VALUE_B + iterations)); + ++iterations; + } + + ASSERT_THAT(recv_sample.payload_slice().number_of_elements(), Eq(SLICE_MAX_LENGTH)); + ASSERT_THAT(iterations, Eq(SLICE_MAX_LENGTH)); +} + +TYPED_TEST(ServicePublishSubscribeTest, write_from_slice_send_receive_works) { + constexpr ServiceType SERVICE_TYPE = TestFixture::TYPE; + constexpr auto SLICE_MAX_LENGTH = 10; + + constexpr uint64_t DEFAULT_VALUE_A = 42; + constexpr uint64_t DEFAULT_VALUE_B = 777; + constexpr uint64_t DEFAULT_VALUE_Z = 21; + struct MyNestedStruct { + uint64_t a { DEFAULT_VALUE_A }; + uint64_t b { DEFAULT_VALUE_B }; + }; + struct MyStruct { + uint64_t z { DEFAULT_VALUE_Z }; + MyNestedStruct data; + }; + + const auto service_name = iox2_testing::generate_service_name(); + + auto node = NodeBuilder().create().expect(""); + auto service = + node.service_builder(service_name).template publish_subscribe>().create().expect(""); + + auto sut_publisher = service.publisher_builder().max_slice_len(SLICE_MAX_LENGTH).create().expect(""); + auto sut_subscriber = service.subscriber_builder().create().expect(""); + + iox::UninitializedArray elements; + for (auto& item : elements) { + new (&item) MyStruct {}; + } + auto payload = iox::Slice(elements.begin(), SLICE_MAX_LENGTH); + auto send_sample = sut_publisher.loan_slice_uninit(SLICE_MAX_LENGTH).expect(""); + send_sample.write_from_slice(payload); + send(assume_init(std::move(send_sample))).expect(""); + + auto recv_result = sut_subscriber.receive().expect(""); + ASSERT_TRUE(recv_result.has_value()); + auto recv_sample = std::move(recv_result.value()); + + auto iterations = 0; + for (const auto& item : recv_sample.payload_slice()) { + ASSERT_THAT(item.z, Eq(DEFAULT_VALUE_Z)); + ASSERT_THAT(item.data.a, Eq(DEFAULT_VALUE_A)); + ASSERT_THAT(item.data.b, Eq(DEFAULT_VALUE_B)); + ++iterations; + } + + ASSERT_THAT(recv_sample.payload_slice().number_of_elements(), Eq(SLICE_MAX_LENGTH)); + ASSERT_THAT(iterations, Eq(SLICE_MAX_LENGTH)); +} + TYPED_TEST(ServicePublishSubscribeTest, loan_slice_send_receive_works) { constexpr ServiceType SERVICE_TYPE = TestFixture::TYPE; constexpr uint64_t PAYLOAD_ALIGNMENT = 8;