diff --git a/include/fastrtps/types/MemberDescriptor.h b/include/fastrtps/types/MemberDescriptor.h index f7cdfcb4a1f..5a52948a4c7 100644 --- a/include/fastrtps/types/MemberDescriptor.h +++ b/include/fastrtps/types/MemberDescriptor.h @@ -18,9 +18,9 @@ #include #include -namespace eprosima{ -namespace fastrtps{ -namespace types{ +namespace eprosima { +namespace fastrtps { +namespace types { class DynamicType; class AnnotationDescriptor; @@ -28,6 +28,7 @@ class AnnotationDescriptor; class MemberDescriptor { protected: + std::string name_; // Name of the member MemberId id_; // MemberId, it should be filled automatically when the member is added. DynamicType_ptr type_; // Member's Type. @@ -43,11 +44,17 @@ class MemberDescriptor friend class DynamicTypeMember; friend class TypeObjectFactory; - bool is_default_value_consistent(const std::string& sDefaultValue) const; + bool is_default_value_consistent( + const std::string& sDefaultValue) const; + + bool is_type_name_consistent( + const std::string& sName) const; - bool is_type_name_consistent(const std::string& sName) const; + void copy_annotations_from_type( + const DynamicType_ptr& type); public: + RTPS_DllAPI MemberDescriptor(); RTPS_DllAPI MemberDescriptor( @@ -57,37 +64,41 @@ class MemberDescriptor RTPS_DllAPI MemberDescriptor( MemberId id, const std::string& name, - DynamicType_ptr type_); + DynamicType_ptr type); RTPS_DllAPI MemberDescriptor( MemberId id, const std::string& name, - DynamicType_ptr type_, + DynamicType_ptr type, const std::string& defaultValue); RTPS_DllAPI MemberDescriptor( MemberId id, const std::string& name, - DynamicType_ptr type_, + DynamicType_ptr type, const std::string& defaultValue, const std::vector& unionLabels, bool isDefaultLabel); - RTPS_DllAPI MemberDescriptor(const MemberDescriptor* descriptor); + RTPS_DllAPI MemberDescriptor( + const MemberDescriptor* descriptor); RTPS_DllAPI ~MemberDescriptor(); - bool check_union_labels(const std::vector& labels) const; + bool check_union_labels( + const std::vector& labels) const; - RTPS_DllAPI ReturnCode_t copy_from(const MemberDescriptor* other); + RTPS_DllAPI ReturnCode_t copy_from( + const MemberDescriptor* other); - RTPS_DllAPI bool equals(const MemberDescriptor* other) const; + RTPS_DllAPI bool equals( + const MemberDescriptor* other) const; RTPS_DllAPI TypeKind get_kind() const; RTPS_DllAPI MemberId get_id() const; - RTPS_DllAPI uint32_t get_index() const; + RTPS_DllAPI uint32_t get_index() const; RTPS_DllAPI std::string get_name() const; @@ -105,39 +116,49 @@ class MemberDescriptor RTPS_DllAPI bool is_default_union_value() const; - RTPS_DllAPI bool is_consistent(TypeKind parentKind) const; + RTPS_DllAPI bool is_consistent( + TypeKind parentKind) const; - RTPS_DllAPI void add_union_case_index(uint64_t value); + RTPS_DllAPI void add_union_case_index( + uint64_t value); - RTPS_DllAPI void set_id(MemberId id); + RTPS_DllAPI void set_id( + MemberId id); - RTPS_DllAPI void set_index(uint32_t index); + RTPS_DllAPI void set_index( + uint32_t index); - RTPS_DllAPI void set_name(const std::string& name); + RTPS_DllAPI void set_name( + const std::string& name); - RTPS_DllAPI void set_type(DynamicType_ptr type); + RTPS_DllAPI void set_type( + DynamicType_ptr type); RTPS_DllAPI DynamicType_ptr get_type() const { return type_; } - RTPS_DllAPI void set_default_union_value(bool bDefault); + RTPS_DllAPI void set_default_union_value( + bool bDefault); - RTPS_DllAPI void set_default_value(const std::string& value) + RTPS_DllAPI void set_default_value( + const std::string& value) { default_value_ = value; } // Annotations - ReturnCode_t apply_annotation(AnnotationDescriptor& descriptor); + ReturnCode_t apply_annotation( + AnnotationDescriptor& descriptor); ReturnCode_t apply_annotation( const std::string& annotation_name, const std::string& key, const std::string& value); - AnnotationDescriptor* get_annotation(const std::string& name) const; + AnnotationDescriptor* get_annotation( + const std::string& name) const; // Annotations application RTPS_DllAPI bool annotation_is_optional() const; @@ -168,23 +189,31 @@ class MemberDescriptor RTPS_DllAPI uint16_t annotation_get_bit_bound() const; // Annotations setters - RTPS_DllAPI void annotation_set_optional(bool optional); + RTPS_DllAPI void annotation_set_optional( + bool optional); - RTPS_DllAPI void annotation_set_key(bool key); + RTPS_DllAPI void annotation_set_key( + bool key); - RTPS_DllAPI void annotation_set_must_understand(bool must_understand); + RTPS_DllAPI void annotation_set_must_understand( + bool must_understand); - RTPS_DllAPI void annotation_set_non_serialized(bool non_serialized); + RTPS_DllAPI void annotation_set_non_serialized( + bool non_serialized); - RTPS_DllAPI void annotation_set_value(const std::string& value); + RTPS_DllAPI void annotation_set_value( + const std::string& value); - RTPS_DllAPI void annotation_set_default(const std::string& default_value); + RTPS_DllAPI void annotation_set_default( + const std::string& default_value); RTPS_DllAPI void annotation_set_default_literal(); - RTPS_DllAPI void annotation_set_position(uint16_t position); + RTPS_DllAPI void annotation_set_position( + uint16_t position); - RTPS_DllAPI void annotation_set_bit_bound(uint16_t bit_bound); + RTPS_DllAPI void annotation_set_bit_bound( + uint16_t bit_bound); }; } // namespace types diff --git a/include/fastrtps/xmlparser/XMLProfileManager.h b/include/fastrtps/xmlparser/XMLProfileManager.h index 6d670f239c8..8fabe95d983 100644 --- a/include/fastrtps/xmlparser/XMLProfileManager.h +++ b/include/fastrtps/xmlparser/XMLProfileManager.h @@ -246,24 +246,14 @@ class XMLProfileManager * XMLProfileManager::DeleteDynamicPubSubType method. */ RTPS_DllAPI static types::DynamicPubSubType* CreateDynamicPubSubType( - const std::string& type_name) - { - if (dynamic_types_.find(type_name) != dynamic_types_.end()) - { - return new types::DynamicPubSubType(dynamic_types_[type_name]->build()); - } - return nullptr; - } + const std::string& type_name); /** * Deletes the given DynamicPubSubType previously created by calling * XMLProfileManager::CreateDynamicPubSubType method. */ RTPS_DllAPI static void DeleteDynamicPubSubType( - types::DynamicPubSubType* type) - { - delete type; - } + types::DynamicPubSubType* type); private: diff --git a/src/cpp/dynamic-types/AnnotationDescriptor.cpp b/src/cpp/dynamic-types/AnnotationDescriptor.cpp index a615c34a951..898ef99af5b 100644 --- a/src/cpp/dynamic-types/AnnotationDescriptor.cpp +++ b/src/cpp/dynamic-types/AnnotationDescriptor.cpp @@ -12,17 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include #include -#include +#include namespace eprosima { namespace fastrtps { namespace types { AnnotationDescriptor::AnnotationDescriptor() -: type_(nullptr) + : type_(nullptr) { } @@ -31,17 +32,20 @@ AnnotationDescriptor::~AnnotationDescriptor() type_ = nullptr; } -AnnotationDescriptor::AnnotationDescriptor(const AnnotationDescriptor* descriptor) +AnnotationDescriptor::AnnotationDescriptor( + const AnnotationDescriptor* descriptor) { copy_from(descriptor); } -AnnotationDescriptor::AnnotationDescriptor(DynamicType_ptr pType) +AnnotationDescriptor::AnnotationDescriptor( + DynamicType_ptr pType) { type_ = pType; } -ReturnCode_t AnnotationDescriptor::copy_from(const AnnotationDescriptor* descriptor) +ReturnCode_t AnnotationDescriptor::copy_from( + const AnnotationDescriptor* descriptor) { if (descriptor != nullptr) { @@ -50,7 +54,7 @@ ReturnCode_t AnnotationDescriptor::copy_from(const AnnotationDescriptor* descrip type_ = descriptor->type_; value_ = descriptor->value_; } - catch(std::exception& /*e*/) + catch (std::exception& /*e*/) { return ReturnCode_t::RETCODE_ERROR; } @@ -63,7 +67,8 @@ ReturnCode_t AnnotationDescriptor::copy_from(const AnnotationDescriptor* descrip return ReturnCode_t::RETCODE_OK; } -bool AnnotationDescriptor::equals(const AnnotationDescriptor* other) const +bool AnnotationDescriptor::equals( + const AnnotationDescriptor* other) const { if (other != nullptr && (type_ == other->type_ || (type_ != nullptr && type_->equals(other->type_.get())))) { @@ -86,17 +91,29 @@ bool AnnotationDescriptor::equals(const AnnotationDescriptor* other) const bool AnnotationDescriptor::key_annotation() const { - auto it = value_.find(ANNOTATION_KEY_ID); - if (it == value_.end()) + bool ret = false; + + // Annotations @key and @Key have names "key" and "Key" respectively. + if (type_ && (type_->get_name() == ANNOTATION_KEY_ID || type_->get_name() == ANNOTATION_EPKEY_ID)) { - it = value_.find(ANNOTATION_EPKEY_ID); // Legacy "@Key" + // When an annotation is a key annotation, there is only one entry in value_. + // Its map key is ANNOTATION_VALUE_ID and its value is either "true" of "false". + // We cannot call get_value() directly because it is not const-qualified + auto it = value_.find(ANNOTATION_VALUE_ID); + + if (it != value_.end()) + { + ret = it->second == CONST_TRUE; + } } - return (it != value_.end() && it->second == CONST_TRUE); + + return ret; } -ReturnCode_t AnnotationDescriptor::get_value(std::string& value) +ReturnCode_t AnnotationDescriptor::get_value( + std::string& value) { - return get_value(value, "value"); + return get_value(value, ANNOTATION_VALUE_ID); } ReturnCode_t AnnotationDescriptor::get_value( @@ -112,7 +129,8 @@ ReturnCode_t AnnotationDescriptor::get_value( return ReturnCode_t::RETCODE_BAD_PARAMETER; } -ReturnCode_t AnnotationDescriptor::get_all_value(std::map& value) const +ReturnCode_t AnnotationDescriptor::get_all_value( + std::map& value) const { value = value_; return ReturnCode_t::RETCODE_OK; @@ -129,7 +147,8 @@ bool AnnotationDescriptor::is_consistent() const return true; } -void AnnotationDescriptor::set_type(DynamicType_ptr pType) +void AnnotationDescriptor::set_type( + DynamicType_ptr pType) { type_ = pType; } diff --git a/src/cpp/dynamic-types/DynamicType.cpp b/src/cpp/dynamic-types/DynamicType.cpp index ea8a13d7faa..7ea1581d3db 100644 --- a/src/cpp/dynamic-types/DynamicType.cpp +++ b/src/cpp/dynamic-types/DynamicType.cpp @@ -191,7 +191,7 @@ ReturnCode_t DynamicType::copy_from_builder( { DynamicTypeMember* newMember = new DynamicTypeMember(it->second); newMember->set_parent(this); - is_key_defined_ = newMember->key_annotation(); + is_key_defined_ |= newMember->key_annotation(); member_by_id_.insert(std::make_pair(newMember->get_id(), newMember)); member_by_name_.insert(std::make_pair(newMember->get_name(), newMember)); } @@ -245,14 +245,7 @@ TypeDescriptor* DynamicType::get_descriptor() bool DynamicType::key_annotation() const { - for (auto anIt = descriptor_->annotation_.begin(); anIt != descriptor_->annotation_.end(); ++anIt) - { - if ((*anIt)->key_annotation()) - { - return true; - } - } - return false; + return descriptor_->annotation_get_key(); } bool DynamicType::equals( diff --git a/src/cpp/dynamic-types/MemberDescriptor.cpp b/src/cpp/dynamic-types/MemberDescriptor.cpp index 3a906433f2c..5339a7539a9 100644 --- a/src/cpp/dynamic-types/MemberDescriptor.cpp +++ b/src/cpp/dynamic-types/MemberDescriptor.cpp @@ -12,12 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include -#include -#include +#include #include +#include #include -#include +#include +#include +#include namespace eprosima { namespace fastrtps { @@ -31,6 +32,7 @@ MemberDescriptor::MemberDescriptor() , index_(INDEX_INVALID) , default_label_(false) { + copy_annotations_from_type(type_); } MemberDescriptor::MemberDescriptor( @@ -43,6 +45,7 @@ MemberDescriptor::MemberDescriptor( , index_(index) , default_label_(false) { + copy_annotations_from_type(type_); } MemberDescriptor::MemberDescriptor( @@ -55,51 +58,54 @@ MemberDescriptor::MemberDescriptor( , default_label_(false) { copy_from(descriptor); + copy_annotations_from_type(type_); } MemberDescriptor::MemberDescriptor( MemberId id, const std::string& name, - DynamicType_ptr type_) + DynamicType_ptr type) : name_(name) , id_(id) - , type_(type_) + , type_(type) , default_value_("") , index_(INDEX_INVALID) , default_label_(false) { - + copy_annotations_from_type(type_); } MemberDescriptor::MemberDescriptor( MemberId id, const std::string& name, - DynamicType_ptr type_, + DynamicType_ptr type, const std::string& defaultValue) : name_(name) , id_(id) - , type_(type_) + , type_(type) , default_value_(defaultValue) , index_(INDEX_INVALID) , default_label_(false) { + copy_annotations_from_type(type_); } MemberDescriptor::MemberDescriptor( MemberId id, const std::string& name, - DynamicType_ptr type_, + DynamicType_ptr type, const std::string& defaultValue, const std::vector& unionLabels, bool isDefaultLabel) : name_(name) , id_(id) - , type_(type_) + , type_(type) , default_value_(defaultValue) , index_(INDEX_INVALID) , default_label_(isDefaultLabel) { labels_ = unionLabels; + copy_annotations_from_type(type_); } MemberDescriptor::~MemberDescriptor() @@ -411,6 +417,25 @@ bool MemberDescriptor::is_type_name_consistent( return TypeDescriptor::is_type_name_consistent(sName); } +void MemberDescriptor::copy_annotations_from_type( + const DynamicType_ptr& type) +{ + if (type) + { + // Copy annotations from type + uint32_t num_annotations = type->get_annotation_count(); + for (uint32_t i = 0; i < num_annotations; ++i) + { + AnnotationDescriptor ann; + type->get_annotation(ann, i); + AnnotationDescriptor* pNewDescriptor = new AnnotationDescriptor(); + pNewDescriptor->copy_from(&ann); + annotation_.push_back(pNewDescriptor); + } + } + +} + void MemberDescriptor::set_id( MemberId id) { diff --git a/src/cpp/rtps/xmlparser/XMLDynamicParser.cpp b/src/cpp/rtps/xmlparser/XMLDynamicParser.cpp index ed561da5cc6..7fee1f08f9f 100644 --- a/src/cpp/rtps/xmlparser/XMLDynamicParser.cpp +++ b/src/cpp/rtps/xmlparser/XMLDynamicParser.cpp @@ -1462,10 +1462,6 @@ p_dynamictypebuilder_t XMLParser::parseXMLMemberDynamicType( if (strncmp(memberTopicKey, "true", 5) == 0) { memberBuilder->apply_annotation(types::ANNOTATION_KEY_ID, "value", "true"); - if (p_dynamictype != nullptr) - { - p_dynamictype->apply_annotation(types::ANNOTATION_KEY_ID, "value", "true"); - } } } diff --git a/src/cpp/rtps/xmlparser/XMLProfileManager.cpp b/src/cpp/rtps/xmlparser/XMLProfileManager.cpp index ef527de55eb..f2d9b7a88c3 100644 --- a/src/cpp/rtps/xmlparser/XMLProfileManager.cpp +++ b/src/cpp/rtps/xmlparser/XMLProfileManager.cpp @@ -405,6 +405,22 @@ XMLP_ret XMLProfileManager::loadXMLString( return loaded_ret; } +types::DynamicPubSubType* XMLProfileManager::CreateDynamicPubSubType( + const std::string& type_name) +{ + if (dynamic_types_.find(type_name) != dynamic_types_.end()) + { + return new types::DynamicPubSubType(dynamic_types_[type_name]->build()); + } + return nullptr; +} + +void XMLProfileManager::DeleteDynamicPubSubType( + types::DynamicPubSubType* type) +{ + delete type; +} + XMLP_ret XMLProfileManager::extractProfiles( up_base_node_t profiles, const std::string& filename) diff --git a/test/unittest/dynamic_types/DynamicTypesTests.cpp b/test/unittest/dynamic_types/DynamicTypesTests.cpp index 44e1584c432..bb56424c10c 100644 --- a/test/unittest/dynamic_types/DynamicTypesTests.cpp +++ b/test/unittest/dynamic_types/DynamicTypesTests.cpp @@ -4942,6 +4942,29 @@ TEST_F(DynamicTypesTests, DynamicType_XML_Bitmask_test) } } +TEST_F(DynamicTypesTests, DynamicType_XML_key_annotation) +{ + using namespace xmlparser; + using namespace types; + + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); + ASSERT_EQ(ret, XMLP_ret::XML_OK); + + { + DynamicPubSubType* pbType = XMLProfileManager::CreateDynamicPubSubType("BoolStruct"); + ASSERT_FALSE(pbType->m_isGetKeyDefined); + XMLProfileManager::DeleteDynamicPubSubType(pbType); + } + + { + DynamicPubSubType* pbType = XMLProfileManager::CreateDynamicPubSubType("my_keyed_struct"); + ASSERT_TRUE(pbType->m_isGetKeyDefined); + XMLProfileManager::DeleteDynamicPubSubType(pbType); + } + + XMLProfileManager::DeleteInstance(); +} + TEST(TypeIdentifierTests, MinimalTypeIdentifierComparision) { TypeIdentifier enum1 = *GetMyEnumIdentifier(false); diff --git a/test/unittest/dynamic_types/types.xml b/test/unittest/dynamic_types/types.xml index 21a7ddddabe..9be040a2d95 100644 --- a/test/unittest/dynamic_types/types.xml +++ b/test/unittest/dynamic_types/types.xml @@ -268,4 +268,11 @@ + + + + + + +