Skip to content

Commit

Permalink
Fix support for @key annotation in Dynamic types (#4694) (#4749)
Browse files Browse the repository at this point in the history
* Refs #20733: Fix support for key annotation in XML types

Signed-off-by: eduponz <eduardoponz@eprosima.com>

* Refs #20733: Add test

Signed-off-by: eduponz <eduardoponz@eprosima.com>

* Refs #20733: Move implementations to cpp

Signed-off-by: eduponz <eduardoponz@eprosima.com>

* Refs #20733: Properly fix key annotation handling

Signed-off-by: eduponz <eduardoponz@eprosima.com>

* Refs #20733: Apply Miguel's suggestions

Signed-off-by: eduponz <eduardoponz@eprosima.com>

---------

Signed-off-by: eduponz <eduardoponz@eprosima.com>
(cherry picked from commit eaa23db)

Co-authored-by: Eduardo Ponz Segrelles <eduardoponz@eprosima.com>
  • Loading branch information
mergify[bot] and EduPonz authored Jun 8, 2024
1 parent 0103a39 commit 0f649cd
Show file tree
Hide file tree
Showing 9 changed files with 180 additions and 82 deletions.
91 changes: 60 additions & 31 deletions include/fastrtps/types/MemberDescriptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,17 @@
#include <fastrtps/types/TypesBase.h>
#include <fastrtps/types/DynamicTypePtr.h>

namespace eprosima{
namespace fastrtps{
namespace types{
namespace eprosima {
namespace fastrtps {
namespace types {

class DynamicType;
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.
Expand All @@ -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(
Expand All @@ -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<uint64_t>& 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<uint64_t>& labels) const;
bool check_union_labels(
const std::vector<uint64_t>& 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;

Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand Down
14 changes: 2 additions & 12 deletions include/fastrtps/xmlparser/XMLProfileManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down
49 changes: 34 additions & 15 deletions src/cpp/dynamic-types/AnnotationDescriptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,18 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#include <fastdds/dds/log/Log.hpp>
#include <fastrtps/types/AnnotationDescriptor.h>
#include <fastrtps/types/DynamicType.h>
#include <fastrtps/types/DynamicTypeBuilderFactory.h>
#include <fastdds/dds/log/Log.hpp>
#include <fastrtps/types/TypesBase.h>

namespace eprosima {
namespace fastrtps {
namespace types {

AnnotationDescriptor::AnnotationDescriptor()
: type_(nullptr)
: type_(nullptr)
{
}

Expand All @@ -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)
{
Expand All @@ -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;
}
Expand All @@ -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()))))
{
Expand All @@ -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(
Expand All @@ -112,7 +129,8 @@ ReturnCode_t AnnotationDescriptor::get_value(
return ReturnCode_t::RETCODE_BAD_PARAMETER;
}

ReturnCode_t AnnotationDescriptor::get_all_value(std::map<std::string, std::string>& value) const
ReturnCode_t AnnotationDescriptor::get_all_value(
std::map<std::string, std::string>& value) const
{
value = value_;
return ReturnCode_t::RETCODE_OK;
Expand All @@ -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;
}
Expand Down
11 changes: 2 additions & 9 deletions src/cpp/dynamic-types/DynamicType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
Expand Down Expand Up @@ -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(
Expand Down
Loading

0 comments on commit 0f649cd

Please sign in to comment.