Skip to content

Commit

Permalink
Fixes for indirect hashes dependencies. (#4496)
Browse files Browse the repository at this point in the history
* Refs #20572: Fixes for indirect hashes dependencies.

Signed-off-by: adriancampo <[email protected]>

* Refs #20572: Applied suggestion. Added tests for build_plain_map_s_type_defn_inconsistencies.

Signed-off-by: adriancampo <[email protected]>

* Refs #20572: Fixes for plain_map_type_identifier_header_consistency.

Signed-off-by: adriancampo <[email protected]>

* Refs #20572: Changed get_type_dependencies methods and aliases equiv_kind as map components.

Signed-off-by: adriancampo <[email protected]>

* Refs #20572: Applied suggestions.

Signed-off-by: adriancampo <[email protected]>

* Refs #20572: Combined map consistency methods.

Signed-off-by: adriancampo <[email protected]>

* Refs #20572: Removed redundant check.

Signed-off-by: adriancampo <[email protected]>

---------

Signed-off-by: adriancampo <[email protected]>
  • Loading branch information
adriancampo authored Mar 11, 2024
1 parent 6ca9630 commit 0cfed85
Show file tree
Hide file tree
Showing 5 changed files with 1,107 additions and 90 deletions.
27 changes: 27 additions & 0 deletions include/fastdds/dds/xtypes/type_representation/TypeObjectUtils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2121,6 +2121,33 @@ class TypeObjectUtils
const PlainCollectionHeader& header,
const TypeIdentifier& element_identifier);

/**
* @brief Retrieves the equivalence kind of a component within a map.
*
* @param[in] identifier TypeIdentifier of the component to be checked.
* @return EK_COMPLETE if the component equivalence kind is EK_COMPLETE.
* @return EK_MINIMAL if the component equivalence kind is EK_MINIMAL.
* @return EK_BOTH if the component equivalence kind is EK_BOTH.
* @return TK_NONE if the component type is invalid.
*/
static EquivalenceKind get_map_component_equiv_kind_for_consistency(
const TypeIdentifier& identifier);

/**
* @brief Check consistency between a given PlainCollectionHeader of a map and the related TypeIdentifier:
* 1. Key TypeIdentifier is valid
* 2. TypeIdentifier initialized
* 3. Consistency of EquivalenceKinds
*
* @param[in] header PlainCollectionHeader of the map to be checked.
* @param[in] type_identifier TypeIdentifier to be checked.
* @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the given parameters are not
* consistent.
*/
static void plain_map_type_components_consistency(
const PlainCollectionHeader& header,
const TypeIdentifier& type_identifier);

