diff --git a/.azure/templates/build-test.yml b/.azure/templates/build-test.yml index 047589a4..01566eda 100644 --- a/.azure/templates/build-test.yml +++ b/.azure/templates/build-test.yml @@ -118,6 +118,7 @@ steps: cmake -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \ -DCMAKE_INSTALL_PREFIX=install \ -DCMAKE_PREFIX_PATH="${BUILD_SOURCESDIRECTORY}/cyclonedds/build/install;${BUILD_SOURCESDIRECTORY}/iceoryx/build/install;${BUILD_SOURCESDIRECTORY}/googletest/build/install" \ + -DCYCLONE_SOURCE_DIR="${BUILD_SOURCESDIRECTORY}/cyclonedds" \ -DANALYZER=${ANALYZER:-off} \ -DSANITIZER=${SANITIZER:-none} \ -DENABLE_ICEORYX=${ICEORYX:-off} \ diff --git a/CMakeLists.txt b/CMakeLists.txt index f0138d62..78e137b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -251,6 +251,19 @@ if(ENABLE_TOPIC_DISCOVERY) set(DDSCXX_HAS_TOPIC_DISCOVERY "1") endif() +get_target_property(cyclonedds_has_qos_provider CycloneDDS::ddsc QOS_PROVIDER_IS_AVAILABLE) +mark_as_advanced(cyclonedds_has_qos_provider) +option(ENABLE_QOS_PROVIDER "Enable QoS Provider support" ${cyclonedds_has_qos_provider}) +if(ENABLE_QOS_PROVIDER) + if (NOT cyclonedds_has_qos_provider) + message(FATAL_ERROR "Cyclone DDS is not compiled with qos provider enabled") + endif() + message(STATUS "Compiling with qos provider support") + set(DDSCXX_HAS_QOS_PROVIDER "1") +endif() + + + configure_file(features.hpp.in "${CMAKE_CURRENT_BINARY_DIR}/src/ddscxx/include/dds/features.hpp") add_subdirectory(src) diff --git a/README.md b/README.md index 86ab0720..4c3020b1 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,7 @@ There are some configuration options specified using CMake defines in addition t * `-DENABLE_TYPELIB=YES`: to enable type library support * `-DENABLE_TOPIC_DISCOVERY=YES`: to enable topic discovery support * `-DENABLE_COVERAGE=YES`: to enable coverage build +* `-DENABLE_QOS_PROVIDER=YES`: to enable qos provider support ### For application developers diff --git a/features.hpp.in b/features.hpp.in index a95242d0..5f8f0c1e 100644 --- a/features.hpp.in +++ b/features.hpp.in @@ -10,4 +10,7 @@ /* Whether to use boost for c++11 compatibility or not */ #cmakedefine DDSCXX_USE_BOOST @DDSCXX_USE_BOOST@ +/* Whether or not support for qos provider is included */ +#cmakedefine DDSCXX_HAS_QOS_PROVIDER @DDSCXX_HAS_QOS_PROVIDER@ + #endif /* __OMG_DDS_DDSCXX_FEATURES_HPP__ */ diff --git a/src/ddscxx/CMakeLists.txt b/src/ddscxx/CMakeLists.txt index 65c63fe7..6b8cf090 100644 --- a/src/ddscxx/CMakeLists.txt +++ b/src/ddscxx/CMakeLists.txt @@ -70,6 +70,11 @@ set(sources src/org/eclipse/cyclonedds/topic/TopicDescriptionDelegate.cpp src/org/eclipse/cyclonedds/topic/qos/TopicQosDelegate.cpp) +if (ENABLE_QOS_PROVIDER) + list(APPEND sources + src/org/eclipse/cyclonedds/core/QosProviderDelegate.cpp) +endif() + if(BUILD_SHARED_LIBS OR NOT DEFINED BUILD_SHARED_LIBS) add_library(ddscxx SHARED ${sources}) else() @@ -91,6 +96,7 @@ add_library(${PROJECT_NAME}::ddscxx ALIAS ddscxx) add_coverage(ddscxx) set_property(TARGET ddscxx PROPERTY CXX_STANDARD ${cyclonedds_cpp_std_to_use}) + target_link_libraries(ddscxx PUBLIC CycloneDDS::ddsc) target_include_directories( ddscxx diff --git a/src/ddscxx/include/dds/core/QosProvider.hpp b/src/ddscxx/include/dds/core/QosProvider.hpp index aeebd3b5..c80abb4d 100644 --- a/src/ddscxx/include/dds/core/QosProvider.hpp +++ b/src/ddscxx/include/dds/core/QosProvider.hpp @@ -18,6 +18,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#ifdef DDS_HAS_QOS_PROVIDER + #include @@ -29,4 +31,6 @@ typedef dds::core::detail::QosProvider QosProvider; } } +#endif /* DDS_HAS_QOS_PROVIDER */ + #endif /* OMG_DDS_CORE_QOS_PROVIDER_HPP_ */ diff --git a/src/ddscxx/include/dds/core/detail/QosProvider.hpp b/src/ddscxx/include/dds/core/detail/QosProvider.hpp index 7a69b1c6..982333de 100644 --- a/src/ddscxx/include/dds/core/detail/QosProvider.hpp +++ b/src/ddscxx/include/dds/core/detail/QosProvider.hpp @@ -19,6 +19,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#ifdef DDS_HAS_QOS_PROVIDER + #include #include @@ -30,4 +32,6 @@ namespace dds { } } +#endif /* DDS_HAS_QOS_PROVIDER */ + #endif /* OMG_DDS_CORE_DETAIL_QOS_PROVIDER_HPP_ */ diff --git a/src/ddscxx/include/dds/topic/detail/TTopicImpl.hpp b/src/ddscxx/include/dds/topic/detail/TTopicImpl.hpp index a053c768..2eb2f334 100644 --- a/src/ddscxx/include/dds/topic/detail/TTopicImpl.hpp +++ b/src/ddscxx/include/dds/topic/detail/TTopicImpl.hpp @@ -334,7 +334,7 @@ dds::topic::detail::Topic::discover_topic( ret = dds_get_qos(ddsc_topic, ddsc_qos); dds::topic::qos::TopicQos qos; if (ret == DDS_RETCODE_OK) { - qos.delegate().ddsc_qos(ddsc_qos); + qos.delegate().ddsc_qos(ddsc_qos, false); } dds_delete_qos(ddsc_qos); ISOCPP_DDSC_RESULT_CHECK_AND_THROW(ret, "Failed to get the qos from discovered topic"); diff --git a/src/ddscxx/include/org/eclipse/cyclonedds/core/QosProviderDelegate.hpp b/src/ddscxx/include/org/eclipse/cyclonedds/core/QosProviderDelegate.hpp index b5f2f1d5..e180a147 100644 --- a/src/ddscxx/include/org/eclipse/cyclonedds/core/QosProviderDelegate.hpp +++ b/src/ddscxx/include/org/eclipse/cyclonedds/core/QosProviderDelegate.hpp @@ -22,11 +22,6 @@ #include #include -#if 0 -C_CLASS(cmn_qosProvider); -C_CLASS(cmn_qosProviderInputAttr); -#endif - namespace org { namespace eclipse @@ -41,6 +36,8 @@ class QosProviderDelegate; } } +struct dds_qos_provider; + class OMG_DDS_API org::eclipse::cyclonedds::core::QosProviderDelegate { public: @@ -49,30 +46,25 @@ class OMG_DDS_API org::eclipse::cyclonedds::core::QosProviderDelegate ~QosProviderDelegate(); dds::domain::qos::DomainParticipantQos - participant_qos(const char* id); + participant_qos(const std::string& id = ""); dds::topic::qos::TopicQos - topic_qos(const char* id); + topic_qos(const std::string& id = ""); dds::sub::qos::SubscriberQos - subscriber_qos(const char* id); + subscriber_qos(const std::string& id = ""); dds::sub::qos::DataReaderQos - datareader_qos(const char* id); + datareader_qos(const std::string& id = ""); dds::pub::qos::PublisherQos - publisher_qos(const char* id); + publisher_qos(const std::string& id = ""); dds::pub::qos::DataWriterQos - datawriter_qos(const char* id); + datawriter_qos(const std::string& id = ""); private: - template - static void named_qos__copyOut(void *from, void *to); -#if 0 - cmn_qosProvider qosProvider; - static const C_STRUCT(cmn_qosProviderInputAttr) qosProviderAttr; -#endif + dds_qos_provider *qosProvider; }; #endif /* CYCLONEDDS_CORE_QOSPROVIDERDELEGATE_HPP_ */ diff --git a/src/ddscxx/include/org/eclipse/cyclonedds/domain/qos/DomainParticipantQosDelegate.hpp b/src/ddscxx/include/org/eclipse/cyclonedds/domain/qos/DomainParticipantQosDelegate.hpp index 6433ff82..62b2e339 100644 --- a/src/ddscxx/include/org/eclipse/cyclonedds/domain/qos/DomainParticipantQosDelegate.hpp +++ b/src/ddscxx/include/org/eclipse/cyclonedds/domain/qos/DomainParticipantQosDelegate.hpp @@ -43,7 +43,7 @@ class OMG_DDS_API DomainParticipantQosDelegate /* The returned ddsc QoS has to be freed. */ dds_qos_t* ddsc_qos() const; - void ddsc_qos(const dds_qos_t* qos); + void ddsc_qos(const dds_qos_t* qos, bool copy_flags); void named_qos(const struct _DDS_NamedDomainParticipantQos &qos); diff --git a/src/ddscxx/include/org/eclipse/cyclonedds/pub/qos/DataWriterQosDelegate.hpp b/src/ddscxx/include/org/eclipse/cyclonedds/pub/qos/DataWriterQosDelegate.hpp index 725fc5f7..2930200a 100644 --- a/src/ddscxx/include/org/eclipse/cyclonedds/pub/qos/DataWriterQosDelegate.hpp +++ b/src/ddscxx/include/org/eclipse/cyclonedds/pub/qos/DataWriterQosDelegate.hpp @@ -68,7 +68,7 @@ class OMG_DDS_API DataWriterQosDelegate /* The returned ddsc QoS has to be freed. */ dds_qos_t* ddsc_qos() const; - void ddsc_qos(const dds_qos_t* qos); + void ddsc_qos(const dds_qos_t* qos, bool copy_flags); void named_qos(const struct _DDS_NamedDataWriterQos &qos); diff --git a/src/ddscxx/include/org/eclipse/cyclonedds/pub/qos/PublisherQosDelegate.hpp b/src/ddscxx/include/org/eclipse/cyclonedds/pub/qos/PublisherQosDelegate.hpp index 5adcab5b..b67847e7 100644 --- a/src/ddscxx/include/org/eclipse/cyclonedds/pub/qos/PublisherQosDelegate.hpp +++ b/src/ddscxx/include/org/eclipse/cyclonedds/pub/qos/PublisherQosDelegate.hpp @@ -45,7 +45,7 @@ class OMG_DDS_API PublisherQosDelegate /* The returned ddsc QoS has to be freed. */ dds_qos_t* ddsc_qos() const; - void ddsc_qos(const dds_qos_t* qos); + void ddsc_qos(const dds_qos_t* qos, bool copy_flags); void named_qos(const struct _DDS_NamedPublisherQos &qos); diff --git a/src/ddscxx/include/org/eclipse/cyclonedds/sub/qos/DataReaderQosDelegate.hpp b/src/ddscxx/include/org/eclipse/cyclonedds/sub/qos/DataReaderQosDelegate.hpp index c643a882..2a39abd0 100644 --- a/src/ddscxx/include/org/eclipse/cyclonedds/sub/qos/DataReaderQosDelegate.hpp +++ b/src/ddscxx/include/org/eclipse/cyclonedds/sub/qos/DataReaderQosDelegate.hpp @@ -60,7 +60,7 @@ class OMG_DDS_API DataReaderQosDelegate /* The returned ddsc QoS has to be freed. */ dds_qos_t* ddsc_qos() const; - void ddsc_qos(const dds_qos_t* qos); + void ddsc_qos(const dds_qos_t* qos, bool copy_flags); void named_qos(const struct _DDS_NamedDataReaderQos &qos); diff --git a/src/ddscxx/include/org/eclipse/cyclonedds/sub/qos/SubscriberQosDelegate.hpp b/src/ddscxx/include/org/eclipse/cyclonedds/sub/qos/SubscriberQosDelegate.hpp index 46a90016..016fc610 100644 --- a/src/ddscxx/include/org/eclipse/cyclonedds/sub/qos/SubscriberQosDelegate.hpp +++ b/src/ddscxx/include/org/eclipse/cyclonedds/sub/qos/SubscriberQosDelegate.hpp @@ -46,7 +46,7 @@ class OMG_DDS_API SubscriberQosDelegate /* The returned ddsc QoS has to be freed. */ dds_qos_t* ddsc_qos() const; - void ddsc_qos(const dds_qos_t* qos); + void ddsc_qos(const dds_qos_t* qos, bool copy_flags); void named_qos(const struct _DDS_NamedSubscriberQos &qos); diff --git a/src/ddscxx/include/org/eclipse/cyclonedds/topic/qos/TopicQosDelegate.hpp b/src/ddscxx/include/org/eclipse/cyclonedds/topic/qos/TopicQosDelegate.hpp index f10502d6..72b01602 100644 --- a/src/ddscxx/include/org/eclipse/cyclonedds/topic/qos/TopicQosDelegate.hpp +++ b/src/ddscxx/include/org/eclipse/cyclonedds/topic/qos/TopicQosDelegate.hpp @@ -61,7 +61,7 @@ class OMG_DDS_API TopicQosDelegate /* The returned ddsc QoS has to be freed. */ dds_qos_t* ddsc_qos() const; - void ddsc_qos(const dds_qos_t* qos); + void ddsc_qos(const dds_qos_t* qos, bool copy_flags); void named_qos(const struct _DDS_NamedTopicQos &qos); diff --git a/src/ddscxx/src/org/eclipse/cyclonedds/core/QosProviderDelegate.cpp b/src/ddscxx/src/org/eclipse/cyclonedds/core/QosProviderDelegate.cpp new file mode 100644 index 00000000..674ec2d1 --- /dev/null +++ b/src/ddscxx/src/org/eclipse/cyclonedds/core/QosProviderDelegate.cpp @@ -0,0 +1,135 @@ +// Copyright(c) 2006 to 2021 ZettaScale Technology and others +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License +// v. 1.0 which is available at +// http://www.eclipse.org/org/documents/edl-v10.php. +// +// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + +/** + * @file + */ + +#include + +#include + +namespace org +{ +namespace eclipse +{ +namespace cyclonedds +{ +namespace core +{ + +QosProviderDelegate::QosProviderDelegate(const std::string& uri, const std::string& id) : qosProvider(nullptr) +{ + dds_return_t ret; + + ret = dds_create_qos_provider_scope(uri.c_str(), &qosProvider, id.c_str()); + ISOCPP_DDSC_RESULT_CHECK_AND_THROW(ret, "Unable to create QosProvider."); +} + +QosProviderDelegate::~QosProviderDelegate() +{ + dds_delete_qos_provider(qosProvider); +} + +dds::domain::qos::DomainParticipantQos +QosProviderDelegate::participant_qos(const std::string &id) +{ + dds::domain::qos::DomainParticipantQos dpq; + const dds_qos_t *c_dpq = NULL; + dds_return_t ret; + + ret = dds_qos_provider_get_qos(qosProvider, DDS_PARTICIPANT_QOS, id.c_str(), &c_dpq); + ISOCPP_DDSC_RESULT_CHECK_AND_THROW(ret, "Unable to obtain requested participant QoS."); + + dpq.delegate().ddsc_qos(c_dpq, false); + + return dpq; +} + +dds::topic::qos::TopicQos +QosProviderDelegate::topic_qos(const std::string &id) +{ + dds::topic::qos::TopicQos tq; + const dds_qos_t *c_tq = NULL; + dds_return_t ret; + + ret = dds_qos_provider_get_qos(qosProvider, DDS_TOPIC_QOS, id.c_str(), &c_tq); + ISOCPP_DDSC_RESULT_CHECK_AND_THROW(ret, "Unable to obtain requested topic QoS."); + + tq.delegate().ddsc_qos(c_tq, false); + + return tq; +} + + +dds::sub::qos::SubscriberQos +QosProviderDelegate::subscriber_qos(const std::string &id) +{ + dds::sub::qos::SubscriberQos sq; + const dds_qos_t *c_sq = NULL; + dds_return_t ret; + + ret = dds_qos_provider_get_qos(qosProvider, DDS_SUBSCRIBER_QOS, id.c_str(), &c_sq); + ISOCPP_DDSC_RESULT_CHECK_AND_THROW(ret, "Unable to obtain requested subscriber QoS."); + + sq.delegate().ddsc_qos(c_sq, false); + + return sq; +} + +dds::sub::qos::DataReaderQos +QosProviderDelegate::datareader_qos(const std::string &id) +{ + dds::sub::qos::DataReaderQos drq; + const dds_qos_t *c_drq = NULL; + dds_return_t ret; + + ret = dds_qos_provider_get_qos(qosProvider, DDS_READER_QOS, id.c_str(), &c_drq); + ISOCPP_DDSC_RESULT_CHECK_AND_THROW(ret, "Unable to obtain requested datareader QoS."); + + drq.delegate().ddsc_qos(c_drq, false); + + return drq; +} + +dds::pub::qos::PublisherQos +QosProviderDelegate::publisher_qos(const std::string &id) +{ + dds::pub::qos::PublisherQos pq; + const dds_qos_t *c_pq = NULL; + dds_return_t ret; + + ret = dds_qos_provider_get_qos(qosProvider, DDS_PUBLISHER_QOS, id.c_str(), &c_pq); + ISOCPP_DDSC_RESULT_CHECK_AND_THROW(ret, "Unable to obtain requested publisher QoS."); + + pq.delegate().ddsc_qos(c_pq, false); + + return pq; +} + +dds::pub::qos::DataWriterQos +QosProviderDelegate::datawriter_qos(const std::string &id) +{ + dds::pub::qos::DataWriterQos dwq; + const dds_qos_t *c_dwq = NULL; + dds_return_t ret; + + ret = dds_qos_provider_get_qos(qosProvider, DDS_WRITER_QOS, id.c_str(), &c_dwq); + ISOCPP_DDSC_RESULT_CHECK_AND_THROW(ret, "Unable to obtain requested datawriter QoS."); + + dwq.delegate().ddsc_qos(c_dwq, false); + + return dwq; +} + +} +} +} +} diff --git a/src/ddscxx/src/org/eclipse/cyclonedds/core/policy/PolicyDelegate.cpp b/src/ddscxx/src/org/eclipse/cyclonedds/core/policy/PolicyDelegate.cpp index 3595abe9..4c8dad57 100644 --- a/src/ddscxx/src/org/eclipse/cyclonedds/core/policy/PolicyDelegate.cpp +++ b/src/ddscxx/src/org/eclipse/cyclonedds/core/policy/PolicyDelegate.cpp @@ -514,6 +514,7 @@ void GroupDataDelegate::set_c_policy(dds_qos_t* qos) const void* data = NULL; org::eclipse::cyclonedds::core::convertByteSeq(value_, data, static_cast(value_.size())); dds_qset_groupdata(qos, data, value_.size()); + dds_free(data); } } @@ -1465,6 +1466,7 @@ void TopicDataDelegate::set_c_policy(dds_qos_t* qos) const void* data = NULL; org::eclipse::cyclonedds::core::convertByteSeq(value_, data, static_cast(value_.size())); dds_qset_topicdata(qos, data, value_.size()); + dds_free(data); } } diff --git a/src/ddscxx/src/org/eclipse/cyclonedds/domain/qos/DomainParticipantQosDelegate.cpp b/src/ddscxx/src/org/eclipse/cyclonedds/domain/qos/DomainParticipantQosDelegate.cpp index 239d383b..86cc8e6b 100644 --- a/src/ddscxx/src/org/eclipse/cyclonedds/domain/qos/DomainParticipantQosDelegate.cpp +++ b/src/ddscxx/src/org/eclipse/cyclonedds/domain/qos/DomainParticipantQosDelegate.cpp @@ -32,7 +32,7 @@ namespace qos DomainParticipantQosDelegate::DomainParticipantQosDelegate() { - ddsc_qos(&ddsi_default_qos_participant); + ddsc_qos(&ddsi_default_qos_participant, true); check(); } @@ -67,13 +67,14 @@ DomainParticipantQosDelegate::ddsc_qos() const } void -DomainParticipantQosDelegate::ddsc_qos(const dds_qos_t* qos) +DomainParticipantQosDelegate::ddsc_qos(const dds_qos_t* qos, bool copy_flags) { assert(qos); - present_ = qos->present; - if (present_ & DDSI_QP_USER_DATA) + if (copy_flags) + present_ = qos->present; + if (qos->present & DDSI_QP_USER_DATA) user_data_.delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_ADLINK_ENTITY_FACTORY) + if (qos->present & DDSI_QP_ADLINK_ENTITY_FACTORY) entity_factory_.delegate().set_iso_policy(qos); } @@ -103,7 +104,7 @@ DomainParticipantQosDelegate::check() const bool DomainParticipantQosDelegate::operator ==(const DomainParticipantQosDelegate& other) const { - return other.present_ == present_ && + return other.present_ == present_ && other.user_data_ == user_data_ && other.entity_factory_ == entity_factory_; diff --git a/src/ddscxx/src/org/eclipse/cyclonedds/pub/qos/DataWriterQosDelegate.cpp b/src/ddscxx/src/org/eclipse/cyclonedds/pub/qos/DataWriterQosDelegate.cpp index 8372ca4e..bae59eb4 100644 --- a/src/ddscxx/src/org/eclipse/cyclonedds/pub/qos/DataWriterQosDelegate.cpp +++ b/src/ddscxx/src/org/eclipse/cyclonedds/pub/qos/DataWriterQosDelegate.cpp @@ -32,7 +32,7 @@ namespace qos DataWriterQosDelegate::DataWriterQosDelegate() { - ddsc_qos(&ddsi_default_qos_writer); + ddsc_qos(&ddsi_default_qos_writer, true); present() &= ~DDSI_QP_DATA_REPRESENTATION; check(); } @@ -256,53 +256,54 @@ DataWriterQosDelegate::ddsc_qos() const } void -DataWriterQosDelegate::ddsc_qos(const dds_qos_t* qos) +DataWriterQosDelegate::ddsc_qos(const dds_qos_t* qos, bool copy_flags) { assert(qos); - present_ = qos->present; - if (present_ & DDSI_QP_USER_DATA) + if (copy_flags) + present_ = qos->present; + if (qos->present & DDSI_QP_USER_DATA) user_data_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_DURABILITY) + if (qos->present & DDSI_QP_DURABILITY) durability_ .delegate().set_iso_policy(qos); #ifdef OMG_DDS_PERSISTENCE_SUPPORT - if (present_ & DDSI_QP_DURABILITY_SERVICE) + if (qos->present & DDSI_QP_DURABILITY_SERVICE) durability_service_.delegate().set_iso_policy(qos); #endif // OMG_DDS_PERSISTENCE_SUPPORT - if (present_ & DDSI_QP_DEADLINE) + if (qos->present & DDSI_QP_DEADLINE) deadline_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_LATENCY_BUDGET) + if (qos->present & DDSI_QP_LATENCY_BUDGET) budget_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_LIVELINESS) + if (qos->present & DDSI_QP_LIVELINESS) liveliness_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_RELIABILITY) + if (qos->present & DDSI_QP_RELIABILITY) reliability_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_DESTINATION_ORDER) + if (qos->present & DDSI_QP_DESTINATION_ORDER) order_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_HISTORY) + if (qos->present & DDSI_QP_HISTORY) history_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_RESOURCE_LIMITS) + if (qos->present & DDSI_QP_RESOURCE_LIMITS) resources_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_TRANSPORT_PRIORITY) + if (qos->present & DDSI_QP_TRANSPORT_PRIORITY) priority_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_LIFESPAN) + if (qos->present & DDSI_QP_LIFESPAN) lifespan_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_OWNERSHIP) + if (qos->present & DDSI_QP_OWNERSHIP) ownership_ .delegate().set_iso_policy(qos); #ifdef OMG_DDS_OWNERSHIP_SUPPORT - if (present_ & DDSI_QP_OWNERSHIP_STRENGTH) + if (qos->present & DDSI_QP_OWNERSHIP_STRENGTH) strength_ .delegate().set_iso_policy(qos); #endif // OMG_DDS_OWNERSHIP_SUPPORT - if (present_ & DDSI_QP_ADLINK_WRITER_DATA_LIFECYCLE) + if (qos->present & DDSI_QP_ADLINK_WRITER_DATA_LIFECYCLE) lifecycle_ .delegate().set_iso_policy(qos); #ifdef OMG_DDS_EXTENSIBLE_AND_DYNAMIC_TOPIC_TYPE_SUPPORT - if (present_ & DDSI_QP_DATA_REPRESENTATION) + if (qos->present & DDSI_QP_DATA_REPRESENTATION) datarepresentation_.delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_TYPE_CONSISTENCY_ENFORCEMENT) + if (qos->present & DDSI_QP_TYPE_CONSISTENCY_ENFORCEMENT) typeconsistencyenforcement_.delegate().set_iso_policy(qos); #endif // OMG_DDS_EXTENSIBLE_AND_DYNAMIC_TOPIC_TYPE_SUPPORT - if (present_ & DDSI_QP_CYCLONE_WRITER_BATCHING) + if (qos->present & DDSI_QP_CYCLONE_WRITER_BATCHING) writerbatching_.delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_PSMX) + if (qos->present & DDSI_QP_PSMX) psmxinstances_.delegate().set_iso_policy(qos); } @@ -373,13 +374,13 @@ DataWriterQosDelegate::operator ==(const DataWriterQosDelegate& other) const #ifdef OMG_DDS_OWNERSHIP_SUPPORT other.strength_ == strength_ && #endif - other.lifecycle_ == lifecycle_ + other.lifecycle_ == lifecycle_ && #ifdef OMG_DDS_EXTENSIBLE_AND_DYNAMIC_TOPIC_TYPE_SUPPORT - && other.datarepresentation_ == datarepresentation_ - && other.typeconsistencyenforcement_ == typeconsistencyenforcement_ + other.datarepresentation_ == datarepresentation_ && + other.typeconsistencyenforcement_ == typeconsistencyenforcement_ && #endif // OMG_DDS_EXTENSIBLE_AND_DYNAMIC_TOPIC_TYPE_SUPPORT - && other.writerbatching_ == writerbatching_ - && other.psmxinstances_ == psmxinstances_ + other.writerbatching_ == writerbatching_ && + other.psmxinstances_ == psmxinstances_ ; } diff --git a/src/ddscxx/src/org/eclipse/cyclonedds/pub/qos/PublisherQosDelegate.cpp b/src/ddscxx/src/org/eclipse/cyclonedds/pub/qos/PublisherQosDelegate.cpp index f1746d9d..0fe813f9 100644 --- a/src/ddscxx/src/org/eclipse/cyclonedds/pub/qos/PublisherQosDelegate.cpp +++ b/src/ddscxx/src/org/eclipse/cyclonedds/pub/qos/PublisherQosDelegate.cpp @@ -32,7 +32,7 @@ namespace qos PublisherQosDelegate::PublisherQosDelegate() { - ddsc_qos(&ddsi_default_qos_publisher_subscriber); + ddsc_qos(&ddsi_default_qos_publisher_subscriber, true); check(); } @@ -87,17 +87,18 @@ PublisherQosDelegate::ddsc_qos() const } void -PublisherQosDelegate::ddsc_qos(const dds_qos_t* qos) +PublisherQosDelegate::ddsc_qos(const dds_qos_t* qos, bool copy_flags) { assert(qos); - present_ = qos->present; - if (present_ & DDSI_QP_PRESENTATION) + if (copy_flags) + present_ = qos->present; + if (qos->present & DDSI_QP_PRESENTATION) presentation_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_PARTITION) + if (qos->present & DDSI_QP_PARTITION) partition_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_GROUP_DATA) + if (qos->present & DDSI_QP_GROUP_DATA) gdata_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_ADLINK_ENTITY_FACTORY) + if (qos->present & DDSI_QP_ADLINK_ENTITY_FACTORY) factory_policy_ .delegate().set_iso_policy(qos); } @@ -127,7 +128,7 @@ PublisherQosDelegate::check() const bool PublisherQosDelegate::operator ==(const PublisherQosDelegate& other) const { - return other.present_ == present_ && + return other.present_ == present_ && other.presentation_ == presentation_ && other.partition_ == partition_ && other.gdata_ == gdata_ && diff --git a/src/ddscxx/src/org/eclipse/cyclonedds/sub/qos/DataReaderQosDelegate.cpp b/src/ddscxx/src/org/eclipse/cyclonedds/sub/qos/DataReaderQosDelegate.cpp index 50545084..483320b0 100644 --- a/src/ddscxx/src/org/eclipse/cyclonedds/sub/qos/DataReaderQosDelegate.cpp +++ b/src/ddscxx/src/org/eclipse/cyclonedds/sub/qos/DataReaderQosDelegate.cpp @@ -32,7 +32,7 @@ namespace qos DataReaderQosDelegate::DataReaderQosDelegate() { - ddsc_qos(&ddsi_default_qos_reader); + ddsc_qos(&ddsi_default_qos_reader, true); present() &= ~DDSI_QP_DATA_REPRESENTATION; check(); } @@ -208,41 +208,42 @@ DataReaderQosDelegate::ddsc_qos() const } void -DataReaderQosDelegate::ddsc_qos(const dds_qos_t* qos) +DataReaderQosDelegate::ddsc_qos(const dds_qos_t* qos, bool copy_flags) { assert(qos); - present_ = qos->present; - if (present_ & DDSI_QP_DEADLINE) + if (copy_flags) + present_ = qos->present; + if (qos->present & DDSI_QP_DEADLINE) deadline_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_DURABILITY) + if (qos->present & DDSI_QP_DURABILITY) durability_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_HISTORY) + if (qos->present & DDSI_QP_HISTORY) history_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_LATENCY_BUDGET) + if (qos->present & DDSI_QP_LATENCY_BUDGET) budget_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_ADLINK_READER_DATA_LIFECYCLE) + if (qos->present & DDSI_QP_ADLINK_READER_DATA_LIFECYCLE) lifecycle_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_LIVELINESS) + if (qos->present & DDSI_QP_LIVELINESS) liveliness_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_DESTINATION_ORDER) + if (qos->present & DDSI_QP_DESTINATION_ORDER) order_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_OWNERSHIP) + if (qos->present & DDSI_QP_OWNERSHIP) ownership_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_TIME_BASED_FILTER) + if (qos->present & DDSI_QP_TIME_BASED_FILTER) tfilter_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_RELIABILITY) + if (qos->present & DDSI_QP_RELIABILITY) reliability_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_RESOURCE_LIMITS) + if (qos->present & DDSI_QP_RESOURCE_LIMITS) resources_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_USER_DATA) + if (qos->present & DDSI_QP_USER_DATA) user_data_ .delegate().set_iso_policy(qos); #ifdef OMG_DDS_EXTENSIBLE_AND_DYNAMIC_TOPIC_TYPE_SUPPORT - if (present_ & DDSI_QP_DATA_REPRESENTATION) + if (qos->present & DDSI_QP_DATA_REPRESENTATION) datarepresentation_.delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_TYPE_CONSISTENCY_ENFORCEMENT) + if (qos->present & DDSI_QP_TYPE_CONSISTENCY_ENFORCEMENT) typeconsistencyenforcement_.delegate().set_iso_policy(qos); #endif // OMG_DDS_EXTENSIBLE_AND_DYNAMIC_TOPIC_TYPE_SUPPORT - if (present_ & DDSI_QP_PSMX) + if (qos->present & DDSI_QP_PSMX) psmxinstances_.delegate().set_iso_policy(qos); } @@ -300,12 +301,12 @@ DataReaderQosDelegate::operator==(const DataReaderQosDelegate& other) const other.resources_ == resources_ && other.ownership_ == ownership_ && other.tfilter_ == tfilter_ && - other.lifecycle_ == lifecycle_ + other.lifecycle_ == lifecycle_ && #ifdef OMG_DDS_EXTENSIBLE_AND_DYNAMIC_TOPIC_TYPE_SUPPORT - && other.datarepresentation_ == datarepresentation_ - && other.typeconsistencyenforcement_ == typeconsistencyenforcement_ + other.datarepresentation_ == datarepresentation_ && + other.typeconsistencyenforcement_ == typeconsistencyenforcement_ && #endif // OMG_DDS_EXTENSIBLE_AND_DYNAMIC_TOPIC_TYPE_SUPPORT - && other.psmxinstances_ == psmxinstances_ + other.psmxinstances_ == psmxinstances_ ; } diff --git a/src/ddscxx/src/org/eclipse/cyclonedds/sub/qos/SubscriberQosDelegate.cpp b/src/ddscxx/src/org/eclipse/cyclonedds/sub/qos/SubscriberQosDelegate.cpp index 8de64ad8..6efbcf5f 100644 --- a/src/ddscxx/src/org/eclipse/cyclonedds/sub/qos/SubscriberQosDelegate.cpp +++ b/src/ddscxx/src/org/eclipse/cyclonedds/sub/qos/SubscriberQosDelegate.cpp @@ -32,7 +32,7 @@ namespace qos SubscriberQosDelegate::SubscriberQosDelegate() { - ddsc_qos(&ddsi_default_qos_publisher_subscriber); + ddsc_qos(&ddsi_default_qos_publisher_subscriber, true); check(); } @@ -87,17 +87,18 @@ SubscriberQosDelegate::ddsc_qos() const } void -SubscriberQosDelegate::ddsc_qos(const dds_qos_t* qos) +SubscriberQosDelegate::ddsc_qos(const dds_qos_t* qos, bool copy_flags) { assert(qos); - present_ = qos->present; - if (present_ & DDSI_QP_PRESENTATION) + if (copy_flags) + present_ = qos->present; + if (qos->present & DDSI_QP_PRESENTATION) presentation_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_PARTITION) + if (qos->present & DDSI_QP_PARTITION) partition_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_GROUP_DATA) + if (qos->present & DDSI_QP_GROUP_DATA) group_data_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_ADLINK_ENTITY_FACTORY) + if (qos->present & DDSI_QP_ADLINK_ENTITY_FACTORY) entity_factory_ .delegate().set_iso_policy(qos); } diff --git a/src/ddscxx/src/org/eclipse/cyclonedds/topic/AnyTopicDelegate.cpp b/src/ddscxx/src/org/eclipse/cyclonedds/topic/AnyTopicDelegate.cpp index 36014c10..d043d2ee 100644 --- a/src/ddscxx/src/org/eclipse/cyclonedds/topic/AnyTopicDelegate.cpp +++ b/src/ddscxx/src/org/eclipse/cyclonedds/topic/AnyTopicDelegate.cpp @@ -163,7 +163,7 @@ AnyTopicDelegate::discover_topic( ret = dds_get_qos(ddsc_topic, ddsc_qos); dds::topic::qos::TopicQos qos; if (ret == DDS_RETCODE_OK) { - qos.delegate().ddsc_qos(ddsc_qos); + qos.delegate().ddsc_qos(ddsc_qos, false); } dds_delete_qos(ddsc_qos); ISOCPP_DDSC_RESULT_CHECK_AND_THROW(ret, "Failed to get the qos from discovered topic"); diff --git a/src/ddscxx/src/org/eclipse/cyclonedds/topic/qos/TopicQosDelegate.cpp b/src/ddscxx/src/org/eclipse/cyclonedds/topic/qos/TopicQosDelegate.cpp index 69838822..42c12ecf 100644 --- a/src/ddscxx/src/org/eclipse/cyclonedds/topic/qos/TopicQosDelegate.cpp +++ b/src/ddscxx/src/org/eclipse/cyclonedds/topic/qos/TopicQosDelegate.cpp @@ -32,7 +32,7 @@ namespace qos TopicQosDelegate::TopicQosDelegate() { - ddsc_qos(&ddsi_default_qos_topic); + ddsc_qos(&ddsi_default_qos_topic, true); present() &= ~DDSI_QP_DATA_REPRESENTATION; check(); } @@ -206,42 +206,43 @@ TopicQosDelegate::ddsc_qos() const } void -TopicQosDelegate::ddsc_qos(const dds_qos_t* qos) +TopicQosDelegate::ddsc_qos(const dds_qos_t* qos, bool copy_flags) { assert(qos); - present_ = qos->present; - if (present_ & DDSI_QP_TOPIC_DATA) + if (copy_flags) + present_ = qos->present; + if (qos->present & DDSI_QP_TOPIC_DATA) topic_data_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_DURABILITY) + if (qos->present & DDSI_QP_DURABILITY) durability_ .delegate().set_iso_policy(qos); #ifdef OMG_DDS_PERSISTENCE_SUPPORT - if (present_ & DDSI_QP_DURABILITY_SERVICE) + if (qos->present & DDSI_QP_DURABILITY_SERVICE) durability_service_.delegate().set_iso_policy(qos); #endif // OMG_DDS_PERSISTENCE_SUPPORT - if (present_ & DDSI_QP_DEADLINE) + if (qos->present & DDSI_QP_DEADLINE) deadline_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_LATENCY_BUDGET) + if (qos->present & DDSI_QP_LATENCY_BUDGET) budget_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_LIVELINESS) + if (qos->present & DDSI_QP_LIVELINESS) liveliness_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_RELIABILITY) + if (qos->present & DDSI_QP_RELIABILITY) reliability_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_DESTINATION_ORDER) + if (qos->present & DDSI_QP_DESTINATION_ORDER) order_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_HISTORY) + if (qos->present & DDSI_QP_HISTORY) history_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_RESOURCE_LIMITS) + if (qos->present & DDSI_QP_RESOURCE_LIMITS) resources_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_TRANSPORT_PRIORITY) + if (qos->present & DDSI_QP_TRANSPORT_PRIORITY) priority_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_LIFESPAN) + if (qos->present & DDSI_QP_LIFESPAN) lifespan_ .delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_OWNERSHIP) + if (qos->present & DDSI_QP_OWNERSHIP) ownership_ .delegate().set_iso_policy(qos); #ifdef OMG_DDS_EXTENSIBLE_AND_DYNAMIC_TOPIC_TYPE_SUPPORT - if (present_ & DDSI_QP_DATA_REPRESENTATION) + if (qos->present & DDSI_QP_DATA_REPRESENTATION) datarepresentation_.delegate().set_iso_policy(qos); - if (present_ & DDSI_QP_TYPE_CONSISTENCY_ENFORCEMENT) + if (qos->present & DDSI_QP_TYPE_CONSISTENCY_ENFORCEMENT) typeconsistencyenforcement_.delegate().set_iso_policy(qos); #endif // OMG_DDS_EXTENSIBLE_AND_DYNAMIC_TOPIC_TYPE_SUPPORT } @@ -288,7 +289,7 @@ TopicQosDelegate::check() const bool TopicQosDelegate::operator ==(const TopicQosDelegate& other) const { - return other.present_ == present_ && + return other.present_ == present_ && other.topic_data_ == topic_data_ && other.durability_ == durability_ && #ifdef OMG_DDS_PERSISTENCE_SUPPORT diff --git a/src/ddscxx/tests/CMakeLists.txt b/src/ddscxx/tests/CMakeLists.txt index de37ca3e..222aefce 100644 --- a/src/ddscxx/tests/CMakeLists.txt +++ b/src/ddscxx/tests/CMakeLists.txt @@ -79,6 +79,11 @@ if (ENABLE_TYPELIB AND ENABLE_TOPIC_DISCOVERY) TopicTypeDiscovery.cpp) endif() +if (ENABLE_QOS_PROVIDER) + list(APPEND sources + QosProvider.cpp) +endif() + if(ENABLE_ICEORYX) list(APPEND sources Iceoryx.cpp) endif() @@ -93,6 +98,12 @@ if(DEFINED ENV{SYSTEM_TEAMFOUNDATIONSERVERURI}) endif() endif() +target_include_directories( + ddscxx_tests + PRIVATE + "$") + + set_property(TARGET ddscxx_tests PROPERTY CXX_STANDARD ${cyclonedds_cpp_std_to_use}) target_link_libraries( ddscxx_tests PRIVATE diff --git a/src/ddscxx/tests/QosProvider.cpp b/src/ddscxx/tests/QosProvider.cpp new file mode 100644 index 00000000..0000a6a8 --- /dev/null +++ b/src/ddscxx/tests/QosProvider.cpp @@ -0,0 +1,951 @@ +// Copyright(c) 2006 to 2022 ZettaScale Technology and others +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License +// v. 1.0 which is available at +// http://www.eclipse.org/org/documents/edl-v10.php. +// +// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + +#include + +#include "dds/dds.hpp" +#include "dds/ddsc/dds_public_qos_provider.h" +#include "dds/ddsrt/string.h" +#include "dds/ddsrt/io.h" + +#define QOS_LENGTH_UNLIMITED "LENGTH_UNLIMITED" +#define QOS_DURATION_INFINITY "DURATION_INFINITY" +#define QOS_DURATION_INFINITY_SEC "DURATION_INFINITE_SEC" +#define QOS_DURATION_INFINITY_NSEC "DURATION_INFINITE_NSEC" + +#define DEF(libs) \ + "\n" libs "\n" +#define LIB(lib_name,profiles) \ + "\n " profiles "\n " +#define N_LIB(profiles) \ + "\n " profiles "\n " +#define PRO(prof_name,ents) \ + "\n " ents "\n " +#define N_PRO(ents) \ + "\n " ents "\n " +#define ENT(qos,kind) \ + "\n <" #kind "_qos>" qos "\n " +#define ENT_N(nm,qos,kind) \ + "\n <" #kind "_qos name=\"" #nm "\">" qos "\n " + + +#define QOS_DURATION_FMT(unit) \ + "<" #unit ">%lli" +#define QOS_DURATION_FMT_STR(unit) \ + "<" #unit ">%s" +#define QOS_POLICY_DEADLINE_PERIOD_FMT(duration_fmt) \ + "" duration_fmt "" +#define QOS_POLICY_DEADLINE_FMT(unit) \ + "" QOS_POLICY_DEADLINE_PERIOD_FMT(unit) "" +#define QOS_POLICY_DESTINATION_ORDER_FMT(k) \ + "" #k "" +#define QOS_POLICY_DURABILITY_FMT(k) \ + "" #k "" +#define QOS_HISTORY_FMT(hk) \ + "" #hk "%d" +#define QOS_SERVICE_CLEANUP_DELAY_FMT(duration_fmt) \ + "" duration_fmt "" +#define QOS_RESOURCE_LIMITS_MS(ms_f) \ + "" ms_f "" +#define QOS_RESOURCE_LIMITS_MI(mi_f) \ + "" mi_f "" +#define QOS_RESOURCE_LIMITS_MSPI(mspi_f) \ + "" mspi_f "" +#define QOS_RESOURCE_LIMITS \ + "%s%s%s" +#define QOS_DURABILITY_SERVICE_HISTORY(hk) \ + "" #hk "%d" +#define QOS_POLICY_DURABILITY_SERVICE_FMT \ + "%s%s" QOS_RESOURCE_LIMITS "" +#define QOS_POLICY_ENTITYFACTORY_FMT(val) \ + "" \ + "" #val "" \ + "" +#define QOS_BASE64_VALUE \ + "%s" +#define QOS_POLICY_GOUPDATA_FMT \ + "" QOS_BASE64_VALUE "" +#define QOS_POLICY_HISTORY_FMT(hk) \ + QOS_HISTORY_FMT(hk) +#define QOS_POLICY_LATENCYBUDGET_FMT(duration_fmt) \ + "" duration_fmt "" +#define QOS_POLICY_LIFESPAN_FMT(duration_fmt) \ + "" duration_fmt "" +#define QOS_LIVELINESS_KIND(lk) \ + "" #lk "" +#define QOS_LIVELINESS_DURATION(duration_fmt) \ + "" duration_fmt "" +#define QOS_POLICY_LIVELINESS_FMT \ + "%s%s" +#define QOS_POLICY_OWNERSHIP_FMT(ok) \ + "" #ok "" +#define QOS_POLICY_OWNERSHIPSTRENGTH_FMT \ + "%d" +#define QOS_PARTITION_ELEMENT \ + "%s" +#define QOS_POLIC_PARTITION_FMT \ + "%s" +#define QOS_ACCESS_SCOPE_KIND(ask) \ + "" #ask "" +#define QOS_COHERENT_ACCESS(ca) \ + "" #ca "" +#define QOS_ORDERED_ACCESS(oa) \ + "" #oa "" +#define QOS_POLICY_PRESENTATION_FMT \ + "%s%s%s" +#define QOS_RELIABILITY_KIND(rk) \ + "" #rk "" +#define QOS_RELIABILITY_DURATION(duration_fmt) \ + "" duration_fmt "" +#define QOS_POLICY_RELIABILITY_FMT \ + "%s%s" +#define QOS_POLICY_RESOURCE_LIMITS_FMT \ + "" QOS_RESOURCE_LIMITS "" +#define QOS_POLICY_TIMEBASEDFILTER_FMT(duration_fmt) \ + "" \ + duration_fmt \ + "" +#define QOS_POLICY_TOPICDATA_FMT \ + "" QOS_BASE64_VALUE "" +#define QOS_POLICY_TRANSPORTPRIORITY_FMT \ + "%d" +#define QOS_POLICY_USERDATA_FMT \ + "" QOS_BASE64_VALUE "" +#define QOS_NOWRITER_DELAY(duration_fmt) \ + "" duration_fmt "" +#define QOS_DISPOSED_DELAY(duration_fmt) \ + "" \ + duration_fmt \ + "" +#define QOS_POLICY_READERDATALIFECYCLE_FMT \ + "%s%s" +#define QOS_POLICY_WRITERDATA_LIFECYCLE_FMT(aui) \ + "" \ + "" #aui "" \ + "" + + + +/** + * Fixture for the DataReader tests + */ +class QosProvider : public ::testing::Test +{ +public: + dds::domain::qos::DomainParticipantQos pQos; + dds::sub::qos::SubscriberQos subQos; + dds::pub::qos::PublisherQos pubQos; + dds::topic::qos::TopicQos tQos; + dds::sub::qos::DataReaderQos rQos; + dds::pub::qos::DataWriterQos wQos; + + enum duration_unit + { + sec = 0, + nsec = 1 + }; + + typedef struct sysdef_qos_conf + { + enum duration_unit deadline_unit; + enum duration_unit durability_serv_unit; + enum duration_unit latency_budget_unit; + enum duration_unit lifespan_unit; + enum duration_unit liveliness_unit; + enum duration_unit reliability_unit; + enum duration_unit time_based_filter_unit; + enum duration_unit reader_data_lifecycle_nowriter_unit; + enum duration_unit reader_data_lifecycle_disposed_unit; + } sysdef_qos_conf_t; + +#define QOS_FORMAT " " +#define CHECK_RET_OK(ret) \ + if (ret < 0) goto fail; + static inline dds_return_t qos_to_conf(dds_qos_t *qos, const sysdef_qos_conf_t *conf, char **out, dds_qos_kind_t kind, uint64_t *validate_mask, const bool ignore_ent) + { + char *sysdef_qos = ddsrt_strdup(""); + dds_return_t ret = DDS_RETCODE_OK; + if ((ignore_ent || (kind == DDS_TOPIC_QOS || kind == DDS_READER_QOS || kind == DDS_WRITER_QOS)) && + (ret >= 0) && (qos->present & DDSI_QP_DEADLINE)) + { + char *deadline; + if (qos->deadline.deadline == DDS_INFINITY) + { + if (conf->deadline_unit == sec) + ret = ddsrt_asprintf(&deadline, QOS_POLICY_DEADLINE_FMT(QOS_DURATION_FMT_STR(sec)), + QOS_DURATION_INFINITY_SEC); + else + ret = ddsrt_asprintf(&deadline, QOS_POLICY_DEADLINE_FMT(QOS_DURATION_FMT_STR(nanosec)), + QOS_DURATION_INFINITY_NSEC); + } else { + if (conf->deadline_unit == sec) + ret = ddsrt_asprintf(&deadline, QOS_POLICY_DEADLINE_FMT(QOS_DURATION_FMT(sec)), + static_cast(qos->deadline.deadline/DDS_NSECS_IN_SEC)); + else + ret = ddsrt_asprintf(&deadline, QOS_POLICY_DEADLINE_FMT(QOS_DURATION_FMT(nanosec)), + static_cast(qos->deadline.deadline)); + } + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT "%s\n" QOS_FORMAT "%s", sysdef_qos, deadline); + ddsrt_free(tmp); + ddsrt_free(deadline); + *validate_mask |= DDSI_QP_DEADLINE; + } + if ((ignore_ent || (kind == DDS_TOPIC_QOS || kind == DDS_READER_QOS || kind == DDS_WRITER_QOS)) && + (ret >= 0) && (qos->present & DDSI_QP_DESTINATION_ORDER)) + { + char *dest_order; + if (qos->destination_order.kind == DDS_DESTINATIONORDER_BY_RECEPTION_TIMESTAMP) + ret = ddsrt_asprintf(&dest_order, "%s", QOS_POLICY_DESTINATION_ORDER_FMT(BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS)); + else + ret = ddsrt_asprintf(&dest_order, "%s", QOS_POLICY_DESTINATION_ORDER_FMT(BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS)); + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT "%s\n" QOS_FORMAT "%s", sysdef_qos, dest_order); + ddsrt_free(tmp); + ddsrt_free(dest_order); + *validate_mask |= DDSI_QP_DESTINATION_ORDER; + } + if ((ignore_ent || (kind != DDS_SUBSCRIBER_QOS && kind != DDS_PUBLISHER_QOS && kind != DDS_PARTICIPANT_QOS)) && + (ret >= 0) && (qos->present & DDSI_QP_DURABILITY)) + { + char *durability; + if (qos->durability.kind == DDS_DURABILITY_VOLATILE) + ret = ddsrt_asprintf(&durability, "%s", QOS_POLICY_DURABILITY_FMT(VOLATILE_DURABILITY_QOS)); + else if (qos->durability.kind == DDS_DURABILITY_TRANSIENT_LOCAL) + ret = ddsrt_asprintf(&durability, "%s", QOS_POLICY_DURABILITY_FMT(TRANSIENT_LOCAL_DURABILITY_QOS)); + else if (qos->durability.kind == DDS_DURABILITY_TRANSIENT) + ret = ddsrt_asprintf(&durability, "%s", QOS_POLICY_DURABILITY_FMT(TRANSIENT_DURABILITY_QOS)); + else + ret = ddsrt_asprintf(&durability, "%s", QOS_POLICY_DURABILITY_FMT(PERSISTENT_DURABILITY_QOS)); + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT "%s\n" QOS_FORMAT "%s", sysdef_qos, durability); + ddsrt_free(tmp); + ddsrt_free(durability); + *validate_mask |= DDSI_QP_DURABILITY; + } + if ((ignore_ent || (kind == DDS_WRITER_QOS || kind == DDS_TOPIC_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_DURABILITY_SERVICE) + { + char *service_cleanup_delay; + if (qos->durability_service.service_cleanup_delay == DDS_INFINITY) + { + if (conf->durability_serv_unit == sec) + ret = ddsrt_asprintf(&service_cleanup_delay, QOS_SERVICE_CLEANUP_DELAY_FMT(QOS_DURATION_FMT_STR(sec)), + QOS_DURATION_INFINITY_SEC); + else + ret = ddsrt_asprintf(&service_cleanup_delay, QOS_SERVICE_CLEANUP_DELAY_FMT(QOS_DURATION_FMT_STR(nanosec)), + QOS_DURATION_INFINITY_NSEC); + } else { + if (conf->durability_serv_unit == sec) + ret = ddsrt_asprintf(&service_cleanup_delay, QOS_SERVICE_CLEANUP_DELAY_FMT(QOS_DURATION_FMT(sec)), + static_cast(qos->durability_service.service_cleanup_delay/DDS_NSECS_IN_SEC)); + else + ret = ddsrt_asprintf(&service_cleanup_delay, QOS_SERVICE_CLEANUP_DELAY_FMT(QOS_DURATION_FMT(nanosec)), + static_cast(qos->durability_service.service_cleanup_delay)); + } + CHECK_RET_OK(ret); + char *history; + if (qos->durability_service.history.kind == DDS_HISTORY_KEEP_LAST) + ret = ddsrt_asprintf(&history, QOS_DURABILITY_SERVICE_HISTORY(KEEP_LAST_HISTORY_QOS), qos->durability_service.history.depth); + else + ret = ddsrt_asprintf(&history, QOS_DURABILITY_SERVICE_HISTORY(KEEP_ALL_HISTORY_QOS), qos->durability_service.history.depth); + CHECK_RET_OK(ret); + char *durability_service; + int32_t ms,mi,mspi; + ms = qos->durability_service.resource_limits.max_samples; + mi = qos->durability_service.resource_limits.max_instances; + mspi = qos->durability_service.resource_limits.max_samples_per_instance; + char *ms_f,*mi_f,*mspi_f; + (void) ddsrt_asprintf(&ms_f,(ms<0? QOS_RESOURCE_LIMITS_MS(QOS_LENGTH_UNLIMITED): QOS_RESOURCE_LIMITS_MS("%d")), ms); + (void) ddsrt_asprintf(&mi_f,(mi<0? QOS_RESOURCE_LIMITS_MI(QOS_LENGTH_UNLIMITED): QOS_RESOURCE_LIMITS_MI("%d")), mi); + (void) ddsrt_asprintf(&mspi_f,(mspi<0? QOS_RESOURCE_LIMITS_MSPI(QOS_LENGTH_UNLIMITED): QOS_RESOURCE_LIMITS_MSPI("%d")), mspi); + ret = ddsrt_asprintf(&durability_service, QOS_POLICY_DURABILITY_SERVICE_FMT, service_cleanup_delay, history, ms_f, mi_f, mspi_f); + ddsrt_free(ms_f);ddsrt_free(mi_f);ddsrt_free(mspi_f); + ddsrt_free(service_cleanup_delay); + ddsrt_free(history); + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT "%s\n" QOS_FORMAT "%s", sysdef_qos, durability_service); + ddsrt_free(tmp); + ddsrt_free(durability_service); + *validate_mask |= DDSI_QP_DURABILITY_SERVICE; + } + if ((ignore_ent || (kind == DDS_PARTICIPANT_QOS || kind == DDS_PUBLISHER_QOS || kind == DDS_SUBSCRIBER_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_ADLINK_ENTITY_FACTORY) + { + char *entity_factory; + if (qos->entity_factory.autoenable_created_entities == 0) + ret = ddsrt_asprintf(&entity_factory, "%s", QOS_POLICY_ENTITYFACTORY_FMT(false)); + else + ret = ddsrt_asprintf(&entity_factory, "%s", QOS_POLICY_ENTITYFACTORY_FMT(true)); + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT "%s\n" QOS_FORMAT "%s", sysdef_qos, entity_factory); + ddsrt_free(tmp); + ddsrt_free(entity_factory); + *validate_mask |= DDSI_QP_ADLINK_ENTITY_FACTORY; + } + if ((ignore_ent || (kind == DDS_PUBLISHER_QOS || kind == DDS_SUBSCRIBER_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_GROUP_DATA) + { + if (qos->group_data.length > 0) + { + char *data = ddsrt_strdup(""); + for (uint32_t i = 0; i < qos->group_data.length; i++) { + char *tmp = data; + ret = ddsrt_asprintf(&data, "%s%c", data, qos->group_data.value[i]); + ddsrt_free(tmp); + CHECK_RET_OK(ret); + } + char *group_data; + ret = ddsrt_asprintf(&group_data, QOS_POLICY_GOUPDATA_FMT, data); + ddsrt_free(data); + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT "%s\n" QOS_FORMAT "%s", sysdef_qos, group_data); + ddsrt_free(tmp); + ddsrt_free(group_data); + *validate_mask |= DDSI_QP_GROUP_DATA; + } + } + if ((ignore_ent || (kind == DDS_TOPIC_QOS || kind == DDS_READER_QOS || kind == DDS_WRITER_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_HISTORY) + { + char *history; + if (qos->history.kind == DDS_HISTORY_KEEP_LAST) + ret = ddsrt_asprintf(&history, QOS_POLICY_HISTORY_FMT(KEEP_LAST_HISTORY_QOS), qos->history.depth); + else + ret = ddsrt_asprintf(&history, QOS_POLICY_HISTORY_FMT(KEEP_ALL_HISTORY_QOS), qos->history.depth); + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT "%s\n" QOS_FORMAT "%s", sysdef_qos, history); + ddsrt_free(tmp); + ddsrt_free(history); + *validate_mask |= DDSI_QP_HISTORY; + } + if ((ignore_ent || (kind == DDS_TOPIC_QOS || kind == DDS_WRITER_QOS || kind == DDS_READER_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_LATENCY_BUDGET) + { + char *latency_budget; + if (qos->latency_budget.duration == DDS_INFINITY) + { + if (conf->latency_budget_unit == sec) + ret = ddsrt_asprintf(&latency_budget, QOS_POLICY_LATENCYBUDGET_FMT(QOS_DURATION_FMT_STR(sec)), + QOS_DURATION_INFINITY_SEC); + else + ret = ddsrt_asprintf(&latency_budget, QOS_POLICY_LATENCYBUDGET_FMT(QOS_DURATION_FMT_STR(nanosec)), + QOS_DURATION_INFINITY_NSEC); + } else { + if (conf->latency_budget_unit == sec) + ret = ddsrt_asprintf(&latency_budget, QOS_POLICY_LATENCYBUDGET_FMT(QOS_DURATION_FMT(sec)), + static_cast(qos->latency_budget.duration/DDS_NSECS_IN_SEC)); + else + ret = ddsrt_asprintf(&latency_budget, QOS_POLICY_LATENCYBUDGET_FMT(QOS_DURATION_FMT(nanosec)), + static_cast(qos->latency_budget.duration)); + } + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT "%s\n" QOS_FORMAT "%s", sysdef_qos, latency_budget); + ddsrt_free(tmp); + ddsrt_free(latency_budget); + *validate_mask |= DDSI_QP_LATENCY_BUDGET; + } + if ((ignore_ent || (kind == DDS_WRITER_QOS || kind == DDS_TOPIC_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_LIFESPAN) + { + char *lifespan; + if (qos->lifespan.duration == DDS_INFINITY) + { + if (conf->lifespan_unit == sec) + ret = ddsrt_asprintf(&lifespan, QOS_POLICY_LIFESPAN_FMT(QOS_DURATION_FMT_STR(sec)), + QOS_DURATION_INFINITY_SEC); + else + ret = ddsrt_asprintf(&lifespan, QOS_POLICY_LIFESPAN_FMT(QOS_DURATION_FMT_STR(nanosec)), + QOS_DURATION_INFINITY_NSEC); + } else { + if (conf->lifespan_unit == sec) + ret = ddsrt_asprintf(&lifespan, QOS_POLICY_LIFESPAN_FMT(QOS_DURATION_FMT(sec)), + static_cast(qos->lifespan.duration/DDS_NSECS_IN_SEC)); + else + ret = ddsrt_asprintf(&lifespan, QOS_POLICY_LIFESPAN_FMT(QOS_DURATION_FMT(nanosec)), + static_cast(qos->lifespan.duration)); + } + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT "%s\n" QOS_FORMAT "%s", sysdef_qos, lifespan); + ddsrt_free(tmp); + ddsrt_free(lifespan); + *validate_mask |= DDSI_QP_LIFESPAN; + } + if ((ignore_ent || (kind != DDS_PUBLISHER_QOS && kind != DDS_SUBSCRIBER_QOS && kind != DDS_PARTICIPANT_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_LIVELINESS) + { + char *duration; + if (qos->liveliness.lease_duration == DDS_INFINITY) + { + if (conf->liveliness_unit == sec) + ret = ddsrt_asprintf(&duration, QOS_LIVELINESS_DURATION(QOS_DURATION_FMT_STR(sec)), + QOS_DURATION_INFINITY_SEC); + else + ret = ddsrt_asprintf(&duration, QOS_LIVELINESS_DURATION(QOS_DURATION_FMT_STR(nanosec)), + QOS_DURATION_INFINITY_NSEC); + } else { + if (conf->liveliness_unit == sec) + ret = ddsrt_asprintf(&duration, QOS_LIVELINESS_DURATION(QOS_DURATION_FMT(sec)), + static_cast(qos->liveliness.lease_duration/DDS_NSECS_IN_SEC)); + else + ret = ddsrt_asprintf(&duration, QOS_LIVELINESS_DURATION(QOS_DURATION_FMT(nanosec)), + static_cast(qos->liveliness.lease_duration)); + } + CHECK_RET_OK(ret); + char *liveliness_kind; + if (qos->liveliness.kind == DDS_LIVELINESS_AUTOMATIC) + ret = ddsrt_asprintf(&liveliness_kind, "%s", QOS_LIVELINESS_KIND(AUTOMATIC_LIVELINESS_QOS)); + else if (qos->liveliness.kind == DDS_LIVELINESS_MANUAL_BY_PARTICIPANT) + ret = ddsrt_asprintf(&liveliness_kind, "%s", QOS_LIVELINESS_KIND(MANUAL_BY_PARTICIPANT_LIVELINESS_QOS)); + else + ret = ddsrt_asprintf(&liveliness_kind, "%s", QOS_LIVELINESS_KIND(MANUAL_BY_TOPIC_LIVELINESS_QOS)); + CHECK_RET_OK(ret); + char *liveliness; + ret = ddsrt_asprintf(&liveliness, QOS_POLICY_LIVELINESS_FMT, duration, liveliness_kind); + ddsrt_free(duration); + ddsrt_free(liveliness_kind); + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT "%s\n" QOS_FORMAT "%s", sysdef_qos, liveliness); + ddsrt_free(tmp); + ddsrt_free(liveliness); + *validate_mask |= DDSI_QP_LIVELINESS; + } + if ((ignore_ent || (kind != DDS_PUBLISHER_QOS && kind != DDS_SUBSCRIBER_QOS && kind != DDS_PARTICIPANT_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_OWNERSHIP) + { + char *ownership; + if (qos->ownership.kind == DDS_OWNERSHIP_SHARED) + ret = ddsrt_asprintf(&ownership, "%s", QOS_POLICY_OWNERSHIP_FMT(SHARED_OWNERSHIP_QOS)); + else + ret = ddsrt_asprintf(&ownership, "%s", QOS_POLICY_OWNERSHIP_FMT(EXCLUSIVE_OWNERSHIP_QOS)); + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT "%s\n" QOS_FORMAT "%s", sysdef_qos, ownership); + ddsrt_free(tmp); + ddsrt_free(ownership); + *validate_mask |= DDSI_QP_OWNERSHIP; + } + if ((ignore_ent || (kind == DDS_WRITER_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_OWNERSHIP_STRENGTH) + { + char *ownership_strength; + ret = ddsrt_asprintf(&ownership_strength, QOS_POLICY_OWNERSHIPSTRENGTH_FMT, qos->ownership_strength.value); + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT "%s\n" QOS_FORMAT "%s", sysdef_qos, ownership_strength); + ddsrt_free(tmp); + ddsrt_free(ownership_strength); + *validate_mask |= DDSI_QP_OWNERSHIP_STRENGTH; + } + if ((ignore_ent || (kind == DDS_PUBLISHER_QOS || kind == DDS_SUBSCRIBER_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_PARTITION) + { + if (qos->partition.n > 0) + { + char *part_elems = ddsrt_strdup(""); + for (uint32_t i = 0; i < qos->partition.n; i++) { + char *tmp = part_elems; + ret = ddsrt_asprintf(&part_elems, "%s" QOS_PARTITION_ELEMENT, part_elems, qos->partition.strs[i]); + CHECK_RET_OK(ret); + ddsrt_free(tmp); + } + CHECK_RET_OK(ret); + char *partition; + ret = ddsrt_asprintf(&partition, QOS_POLIC_PARTITION_FMT, part_elems); + ddsrt_free(part_elems); + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT "%s\n" QOS_FORMAT "%s", sysdef_qos, partition); + ddsrt_free(tmp); + ddsrt_free(partition); + *validate_mask |= DDSI_QP_PARTITION; + } + } + if ((ignore_ent || (kind == DDS_PUBLISHER_QOS || kind == DDS_SUBSCRIBER_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_PRESENTATION) + { + char *access_scope_kind; + if (qos->presentation.access_scope == DDS_PRESENTATION_INSTANCE) + ret = ddsrt_asprintf(&access_scope_kind, QOS_ACCESS_SCOPE_KIND(INSTANCE_PRESENTATION_QOS)); + else if (qos->presentation.access_scope == DDS_PRESENTATION_TOPIC) + ret = ddsrt_asprintf(&access_scope_kind, QOS_ACCESS_SCOPE_KIND(TOPIC_PRESENTATION_QOS)); + else + ret = ddsrt_asprintf(&access_scope_kind, QOS_ACCESS_SCOPE_KIND(GROUP_PRESENTATION_QOS)); + CHECK_RET_OK(ret); + char *coherent_access; + if (qos->presentation.coherent_access) + ret = ddsrt_asprintf(&coherent_access, "%s", QOS_COHERENT_ACCESS(true)); + else + ret = ddsrt_asprintf(&coherent_access, "%s", QOS_COHERENT_ACCESS(false)); + CHECK_RET_OK(ret); + char *ordered_access; + if (qos->presentation.ordered_access) + ret = ddsrt_asprintf(&ordered_access, "%s", QOS_ORDERED_ACCESS(true)); + else + ret = ddsrt_asprintf(&ordered_access, "%s", QOS_ORDERED_ACCESS(false)); + CHECK_RET_OK(ret); + char *presentation; + ret = ddsrt_asprintf(&presentation, QOS_POLICY_PRESENTATION_FMT, access_scope_kind, coherent_access, ordered_access); + ddsrt_free(access_scope_kind); + ddsrt_free(coherent_access); + ddsrt_free(ordered_access); + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT "%s\n" QOS_FORMAT "%s", sysdef_qos, presentation); + ddsrt_free(tmp); + ddsrt_free(presentation); + *validate_mask |= DDSI_QP_PRESENTATION; + } + if ((ignore_ent || (kind == DDS_TOPIC_QOS || kind == DDS_READER_QOS || kind == DDS_WRITER_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_RELIABILITY) + { + char *max_blocking_time; + if (qos->reliability.max_blocking_time == DDS_INFINITY) + { + if (conf->reliability_unit == sec) + ret = ddsrt_asprintf(&max_blocking_time, QOS_RELIABILITY_DURATION(QOS_DURATION_FMT_STR(sec)), + QOS_DURATION_INFINITY_SEC); + else + ret = ddsrt_asprintf(&max_blocking_time, QOS_RELIABILITY_DURATION(QOS_DURATION_FMT_STR(nanosec)), + QOS_DURATION_INFINITY_NSEC); + } else { + if (conf->reliability_unit == sec) + ret = ddsrt_asprintf(&max_blocking_time, QOS_RELIABILITY_DURATION(QOS_DURATION_FMT(sec)), + static_cast(qos->reliability.max_blocking_time/DDS_NSECS_IN_SEC)); + else + ret = ddsrt_asprintf(&max_blocking_time, QOS_RELIABILITY_DURATION(QOS_DURATION_FMT(nanosec)), + static_cast(qos->reliability.max_blocking_time)); + } + CHECK_RET_OK(ret); + char *reliability_kind; + if (qos->reliability.kind == DDS_RELIABILITY_BEST_EFFORT) + ret = ddsrt_asprintf(&reliability_kind, "%s", QOS_RELIABILITY_KIND(BEST_EFFORT_RELIABILITY_QOS)); + else + ret = ddsrt_asprintf(&reliability_kind, "%s", QOS_RELIABILITY_KIND(RELIABLE_RELIABILITY_QOS)); + CHECK_RET_OK(ret); + char *reliability; + ret = ddsrt_asprintf(&reliability, QOS_POLICY_RELIABILITY_FMT, max_blocking_time, reliability_kind); + ddsrt_free(max_blocking_time); + ddsrt_free(reliability_kind); + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT "%s\n" QOS_FORMAT "%s", sysdef_qos, reliability); + ddsrt_free(tmp); + ddsrt_free(reliability); + *validate_mask |= DDSI_QP_RELIABILITY; + } + if ((ignore_ent || (kind == DDS_TOPIC_QOS || kind == DDS_READER_QOS || kind == DDS_WRITER_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_RESOURCE_LIMITS) + { + int32_t ms,mi,mspi; + ms = qos->resource_limits.max_samples; + mi = qos->resource_limits.max_instances; + mspi = qos->resource_limits.max_samples_per_instance; + char *ms_f,*mi_f,*mspi_f; + (void) ddsrt_asprintf(&ms_f,(ms<0? QOS_RESOURCE_LIMITS_MS(QOS_LENGTH_UNLIMITED): QOS_RESOURCE_LIMITS_MS("%d")), ms); + (void) ddsrt_asprintf(&mi_f,(mi<0? QOS_RESOURCE_LIMITS_MI(QOS_LENGTH_UNLIMITED): QOS_RESOURCE_LIMITS_MI("%d")), mi); + (void) ddsrt_asprintf(&mspi_f,(mspi<0? QOS_RESOURCE_LIMITS_MSPI(QOS_LENGTH_UNLIMITED): QOS_RESOURCE_LIMITS_MSPI("%d")), mspi); + char *resource_limits; + ret = ddsrt_asprintf(&resource_limits, QOS_POLICY_RESOURCE_LIMITS_FMT, ms_f, mi_f, mspi_f); + ddsrt_free(ms_f);ddsrt_free(mi_f);ddsrt_free(mspi_f); + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT "%s\n" QOS_FORMAT "%s", sysdef_qos, resource_limits); + ddsrt_free(tmp); + ddsrt_free(resource_limits); + *validate_mask |= DDSI_QP_RESOURCE_LIMITS; + } + if ((ignore_ent || (kind == DDS_READER_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_TIME_BASED_FILTER) + { + char *time_based_filter; + if (qos->time_based_filter.minimum_separation == DDS_INFINITY) + { + if (conf->time_based_filter_unit == sec) + ret = ddsrt_asprintf(&time_based_filter, QOS_POLICY_TIMEBASEDFILTER_FMT(QOS_DURATION_FMT_STR(sec)), + QOS_DURATION_INFINITY_SEC); + else + ret = ddsrt_asprintf(&time_based_filter, QOS_POLICY_TIMEBASEDFILTER_FMT(QOS_DURATION_FMT_STR(nanosec)), + QOS_DURATION_INFINITY_NSEC); + } else { + if (conf->time_based_filter_unit == sec) + ret = ddsrt_asprintf(&time_based_filter, QOS_POLICY_TIMEBASEDFILTER_FMT(QOS_DURATION_FMT(sec)), + static_cast(qos->time_based_filter.minimum_separation/DDS_NSECS_IN_SEC)); + else + ret = ddsrt_asprintf(&time_based_filter, QOS_POLICY_TIMEBASEDFILTER_FMT(QOS_DURATION_FMT(nanosec)), + static_cast(qos->time_based_filter.minimum_separation)); + } + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT "%s\n" QOS_FORMAT "%s", sysdef_qos, time_based_filter); + ddsrt_free(tmp); + ddsrt_free(time_based_filter); + *validate_mask |= DDSI_QP_TIME_BASED_FILTER; + } + if ((ignore_ent || (kind == DDS_TOPIC_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_TOPIC_DATA) + { + if (qos->topic_data.length > 0) + { + char *data = ddsrt_strdup(""); + for (uint32_t i = 0; i < qos->topic_data.length; i++) { + char *tmp = data; + ret = ddsrt_asprintf(&data, "%s%c", data, qos->topic_data.value[i]); + ddsrt_free(tmp); + CHECK_RET_OK(ret); + } + char *topic_data; + ret = ddsrt_asprintf(&topic_data, QOS_POLICY_TOPICDATA_FMT, data); + ddsrt_free(data); + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT "%s\n" QOS_FORMAT "%s", sysdef_qos, topic_data); + ddsrt_free(tmp); + ddsrt_free(topic_data); + *validate_mask |= DDSI_QP_TOPIC_DATA; + } + } + if ((ignore_ent || (kind == DDS_TOPIC_QOS || kind == DDS_WRITER_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_TRANSPORT_PRIORITY) + { + char *priority; + ret = ddsrt_asprintf(&priority, QOS_POLICY_TRANSPORTPRIORITY_FMT, qos->transport_priority.value); + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT "%s\n" QOS_FORMAT "%s", sysdef_qos, priority); + ddsrt_free(tmp); + ddsrt_free(priority); + *validate_mask |= DDSI_QP_TRANSPORT_PRIORITY; + } + if ((ignore_ent || (kind == DDS_PARTICIPANT_QOS || kind == DDS_READER_QOS || kind == DDS_WRITER_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_USER_DATA) + { + if (qos->user_data.length > 0) + { + char *data = ddsrt_strdup(""); + for (uint32_t i = 0; i < qos->user_data.length; i++) { + char *tmp = data; + ret = ddsrt_asprintf(&data, "%s%c", data, qos->user_data.value[i]); + ddsrt_free(tmp); + CHECK_RET_OK(ret); + } + char *user_data; + ret = ddsrt_asprintf(&user_data, QOS_POLICY_USERDATA_FMT, data); + ddsrt_free(data); + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT "%s\n" QOS_FORMAT "%s", sysdef_qos, user_data); + ddsrt_free(tmp); + ddsrt_free(user_data); + *validate_mask |= DDSI_QP_USER_DATA; + } + } + if ((ignore_ent || (kind == DDS_READER_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_ADLINK_READER_DATA_LIFECYCLE) + { + char *nowriter_delay; + if (qos->reader_data_lifecycle.autopurge_nowriter_samples_delay == DDS_INFINITY) + { + if (conf->reader_data_lifecycle_nowriter_unit == sec) + ret = ddsrt_asprintf(&nowriter_delay, QOS_NOWRITER_DELAY(QOS_DURATION_FMT_STR(sec)), + QOS_DURATION_INFINITY_SEC); + else + ret = ddsrt_asprintf(&nowriter_delay, QOS_NOWRITER_DELAY(QOS_DURATION_FMT_STR(nanosec)), + QOS_DURATION_INFINITY_NSEC); + } else { + if (conf->reader_data_lifecycle_nowriter_unit == sec) + ret = ddsrt_asprintf(&nowriter_delay, QOS_NOWRITER_DELAY(QOS_DURATION_FMT(sec)), + static_cast(qos->reader_data_lifecycle.autopurge_nowriter_samples_delay/DDS_NSECS_IN_SEC)); + else + ret = ddsrt_asprintf(&nowriter_delay, QOS_NOWRITER_DELAY(QOS_DURATION_FMT(nanosec)), + static_cast(qos->reader_data_lifecycle.autopurge_nowriter_samples_delay)); + } + CHECK_RET_OK(ret); + char *disposed_delay; + if (qos->reader_data_lifecycle.autopurge_disposed_samples_delay == DDS_INFINITY) + { + if (conf->reader_data_lifecycle_disposed_unit == sec) + ret = ddsrt_asprintf(&disposed_delay, QOS_DISPOSED_DELAY(QOS_DURATION_FMT_STR(sec)), + QOS_DURATION_INFINITY_SEC); + else + ret = ddsrt_asprintf(&disposed_delay, QOS_DISPOSED_DELAY(QOS_DURATION_FMT_STR(nanosec)), + QOS_DURATION_INFINITY_NSEC); + } else { + if (conf->reader_data_lifecycle_disposed_unit == sec) + ret = ddsrt_asprintf(&disposed_delay, QOS_DISPOSED_DELAY(QOS_DURATION_FMT(sec)), + static_cast(qos->reader_data_lifecycle.autopurge_disposed_samples_delay/DDS_NSECS_IN_SEC)); + else + ret = ddsrt_asprintf(&disposed_delay, QOS_DISPOSED_DELAY(QOS_DURATION_FMT(nanosec)), + static_cast(qos->reader_data_lifecycle.autopurge_disposed_samples_delay)); + } + CHECK_RET_OK(ret); + char *reader_data_lifecycle; + ret = ddsrt_asprintf(&reader_data_lifecycle, QOS_POLICY_READERDATALIFECYCLE_FMT, nowriter_delay, disposed_delay); + ddsrt_free(nowriter_delay); + ddsrt_free(disposed_delay); + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT "%s\n" QOS_FORMAT "%s", sysdef_qos, reader_data_lifecycle); + ddsrt_free(tmp); + ddsrt_free(reader_data_lifecycle); + *validate_mask |= DDSI_QP_ADLINK_READER_DATA_LIFECYCLE; + } + if ((ignore_ent || (kind == DDS_WRITER_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_ADLINK_WRITER_DATA_LIFECYCLE) + { + char *writer_data_lifecycle; + if (qos->writer_data_lifecycle.autodispose_unregistered_instances) + ret = ddsrt_asprintf(&writer_data_lifecycle, "%s", QOS_POLICY_WRITERDATA_LIFECYCLE_FMT(true)); + else + ret = ddsrt_asprintf(&writer_data_lifecycle, "%s", QOS_POLICY_WRITERDATA_LIFECYCLE_FMT(false)); + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT "%s\n" QOS_FORMAT "%s", sysdef_qos, writer_data_lifecycle); + ddsrt_free(tmp); + ddsrt_free(writer_data_lifecycle); + *validate_mask |= DDSI_QP_ADLINK_WRITER_DATA_LIFECYCLE; + } + + *out = sysdef_qos; + fail: + return ret; + } + +#undef QOS_FORMAT + + static dds_return_t + get_single_configuration(dds_qos_t *qos, sysdef_qos_conf_t *conf, dds_qos_kind_t kind, char **out_conf, uint64_t *validate_mask) + { + dds_return_t ret = DDS_RETCODE_OK; + char *qos_conf = NULL; + ret = qos_to_conf(qos, conf, &qos_conf, kind, validate_mask, false); + const char *def; + if (ret >= 0) + { + switch(kind) + { + case DDS_PARTICIPANT_QOS: + def = DEF(LIB(lib1,PRO(pro00,ENT("%s",domain_participant)))); + break; + case DDS_PUBLISHER_QOS: + def = DEF(LIB(lib1,PRO(pro00,ENT("%s",publisher)))); + break; + case DDS_SUBSCRIBER_QOS: + def = DEF(LIB(lib1,PRO(pro00,ENT("%s",subscriber)))); + break; + case DDS_TOPIC_QOS: + def = DEF(LIB(lib1,PRO(pro00,ENT("%s",topic)))); + break; + case DDS_READER_QOS: + def = DEF(LIB(lib1,PRO(pro00,ENT("%s",datareader)))); + break; + case DDS_WRITER_QOS: + def = DEF(LIB(lib1,PRO(pro00,ENT("%s",datawriter)))); + break; + default: + ddsrt_free(qos_conf); + return DDS_RETCODE_ERROR; + } + ret = ddsrt_asprintf(out_conf, def, qos_conf); + ddsrt_free(qos_conf); + } + + return ret; + } + + + void doTest(dds_qos_kind_t kind) + { + dds::domain::DomainParticipant dp(org::eclipse::cyclonedds::domain::default_id()); + dds::pub::Publisher pub(dp); + dds::sub::Subscriber sub(dp); + dds_qos_t *qos = NULL; + dds::core::ByteSeq bs; + dds::core::StringSeq pList; + dds_return_t result; + sysdef_qos_conf_t dur_conf = {sec,sec,sec,sec,sec,sec,sec,sec,sec}; + char *full_configuration = NULL; + uint64_t validate_mask = 0; + + for (unsigned char c = 'a'; c <= 'd'; c++) bs.push_back(c); + pList.push_back("abcd"); + pList.push_back("efgh"); + pList.push_back("ijkl"); + switch(kind) + { + case DDS_PARTICIPANT_QOS: + pQos = dds::domain::DomainParticipant::default_participant_qos() + << dds::core::policy::UserData(bs) + << dds::core::policy::EntityFactory::AutoEnable(); + qos = pQos.delegate().ddsc_qos(); + break; + case DDS_PUBLISHER_QOS: + pubQos = dp.default_publisher_qos() + << dds::core::policy::GroupData(bs) + << dds::core::policy::Partition(pList) + << dds::core::policy::Presentation::InstanceAccessScope(false, false) + << dds::core::policy::EntityFactory::AutoEnable(); + qos = pubQos.delegate().ddsc_qos(); + break; + case DDS_SUBSCRIBER_QOS: + subQos = dp.default_subscriber_qos() + << dds::core::policy::GroupData(bs) + << dds::core::policy::Partition(pList) + << dds::core::policy::Presentation::InstanceAccessScope(false, false) + << dds::core::policy::EntityFactory::AutoEnable(); + qos = subQos.delegate().ddsc_qos(); + break; + case DDS_TOPIC_QOS: + tQos = dp.default_topic_qos() + << dds::core::policy::TopicData(bs) + << dds::core::policy::Durability::Volatile() + << dds::core::policy::Deadline(dds::core::Duration(1,0)) + << dds::core::policy::LatencyBudget(dds::core::Duration(1,0)) + << dds::core::policy::Ownership::Exclusive() + << dds::core::policy::Liveliness::Automatic(dds::core::Duration::infinite()) + << dds::core::policy::Reliability::Reliable(dds::core::Duration(1, 0)) + << dds::core::policy::TransportPriority(1000) + << dds::core::policy::Lifespan(dds::core::Duration(1, 0)) + << dds::core::policy::DestinationOrder::SourceTimestamp() + << dds::core::policy::History::KeepLast(1) + << dds::core::policy::ResourceLimits(1, 1, 1) + << dds::core::policy::DurabilityService(dds::core::Duration(1, 0), dds::core::policy::HistoryKind::KEEP_ALL, -1, 1, 1, 1); + qos = tQos.delegate().ddsc_qos(); + break; + case DDS_READER_QOS: + rQos = sub.default_datareader_qos() + << dds::core::policy::UserData(bs) + << dds::core::policy::Durability::Volatile() + << dds::core::policy::Deadline(dds::core::Duration(1,0)) + << dds::core::policy::LatencyBudget(dds::core::Duration(1,0)) + << dds::core::policy::Ownership::Exclusive() + << dds::core::policy::Liveliness::Automatic(dds::core::Duration::infinite()) + << dds::core::policy::Reliability::Reliable(dds::core::Duration(1, 0)) + << dds::core::policy::DestinationOrder::SourceTimestamp() + << dds::core::policy::History::KeepLast(1) + << dds::core::policy::ResourceLimits(1, 1, 1) + << dds::core::policy::TimeBasedFilter(dds::core::Duration(1, 0)) + << dds::core::policy::ReaderDataLifecycle(dds::core::Duration(1,0), dds::core::Duration(1,0)); + qos = rQos.delegate().ddsc_qos(); + break; + case DDS_WRITER_QOS: + wQos = pub.default_datawriter_qos() + << dds::core::policy::UserData(bs) + << dds::core::policy::Durability::Volatile() + << dds::core::policy::Deadline(dds::core::Duration(1,0)) + << dds::core::policy::LatencyBudget(dds::core::Duration(1,0)) + << dds::core::policy::Ownership::Exclusive() + << dds::core::policy::OwnershipStrength(100) + << dds::core::policy::Liveliness::Automatic(dds::core::Duration::infinite()) + << dds::core::policy::Reliability::Reliable(dds::core::Duration(1, 0)) + << dds::core::policy::DestinationOrder::SourceTimestamp() + << dds::core::policy::History::KeepLast(1) + << dds::core::policy::ResourceLimits(1, 1, 1) + << dds::core::policy::WriterDataLifecycle::AutoDisposeUnregisteredInstances(); + qos = wQos.delegate().ddsc_qos(); + break; + default: + assert(0); + break; + } + result = get_single_configuration(qos, &dur_conf, kind, &full_configuration, &validate_mask); + ASSERT_TRUE(result >= 0); + dds::core::QosProvider qp(full_configuration); + switch(kind) + { + case DDS_PARTICIPANT_QOS: + { + dds::domain::qos::DomainParticipantQos qpQos = qp.participant_qos("lib1::pro00"); + ASSERT_TRUE(pQos == qpQos); + break; + } + case DDS_PUBLISHER_QOS: + { + dds::pub::qos::PublisherQos qpQos = qp.publisher_qos("lib1::pro00"); + ASSERT_TRUE(pubQos == qpQos); + break; + } + case DDS_SUBSCRIBER_QOS: + { + dds::sub::qos::SubscriberQos qpQos = qp.subscriber_qos("lib1::pro00"); + ASSERT_TRUE(subQos == qpQos); + break; + } + case DDS_TOPIC_QOS: + { + dds::topic::qos::TopicQos qpQos = qp.topic_qos("lib1::pro00"); + ASSERT_TRUE(tQos == qpQos); + break; + } + case DDS_READER_QOS: + { + dds::sub::qos::DataReaderQos qpQos = qp.datareader_qos("lib1::pro00"); + ASSERT_TRUE(rQos == qpQos); + break; + } + case DDS_WRITER_QOS: + { + dds::pub::qos::DataWriterQos qpQos = qp.datawriter_qos("lib1::pro00"); + ASSERT_TRUE(wQos == qpQos); + break; + } + } + dds_delete_qos(qos); + ddsrt_free(full_configuration); + } + QosProvider(/*dds_qos_kind_t kind*/) + { + } +}; + +/** + * Tests + */ + +TEST_F(QosProvider, participantQos) +{ + this->doTest(DDS_PARTICIPANT_QOS); +} + +TEST_F(QosProvider, publisherQos) +{ + this->doTest(DDS_PUBLISHER_QOS); +} + +TEST_F(QosProvider, subscriberQos) +{ + this->doTest(DDS_SUBSCRIBER_QOS); +} + +TEST_F(QosProvider, dataWriterQos) +{ + this->doTest(DDS_WRITER_QOS); +} + +TEST_F(QosProvider, dataReaderQos) +{ + this->doTest(DDS_READER_QOS); +} + +TEST_F(QosProvider, topicQos) +{ + this->doTest(DDS_TOPIC_QOS); +} +