From d1c190f8a219541359dd93af828276404ed14558 Mon Sep 17 00:00:00 2001 From: Jeff Ithier Date: Sat, 2 Nov 2024 11:16:43 +0100 Subject: [PATCH] [#500] Expose UniquePublisherId UniqueSubscriberId UniqueNotifierId UniqueListenerId bytes in CXX API --- .../cxx/include/iox2/unique_port_id.hpp | 15 +++++++- iceoryx2-ffi/cxx/src/unique_port_id.cpp | 36 +++++++++++++++++++ .../cxx/tests/src/unique_port_id_tests.cpp | 22 ++++++++++++ .../ffi/src/api/unique_listener_id.rs | 18 ++++++++++ .../ffi/src/api/unique_notifier_id.rs | 18 ++++++++++ .../ffi/src/api/unique_publisher_id.rs | 18 ++++++++++ .../ffi/src/api/unique_subscriber_id.rs | 19 ++++++++++ iceoryx2/src/port/port_identifiers.rs | 5 +++ 8 files changed, 150 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..2e9e03406 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: @@ -48,6 +55,8 @@ class UniqueSubscriberId { auto operator=(UniqueSubscriberId&& rhs) noexcept -> UniqueSubscriberId&; ~UniqueSubscriberId(); + auto bytes() -> iox::optional>; + private: template friend class Subscriber; @@ -69,6 +78,8 @@ class UniqueNotifierId { auto operator=(UniqueNotifierId&& rhs) noexcept -> UniqueNotifierId&; ~UniqueNotifierId(); + auto bytes() -> iox::optional>; + private: template friend class Notifier; @@ -90,6 +101,8 @@ class UniqueListenerId { auto operator=(UniqueListenerId&& rhs) noexcept -> UniqueListenerId&; ~UniqueListenerId(); + auto bytes() -> iox::optional>; + private: template friend class Listener; diff --git a/iceoryx2-ffi/cxx/src/unique_port_id.cpp b/iceoryx2-ffi/cxx/src/unique_port_id.cpp index c8f8116f2..13a76c686 100644 --- a/iceoryx2-ffi/cxx/src/unique_port_id.cpp +++ b/iceoryx2-ffi/cxx/src/unique_port_id.cpp @@ -43,6 +43,15 @@ UniquePublisherId::UniquePublisherId(iox2_unique_publisher_id_h handle) : m_handle { handle } { } +auto UniquePublisherId::bytes() -> iox::optional> { + if (m_handle != nullptr) { + std::array bytes {}; + iox2_unique_publisher_id_value(m_handle, bytes.data()); + return bytes; + } + return iox::nullopt; +}; + void UniquePublisherId::drop() { if (m_handle != nullptr) { iox2_unique_publisher_id_drop(m_handle); @@ -81,6 +90,15 @@ UniqueSubscriberId::UniqueSubscriberId(iox2_unique_subscriber_id_h handle) : m_handle { handle } { } +auto UniqueSubscriberId::bytes() -> iox::optional> { + if (m_handle != nullptr) { + std::array bytes {}; + iox2_unique_subscriber_id_value(m_handle, bytes.data()); + return bytes; + } + return iox::nullopt; +}; + void UniqueSubscriberId::drop() { if (m_handle != nullptr) { iox2_unique_subscriber_id_drop(m_handle); @@ -118,6 +136,15 @@ UniqueNotifierId::UniqueNotifierId(iox2_unique_notifier_id_h handle) : m_handle { handle } { } +auto UniqueNotifierId::bytes() -> iox::optional> { + if (m_handle != nullptr) { + std::array bytes {}; + iox2_unique_notifier_id_value(m_handle, bytes.data()); + return bytes; + } + return iox::nullopt; +}; + void UniqueNotifierId::drop() { if (m_handle != nullptr) { iox2_unique_notifier_id_drop(m_handle); @@ -155,6 +182,15 @@ UniqueListenerId::UniqueListenerId(iox2_unique_listener_id_h handle) : m_handle { handle } { } +auto UniqueListenerId::bytes() -> iox::optional> { + if (m_handle != nullptr) { + std::array bytes {}; + iox2_unique_listener_id_value(m_handle, bytes.data()); + return bytes; + } + return iox::nullopt; +}; + void UniqueListenerId::drop() { if (m_handle != nullptr) { iox2_unique_listener_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..89e86cd4c 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,26 @@ struct UniquePortIdTest : public ::testing::Test { TYPED_TEST_SUITE(UniquePortIdTest, iox2_testing::ServiceTypes); +TYPED_TEST(UniquePortIdTest, unique_port_id_value) { + auto null_id = std::array {}; + + auto unique_publisher_id = this->publisher_1.id(); + ASSERT_TRUE(unique_publisher_id.bytes().has_value()); + ASSERT_NE(unique_publisher_id.bytes().value(), null_id); + + auto unique_subscriber_id = this->publisher_1.id(); + ASSERT_TRUE(unique_subscriber_id.bytes().has_value()); + ASSERT_NE(unique_subscriber_id.bytes().value(), null_id); + + auto unique_notifier_id = this->notifier_1.id(); + ASSERT_TRUE(unique_notifier_id.bytes().has_value()); + ASSERT_NE(unique_notifier_id.bytes().value(), null_id); + + auto unique_listener_id = this->listener_1.id(); + ASSERT_TRUE(unique_listener_id.bytes().has_value()); + ASSERT_NE(unique_listener_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_listener_id.rs b/iceoryx2-ffi/ffi/src/api/unique_listener_id.rs index b286894fa..89530262c 100644 --- a/iceoryx2-ffi/ffi/src/api/unique_listener_id.rs +++ b/iceoryx2-ffi/ffi/src/api/unique_listener_id.rs @@ -86,6 +86,24 @@ impl HandleToType for iox2_unique_listener_id_h_ref { // BEGIN C API +#[no_mangle] +unsafe extern "C" fn iox2_unique_listener_id_value( + handle: iox2_unique_listener_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 listener id! /// /// # Arguments diff --git a/iceoryx2-ffi/ffi/src/api/unique_notifier_id.rs b/iceoryx2-ffi/ffi/src/api/unique_notifier_id.rs index 8b289bd8a..22e0950e0 100644 --- a/iceoryx2-ffi/ffi/src/api/unique_notifier_id.rs +++ b/iceoryx2-ffi/ffi/src/api/unique_notifier_id.rs @@ -86,6 +86,24 @@ impl HandleToType for iox2_unique_notifier_id_h_ref { // BEGIN C API +#[no_mangle] +unsafe extern "C" fn iox2_unique_notifier_id_value( + handle: iox2_unique_notifier_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 notifier id! /// /// # Arguments 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-ffi/ffi/src/api/unique_subscriber_id.rs b/iceoryx2-ffi/ffi/src/api/unique_subscriber_id.rs index 65c8effc2..64487e76c 100644 --- a/iceoryx2-ffi/ffi/src/api/unique_subscriber_id.rs +++ b/iceoryx2-ffi/ffi/src/api/unique_subscriber_id.rs @@ -86,6 +86,25 @@ impl HandleToType for iox2_unique_subscriber_id_h_ref { // BEGIN C API +#[no_mangle] +unsafe extern "C" fn iox2_unique_subscriber_id_value( + handle: iox2_unique_subscriber_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 subscriber 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() + } } }; }