/**
* @brief Check map key_identifier consistency.
* XTypes v1.3 Clause 7.2.2.4.3: Implementers of this specification need only support key elements of signed
Expand Down
67 changes: 55 additions & 12 deletions src/cpp/fastdds/xtypes/type_representation/TypeObjectRegistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -342,25 +342,14 @@ ReturnCode_t TypeObjectRegistry::get_type_dependencies(
const TypeIdentifierSeq& type_identifiers,
std::unordered_set<TypeIdentfierWithSize>& type_dependencies)
{
ReturnCode_t ret_code = eprosima::fastdds::dds::RETCODE_OK;
for (const TypeIdentifier& type_id : type_identifiers)
{
if (!TypeObjectUtils::is_direct_hash_type_identifier(type_id))
{
return eprosima::fastdds::dds::RETCODE_BAD_PARAMETER;
}
TypeObject type_object;
ret_code = get_type_object(type_id, type_object);
if (eprosima::fastdds::dds::RETCODE_OK == ret_code)
{
ret_code = get_dependencies_from_type_object(type_object, type_dependencies);
if (eprosima::fastdds::dds::RETCODE_OK != ret_code)
{
break;
}
}
}
return ret_code;
return get_type_dependencies_impl(type_identifiers, type_dependencies);
}

bool TypeObjectRegistry::is_type_identifier_known(
Expand Down Expand Up @@ -560,6 +549,60 @@ ReturnCode_t TypeObjectRegistry::get_dependencies_from_type_object(
return ret_code;
}

ReturnCode_t TypeObjectRegistry::get_type_dependencies_impl(
const TypeIdentifierSeq& type_identifiers,
std::unordered_set<TypeIdentfierWithSize>& type_dependencies)
{
ReturnCode_t ret_code = eprosima::fastdds::dds::RETCODE_OK;
for (const TypeIdentifier& type_id : type_identifiers)
{
if (TypeObjectUtils::is_fully_descriptive_type_identifier(type_id))
{
return eprosima::fastdds::dds::RETCODE_BAD_PARAMETER;
}
else if (TypeObjectUtils::is_direct_hash_type_identifier(type_id))
{
TypeObject type_object;
ret_code = get_type_object(type_id, type_object);
if (eprosima::fastdds::dds::RETCODE_OK == ret_code)
{
ret_code = get_dependencies_from_type_object(type_object, type_dependencies);
if (eprosima::fastdds::dds::RETCODE_OK != ret_code)
{
break;
}
}
}
else if (TypeObjectUtils::is_indirect_hash_type_identifier(type_id))
{
switch (type_id._d())
{
case TI_PLAIN_SEQUENCE_SMALL:
get_indirect_hash_collection_dependencies(type_id.seq_sdefn(), type_dependencies);
break;
case TI_PLAIN_SEQUENCE_LARGE:
get_indirect_hash_collection_dependencies(type_id.seq_ldefn(), type_dependencies);
break;
case TI_PLAIN_ARRAY_SMALL:
get_indirect_hash_collection_dependencies(type_id.array_sdefn(), type_dependencies);
break;
case TI_PLAIN_ARRAY_LARGE:
get_indirect_hash_collection_dependencies(type_id.array_ldefn(), type_dependencies);
break;
case TI_PLAIN_MAP_SMALL:
get_indirect_hash_map_dependencies(type_id.map_sdefn(), type_dependencies);
break;
case TI_PLAIN_MAP_LARGE:
get_indirect_hash_map_dependencies(type_id.map_ldefn(), type_dependencies);
break;
default:
return eprosima::fastdds::dds::RETCODE_BAD_PARAMETER;
}
}
}
return ret_code;
}

void TypeObjectRegistry::add_dependency(
const TypeIdentifier& type_id,
std::unordered_set<TypeIdentfierWithSize>& type_dependencies)
Expand Down
145 changes: 135 additions & 10 deletions src/cpp/fastdds/xtypes/type_representation/TypeObjectRegistry.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,9 @@ class TypeObjectRegistry : public ITypeObjectRegistry
TypeInformation& type_information);

/**
* @brief Get the type dependencies of the given type identifiers.
* @brief Get the type dependencies of the given direct hash type identifiers.
*
* @param[in] type_identifiers Sequence with the queried TypeIdentifiers.
* @param[in] type_identifiers Sequence with the queried direct hash TypeIdentifiers.
* @param[in out] type_dependencies Unordered set of TypeIdentifiers with related TypeObject serialized size.
* @return ReturnCode_t RETCODE_OK if the operation is successful.
* RETCODE_NO_DATA if any given TypeIdentifier is unknown to the registry.
Expand Down Expand Up @@ -275,6 +275,19 @@ class TypeObjectRegistry : public ITypeObjectRegistry

protected:

/**
* @brief Get the type dependencies of the given type identifiers.
*
* @param[in] type_identifiers Sequence with the queried TypeIdentifiers.
* @param[in out] type_dependencies Unordered set of TypeIdentifiers with related TypeObject serialized size.
* @return ReturnCode_t RETCODE_OK if the operation is successful.
* RETCODE_NO_DATA if any given TypeIdentifier is unknown to the registry.
* RETCODE_BAD_PARAMETER if any given TypeIdentifier is fully descriptive.
*/
ReturnCode_t get_type_dependencies_impl(
const TypeIdentifierSeq& type_identifiers,
std::unordered_set<TypeIdentfierWithSize>& type_dependencies);

