Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions include/ignition/transport/TopicUtils.hh
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,14 @@ namespace ignition
std::string &_partition,
std::string &_namespaceAndTopic);

/// \brief Convert a topic name to a valid topic. The input topic is
/// modified by:
/// * turning white space into `_`.
/// * removing special characters and combinations.
/// \param[in] _topic Input topic, which may be invalid.
/// \return A valid topic, or empty string if not possible to convert.
public: static std::string AsValidTopic(const std::string &_topic);

/// \brief The kMaxNameLength specifies the maximum number of characters
/// allowed in a namespace, a partition name, a topic name, and a fully
/// qualified topic name.
Expand Down
23 changes: 23 additions & 0 deletions src/TopicUtils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*
*/

#include <regex>
#include <string>

#include "ignition/transport/TopicUtils.hh"
Expand Down Expand Up @@ -154,3 +155,25 @@ bool TopicUtils::DecomposeFullyQualifiedTopic(
_namespaceAndTopic = possibleTopic;
return true;
}

//////////////////////////////////////////////////
std::string TopicUtils::AsValidTopic(const std::string &_topic)
{
std::string validTopic{_topic};

// Substitute spaces with _
validTopic = std::regex_replace(validTopic, std::regex(" "), "_");

// Remove special characters and combinations
validTopic = std::regex_replace(validTopic, std::regex("@"), "");
validTopic = std::regex_replace(validTopic, std::regex("~"), "");
validTopic = std::regex_replace(validTopic, std::regex("//"), "");
validTopic = std::regex_replace(validTopic, std::regex(":="), "");

if (!IsValidTopic(validTopic))
{
return std::string();
}

return validTopic;
}
49 changes: 49 additions & 0 deletions src/TopicUtils_TEST.cc
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,55 @@ TEST(TopicUtilsTest, testFullyQualifiedName)
}
}

//////////////////////////////////////////////////
TEST(TopicUtilsTest, asValidTopic)
{
for (auto unmodified :
{
"/abc",
"abc/de",
"a",
"ABC/",
"/abc",
"/abc/d",
"/abc/d/e",
"a(bc)d-e_f=h+i.j"
})
{
auto valid = transport::TopicUtils::AsValidTopic(unmodified);
EXPECT_EQ(unmodified, valid);
EXPECT_TRUE(transport::TopicUtils::IsValidTopic(valid)) << valid;
}

std::vector<std::pair<std::string, std::string>> modifiedStrings =
{
{"a b c", "a_b__c"},
{"a@b@c", "abc"},
{"a:=b:=c", "abc"},
{"a//b/c", "ab/c"},
{"a~b~c", "abc"}
};

for (auto modified : modifiedStrings)
{
auto valid = transport::TopicUtils::AsValidTopic(modified.first);
EXPECT_EQ(modified.second, valid);
EXPECT_TRUE(transport::TopicUtils::IsValidTopic(valid)) << valid;
}

for (auto fail :
{
"",
"@@@",
"~@~",
})
{
auto empty = transport::TopicUtils::AsValidTopic(fail);
EXPECT_TRUE(empty.empty());
EXPECT_FALSE(transport::TopicUtils::IsValidTopic(empty));
}
}

//////////////////////////////////////////////////
int main(int argc, char **argv)
{
Expand Down