From 33b1d138d133c4fd4b795b32a59113823486800e Mon Sep 17 00:00:00 2001 From: Jeff Ithier Date: Sat, 2 Nov 2024 11:16:43 +0100 Subject: [PATCH] [#500] Expose UniquePortId bytes in CXX API --- .../cxx/include/iox2/unique_port_id.hpp | 9 ++++++++- iceoryx2-ffi/cxx/src/unique_port_id.cpp | 12 ++++++++++++ .../cxx/tests/src/unique_port_id_tests.cpp | 9 +++++++++ .../ffi/src/api/unique_publisher_id.rs | 18 ++++++++++++++++++ iceoryx2/src/port/port_identifiers.rs | 5 +++++ 5 files changed, 52 insertions(+), 1 deletion(-) diff --git a/iceoryx2-ffi/cxx/include/iox2/unique_port_id.hpp b/iceoryx2-ffi/cxx/include/iox2/unique_port_id.hpp index f4ffa7146..5360069e1 100644 --- a/iceoryx2-ffi/cxx/include/iox2/unique_port_id.hpp +++ b/iceoryx2-ffi/cxx/include/iox2/unique_port_id.hpp @@ -13,9 +13,15 @@ #ifndef IOX2_UNIQUE_PORT_ID_HPP #define IOX2_UNIQUE_PORT_ID_HPP +#include "iox/optional.hpp" #include "iox2/internal/iceoryx2.hpp" +#include + namespace iox2 { + +constexpr uint64_t UNIQUE_PORT_ID_LENGTH = 128; + /// The system-wide unique id of a [`Publisher`]. class UniquePublisherId { public: @@ -25,6 +31,8 @@ class UniquePublisherId { auto operator=(UniquePublisherId&& rhs) noexcept -> UniquePublisherId&; ~UniquePublisherId(); + auto bytes() -> iox::optional>; + private: template friend class Publisher; @@ -38,7 +46,6 @@ class UniquePublisherId { iox2_unique_publisher_id_h m_handle = nullptr; }; - /// The system-wide unique id of a [`Subscriber`]. class UniqueSubscriberId { public: diff --git a/iceoryx2-ffi/cxx/src/unique_port_id.cpp b/iceoryx2-ffi/cxx/src/unique_port_id.cpp index c8f8116f2..32abe11d8 100644 --- a/iceoryx2-ffi/cxx/src/unique_port_id.cpp +++ b/iceoryx2-ffi/cxx/src/unique_port_id.cpp @@ -12,6 +12,9 @@ #include "iox2/unique_port_id.hpp" +#include +#include + namespace iox2 { UniquePublisherId::UniquePublisherId(UniquePublisherId&& rhs) noexcept { *this = std::move(rhs); @@ -43,6 +46,15 @@ UniquePublisherId::UniquePublisherId(iox2_unique_publisher_id_h handle) : m_handle { handle } { } +auto UniquePublisherId::bytes() -> iox::optional> { + if (m_handle != nullptr) { + std::array unique_port_id {}; + iox2_unique_publisher_id_value(m_handle, unique_port_id.data()); + return unique_port_id; + } + return iox::nullopt; +}; + void UniquePublisherId::drop() { if (m_handle != nullptr) { iox2_unique_publisher_id_drop(m_handle); diff --git a/iceoryx2-ffi/cxx/tests/src/unique_port_id_tests.cpp b/iceoryx2-ffi/cxx/tests/src/unique_port_id_tests.cpp index 939e4ec34..57447b9c8 100644 --- a/iceoryx2-ffi/cxx/tests/src/unique_port_id_tests.cpp +++ b/iceoryx2-ffi/cxx/tests/src/unique_port_id_tests.cpp @@ -17,10 +17,12 @@ #include "iox2/publisher.hpp" #include "iox2/service_name.hpp" #include "iox2/subscriber.hpp" +#include "iox2/unique_port_id.hpp" #include "test.hpp" #include +#include namespace { using namespace iox2; @@ -63,6 +65,13 @@ struct UniquePortIdTest : public ::testing::Test { TYPED_TEST_SUITE(UniquePortIdTest, iox2_testing::ServiceTypes); +TYPED_TEST(UniquePortIdTest, unique_publisher_id_value) { + auto null_id = std::array {}; + auto unique_port_id = this->publisher_1.id(); + ASSERT_TRUE(unique_port_id.bytes().has_value()); + ASSERT_NE(unique_port_id.bytes().value(), null_id); +} + TYPED_TEST(UniquePortIdTest, unique_port_id_from_same_port_is_equal) { ASSERT_TRUE(this->listener_1.id() == this->listener_1.id()); ASSERT_TRUE(this->notifier_1.id() == this->notifier_1.id()); diff --git a/iceoryx2-ffi/ffi/src/api/unique_publisher_id.rs b/iceoryx2-ffi/ffi/src/api/unique_publisher_id.rs index 4f81be0a6..3c1804d95 100644 --- a/iceoryx2-ffi/ffi/src/api/unique_publisher_id.rs +++ b/iceoryx2-ffi/ffi/src/api/unique_publisher_id.rs @@ -86,6 +86,24 @@ impl HandleToType for iox2_unique_publisher_id_h_ref { // BEGIN C API +#[no_mangle] +unsafe extern "C" fn iox2_unique_publisher_id_value( + handle: iox2_unique_publisher_id_h, + id_ptr: *mut u8, +) { + handle.assert_non_null(); + + let h = &mut *handle.as_type(); + + if let Some(Some(id)) = (h.value.internal.as_ptr() as *const Option).as_ref() + { + let bytes = id.value().to_ne_bytes(); + unsafe { + std::ptr::copy_nonoverlapping(bytes.as_ptr(), id_ptr, bytes.len()); + } + } +} + /// This function needs to be called to destroy the unique publisher id! /// /// # Arguments diff --git a/iceoryx2/src/port/port_identifiers.rs b/iceoryx2/src/port/port_identifiers.rs index 1826057ec..415de10a3 100644 --- a/iceoryx2/src/port/port_identifiers.rs +++ b/iceoryx2/src/port/port_identifiers.rs @@ -35,6 +35,11 @@ macro_rules! generate_id { pub fn new() -> Self { Self::default() } + + /// Returns the underlying raw value of the ID + pub fn value(&self) -> u128 { + self.0.value() + } } }; }