/**
* @brief Add type dependency to the sequence.
*
Expand All @@ -285,6 +298,82 @@ class TypeObjectRegistry : public ITypeObjectRegistry
const TypeIdentifier& type_id,
std::unordered_set<TypeIdentfierWithSize>& type_dependencies);

/**
* @brief Get the type dependencies of plain sequences or arrays.
*
* @tparam T Either PlainSequenceSElemDefn, PlainSequenceLElemDefn, PlainArraySElemDefn or PlainArrayLElemDefn.
* @param[in] collection_type Plain collection Type.
* @param[in out] type_dependencies Unordered set of TypeIdentifiers with related TypeObject serialized size.
* @return ReturnCode_t RETCODE_OK if the operation is successful.
* RETCODE_NO_DATA if any dependent TypeIdentifier is unknown to the registry.
* RETCODE_BAD_PARAMETER if the collection type is fully descriptive.
*/
template<typename T>
ReturnCode_t get_indirect_hash_collection_dependencies(
const T& collection_type,
std::unordered_set<TypeIdentfierWithSize>& type_dependencies)
{
TypeIdentifierSeq type_ids;

TypeIdentifier type_id = *collection_type.element_identifier();
if (TypeObjectUtils::is_direct_hash_type_identifier(type_id))
{
add_dependency(type_id, type_dependencies);
type_ids.push_back(type_id);
}
else if (TypeObjectUtils::is_indirect_hash_type_identifier(type_id))
{
type_ids.push_back(type_id);
}

if (!type_ids.empty())
{
return get_type_dependencies_impl(type_ids, type_dependencies);
}
return eprosima::fastdds::dds::RETCODE_BAD_PARAMETER;
}

/**
* @brief Get the type dependencies of plain maps.
*
* @tparam T Either PlainMapSTypeDefn or PlainMapLTypeDefn.
* @param[in] map_type Plain map Type.
* @param[in out] type_dependencies Unordered set of TypeIdentifiers with related TypeObject serialized size.
* @return ReturnCode_t RETCODE_OK if the operation is successful.
* RETCODE_NO_DATA if any dependent TypeIdentifier is unknown to the registry.
* RETCODE_BAD_PARAMETER if both the key and the elements types are fully descriptive.
*/
template<typename T>
ReturnCode_t get_indirect_hash_map_dependencies(
const T& map_type,
std::unordered_set<TypeIdentfierWithSize>& type_dependencies)
{
TypeIdentifierSeq type_ids;

TypeIdentifier key_id = *map_type.key_identifier();
if (TypeObjectUtils::is_direct_hash_type_identifier(key_id))
{
add_dependency(key_id, type_dependencies);
type_ids.push_back(key_id);
}
TypeIdentifier element_id = *map_type.element_identifier();
if (TypeObjectUtils::is_direct_hash_type_identifier(element_id))
{
add_dependency(element_id, type_dependencies);
type_ids.push_back(element_id);
}
else if (TypeObjectUtils::is_indirect_hash_type_identifier(element_id))
{
type_ids.push_back(element_id);
}

if (!type_ids.empty())
{
return get_type_dependencies_impl(type_ids, type_dependencies);
}
return eprosima::fastdds::dds::RETCODE_BAD_PARAMETER;
}

