Skip to content

Commit

Permalink
Allow fully qualified name in TypeDescriptor (#2005)
Browse files Browse the repository at this point in the history
* Allow fully qualified name in TypeDescriptor

According to the DDS-XTypes spec 7.5.2.4.10, the name of TypeDescriptor
should be the fully qualified name, which is the concatenation of
module names with the name of a type inside of those modules.

This change will allow an object of DynamicTypeBuilder to set a type
name that contains colon in it.

Signed-off-by: Yangbo Long <yangbo.long.mav@gmail.com>

* Try to fix linters

Signed-off-by: Yangbo Long <yangbo.long.mav@gmail.com>

* Add some unit tests for type descriptor names

Signed-off-by: Yangbo Long <yangbo.long.mav@gmail.com>

* Fix linters

Signed-off-by: Yangbo Long <yangbo.long.mav@gmail.com>
(cherry picked from commit 61267e3)

Co-authored-by: h.o.t. neglected <yangbo.long.mav@gmail.com>
  • Loading branch information
mergify[bot] and YangboLong authored Jun 15, 2021
1 parent d9dac63 commit 661a563
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 28 deletions.
24 changes: 24 additions & 0 deletions include/fastrtps/types/TypeDescriptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,23 @@ namespace eprosima {
namespace fastrtps {
namespace types {

enum FSM_INPUTS
{
LETTER = 1,
NUMBER,
UNDERSCORE,
COLON,
OTHER
};

enum FSM_STATES
{
INVALID = 0,
SINGLECOLON,
DOUBLECOLON,
VALID
};

class TypeDescriptor
{
protected:
Expand All @@ -37,6 +54,13 @@ class TypeDescriptor
DynamicType_ptr key_element_type_; // Key Type for maps.
std::vector<AnnotationDescriptor*> annotation_; // Annotations to apply

const int stateTable[4][6] = {
/* Input: letter, number, underscore, colon, other */
{INVALID, VALID, INVALID, INVALID, INVALID, INVALID},
{SINGLECOLON, INVALID, INVALID, INVALID, DOUBLECOLON, INVALID},
{DOUBLECOLON, VALID, INVALID, INVALID, INVALID, INVALID},
{VALID, VALID, VALID, VALID, SINGLECOLON, INVALID}};

void clean();

bool is_type_name_consistent(const std::string& sName) const;
Expand Down
43 changes: 32 additions & 11 deletions src/cpp/dynamic-types/TypeDescriptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,20 +249,41 @@ bool TypeDescriptor::is_consistent() const
bool TypeDescriptor::is_type_name_consistent(
const std::string& sName) const
{
// The first letter must start with a letter ( uppercase or lowercase )
if (sName.length() > 0 && std::isalpha(sName[0]))
{
// All characters must be letters, numbers or underscore.
for (uint32_t i = 1; i < sName.length(); ++i)
// Implement an FSM string parser to deal with both a plain type name
// and a fully qualified name. According to the DDS xtypes standard,
// type's fully qualified name is a concatenation of module names with
// the name of a type inside of those modules.
int currState = INVALID;
for (uint32_t i = 0; i < sName.length(); ++i)
{
int col = 0;
if (std::isalpha(sName[i]))
{
if (!std::isalnum(sName[i]) && sName[i] != 95)
{
return false;
}
col = LETTER;
}
else if (std::isdigit(sName[i]))
{
col = NUMBER;
}
else if (sName[i] == '_')
{
col = UNDERSCORE;
}
else if (sName[i] == ':')
{
col = COLON;
}
else
{
col = OTHER;
}
currState = stateTable[currState][col];
if (currState == INVALID)
{
return false;
}
return true;
}
return false;
return true;
}

void TypeDescriptor::set_kind(
Expand Down
89 changes: 72 additions & 17 deletions test/unittest/xtypes/XTypesTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,27 +18,31 @@
#include "idl/TypesTypeObject.h"
#include "idl/WideEnumTypeObject.h"
#include <gtest/gtest.h>
#include <fastrtps/types/DynamicTypeBuilderFactory.h>
#include <fastrtps/types/TypeDescriptor.h>

using namespace eprosima::fastrtps;
using namespace eprosima::fastrtps::types;

class XTypesTests: public ::testing::Test
class XTypesTests : public ::testing::Test
{
public:
XTypesTests()
{
//registerTypesTypes();
}

~XTypesTests()
{
TypeObjectFactory::delete_instance();
eprosima::fastdds::dds::Log::KillThread();
}

virtual void TearDown()
{
}
public:

XTypesTests()
{
//registerTypesTypes();
}

~XTypesTests()
{
TypeObjectFactory::delete_instance();
eprosima::fastdds::dds::Log::KillThread();
}

virtual void TearDown()
{
}

};

TEST_F(XTypesTests, EnumMinimalCoercion)
Expand Down Expand Up @@ -731,7 +735,58 @@ TEST_F(XTypesTests, SimpleUnionCompleteCoercion)
ASSERT_FALSE(basic_wide_union->consistent(*basic_union, consistencyQos));
}

int main(int argc, char **argv)
TEST_F(XTypesTests, TypeDescriptorFullyQualifiedName)
{
DynamicTypeBuilder_ptr my_builder(DynamicTypeBuilderFactory::get_instance()->create_struct_builder());
my_builder->add_member(0, "x", DynamicTypeBuilderFactory::get_instance()->create_float32_type());
my_builder->add_member(0, "y", DynamicTypeBuilderFactory::get_instance()->create_float32_type());
my_builder->add_member(0, "z", DynamicTypeBuilderFactory::get_instance()->create_float32_type());
const TypeDescriptor* my_descriptor = my_builder->get_type_descriptor();

my_builder->set_name("Position");
ASSERT_TRUE(my_descriptor->is_consistent());
my_builder->set_name("Position_");
ASSERT_TRUE(my_descriptor->is_consistent());
my_builder->set_name("Position123");
ASSERT_TRUE(my_descriptor->is_consistent());
my_builder->set_name("position_123");
ASSERT_TRUE(my_descriptor->is_consistent());
my_builder->set_name("_Position");
ASSERT_FALSE(my_descriptor->is_consistent());
my_builder->set_name("123Position");
ASSERT_FALSE(my_descriptor->is_consistent());
my_builder->set_name("Position&");
ASSERT_FALSE(my_descriptor->is_consistent());

my_builder->set_name("my_interface::action::dds_::Position");
ASSERT_TRUE(my_descriptor->is_consistent());
my_builder->set_name("my_interface:action::dds_::Position");
ASSERT_FALSE(my_descriptor->is_consistent());
my_builder->set_name("my_interface:::action::dds_::Position");
ASSERT_FALSE(my_descriptor->is_consistent());
my_builder->set_name("_my_interface::action::dds_::Position");
ASSERT_FALSE(my_descriptor->is_consistent());
my_builder->set_name("1my_interface::action::dds_::Position");
ASSERT_FALSE(my_descriptor->is_consistent());
my_builder->set_name(":my_interface::action::dds_::Position");
ASSERT_FALSE(my_descriptor->is_consistent());
my_builder->set_name("::my_interface::action::dds_::Position");
ASSERT_FALSE(my_descriptor->is_consistent());
my_builder->set_name("$my_interface::action::dds_::Position");
ASSERT_FALSE(my_descriptor->is_consistent());
my_builder->set_name("my_interface::2action::dds_::Position");
ASSERT_FALSE(my_descriptor->is_consistent());
my_builder->set_name("my_interface::_action::dds_::Position");
ASSERT_FALSE(my_descriptor->is_consistent());
my_builder->set_name("my_interface::*action::dds_::Position");
ASSERT_FALSE(my_descriptor->is_consistent());
my_builder->set_name("my_interface::action*::dds_::Position");
ASSERT_FALSE(my_descriptor->is_consistent());
}

int main(
int argc,
char** argv)
{
eprosima::fastdds::dds::Log::SetVerbosity(eprosima::fastdds::dds::Log::Info);

Expand Down

0 comments on commit 661a563

Please sign in to comment.