/**
* @brief Get the alias type dependencies.
*
Expand All @@ -299,13 +388,22 @@ class TypeObjectRegistry : public ITypeObjectRegistry
const T& alias_type,
std::unordered_set<TypeIdentfierWithSize>& type_dependencies)
{
TypeIdentifierSeq type_ids;

TypeIdentifier type_id = alias_type.body().common().related_type();
if (TypeObjectUtils::is_direct_hash_type_identifier(type_id))
{
add_dependency(type_id, type_dependencies);
TypeIdentifierSeq type_ids;
type_ids.push_back(type_id);
return get_type_dependencies(type_ids, type_dependencies);
}
else if (TypeObjectUtils::is_indirect_hash_type_identifier(type_id))
{
type_ids.push_back(type_id);
}

if (!type_ids.empty())
{
return get_type_dependencies_impl(type_ids, type_dependencies);
}
return eprosima::fastdds::dds::RETCODE_OK;
}
Expand All @@ -325,6 +423,7 @@ class TypeObjectRegistry : public ITypeObjectRegistry
std::unordered_set<TypeIdentfierWithSize>& type_dependencies)
{
TypeIdentifierSeq type_ids;

for (auto member : annotation_type.member_seq())
{
TypeIdentifier type_id = member.common().member_type_id();
Expand All @@ -334,9 +433,10 @@ class TypeObjectRegistry : public ITypeObjectRegistry
type_ids.push_back(type_id);
}
}

if (!type_ids.empty())
{
return get_type_dependencies(type_ids, type_dependencies);
return get_type_dependencies_impl(type_ids, type_dependencies);
}
return eprosima::fastdds::dds::RETCODE_OK;
}
Expand Down Expand Up @@ -370,10 +470,14 @@ class TypeObjectRegistry : public ITypeObjectRegistry
add_dependency(type_id, type_dependencies);
type_ids.push_back(type_id);
}
else if (TypeObjectUtils::is_indirect_hash_type_identifier(type_id))
{
type_ids.push_back(type_id);
}
}
if (!type_ids.empty())
{
return get_type_dependencies(type_ids, type_dependencies);
return get_type_dependencies_impl(type_ids, type_dependencies);
}
return eprosima::fastdds::dds::RETCODE_OK;
}
Expand All @@ -393,6 +497,7 @@ class TypeObjectRegistry : public ITypeObjectRegistry
std::unordered_set<TypeIdentfierWithSize>& type_dependencies)
{
TypeIdentifierSeq type_ids;

TypeIdentifier discriminator_type_id = union_type.discriminator().common().type_id();
if (TypeObjectUtils::is_direct_hash_type_identifier(discriminator_type_id))
{
Expand All @@ -407,10 +512,15 @@ class TypeObjectRegistry : public ITypeObjectRegistry
add_dependency(type_id, type_dependencies);
type_ids.push_back(type_id);
}
else if (TypeObjectUtils::is_indirect_hash_type_identifier(type_id))
{
type_ids.push_back(type_id);
}
}

if (!type_ids.empty())
{
return get_type_dependencies(type_ids, type_dependencies);
return get_type_dependencies_impl(type_ids, type_dependencies);
}
return eprosima::fastdds::dds::RETCODE_OK;
}
Expand All @@ -429,13 +539,22 @@ class TypeObjectRegistry : public ITypeObjectRegistry
const T& collection_type,
std::unordered_set<TypeIdentfierWithSize>& type_dependencies)
{
TypeIdentifierSeq type_ids;

TypeIdentifier type_id = collection_type.element().common().type();
if (TypeObjectUtils::is_direct_hash_type_identifier(type_id))
{
add_dependency(type_id, type_dependencies);
TypeIdentifierSeq type_ids;
type_ids.push_back(type_id);
return get_type_dependencies(type_ids, type_dependencies);
}
else if (TypeObjectUtils::is_indirect_hash_type_identifier(type_id))
{
type_ids.push_back(type_id);
}

if (!type_ids.empty())
{
return get_type_dependencies_impl(type_ids, type_dependencies);
}
return eprosima::fastdds::dds::RETCODE_OK;
}
Expand All @@ -455,6 +574,7 @@ class TypeObjectRegistry : public ITypeObjectRegistry
std::unordered_set<TypeIdentfierWithSize>& type_dependencies)
{
TypeIdentifierSeq type_ids;

TypeIdentifier key_type_id = map_type.key().common().type();
if (TypeObjectUtils::is_direct_hash_type_identifier(key_type_id))
{
Expand All @@ -467,9 +587,14 @@ class TypeObjectRegistry : public ITypeObjectRegistry
add_dependency(element_type_id, type_dependencies);
type_ids.push_back(element_type_id);
}
else if (TypeObjectUtils::is_indirect_hash_type_identifier(element_type_id))
{
type_ids.push_back(element_type_id);
}

if (!type_ids.empty())
{
return get_type_dependencies(type_ids, type_dependencies);
return get_type_dependencies_impl(type_ids, type_dependencies);
}
return eprosima::fastdds::dds::RETCODE_OK;
}
Expand Down
Loading

0 comments on commit 0cfed85

Please sign in to comment.