diff --git a/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/names.hpp b/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/names.hpp index f4aff1c16..b19e95706 100644 --- a/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/names.hpp +++ b/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/names.hpp @@ -60,6 +60,8 @@ _create_topic_name( const char * base, const char * suffix = nullptr) { + assert(qos_profile); + assert(base); if (qos_profile->avoid_ros_namespace_conventions) { prefix = nullptr; } diff --git a/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/namespace_prefix.hpp b/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/namespace_prefix.hpp index 08bb3a787..a2063a0ab 100644 --- a/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/namespace_prefix.hpp +++ b/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/namespace_prefix.hpp @@ -36,18 +36,22 @@ RMW_FASTRTPS_SHARED_CPP_PUBLIC extern const std::vector _ros_prefix * \return name stripped of prefix, or * \return "" if name doesn't start with prefix */ +RMW_FASTRTPS_SHARED_CPP_PUBLIC std::string _resolve_prefix(const std::string & name, const std::string & prefix); /// Return the ROS specific prefix if it exists, otherwise "". +RMW_FASTRTPS_SHARED_CPP_PUBLIC std::string _get_ros_prefix_if_exists(const std::string & topic_name); /// Returns the topic name stripped of and ROS specific prefix if exists. +RMW_FASTRTPS_SHARED_CPP_PUBLIC std::string _strip_ros_prefix_if_exists(const std::string & topic_name); /// Returns the list of ros prefixes +RMW_FASTRTPS_SHARED_CPP_PUBLIC const std::vector & _get_all_ros_prefixes(); #endif // RMW_FASTRTPS_SHARED_CPP__NAMESPACE_PREFIX_HPP_ diff --git a/rmw_fastrtps_shared_cpp/src/namespace_prefix.cpp b/rmw_fastrtps_shared_cpp/src/namespace_prefix.cpp index f42b689e1..d02fd0d51 100644 --- a/rmw_fastrtps_shared_cpp/src/namespace_prefix.cpp +++ b/rmw_fastrtps_shared_cpp/src/namespace_prefix.cpp @@ -31,7 +31,7 @@ const std::vector _ros_prefixes = std::string _resolve_prefix(const std::string & name, const std::string & prefix) { - if (name.rfind(prefix, 0) == 0 && name.at(prefix.length()) == '/') { + if (name.rfind(prefix + "/", 0) == 0) { return name.substr(prefix.length()); } return ""; @@ -42,7 +42,7 @@ std::string _get_ros_prefix_if_exists(const std::string & topic_name) { for (const auto & prefix : _ros_prefixes) { - if (topic_name.rfind(prefix, 0) == 0 && topic_name.at(prefix.length()) == '/') { + if (topic_name.rfind(prefix + "/", 0) == 0) { return prefix; } } @@ -54,7 +54,7 @@ std::string _strip_ros_prefix_if_exists(const std::string & topic_name) { for (const auto & prefix : _ros_prefixes) { - if (topic_name.rfind(prefix, 0) == 0 && topic_name.at(prefix.length()) == '/') { + if (topic_name.rfind(prefix + "/", 0) == 0) { return topic_name.substr(prefix.length()); } } diff --git a/rmw_fastrtps_shared_cpp/test/CMakeLists.txt b/rmw_fastrtps_shared_cpp/test/CMakeLists.txt index d434ea6e4..3db9b12e6 100644 --- a/rmw_fastrtps_shared_cpp/test/CMakeLists.txt +++ b/rmw_fastrtps_shared_cpp/test/CMakeLists.txt @@ -23,3 +23,9 @@ ament_add_gtest(test_guid_utils test_guid_utils.cpp) if(TARGET test_guid_utils) target_link_libraries(test_guid_utils ${PROJECT_NAME}) endif() + +ament_add_gtest(test_names test_names.cpp) +if(TARGET test_names) + ament_target_dependencies(test_names rmw) + target_link_libraries(test_names ${PROJECT_NAME}) +endif() diff --git a/rmw_fastrtps_shared_cpp/test/test_names.cpp b/rmw_fastrtps_shared_cpp/test/test_names.cpp new file mode 100644 index 000000000..3d9a40bcc --- /dev/null +++ b/rmw_fastrtps_shared_cpp/test/test_names.cpp @@ -0,0 +1,90 @@ +// Copyright 2020 Open Source Robotics Foundation, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "gtest/gtest.h" + +#include "rmw/qos_profiles.h" + +#include "rmw_fastrtps_shared_cpp/names.hpp" +#include "rmw_fastrtps_shared_cpp/namespace_prefix.hpp" + +TEST(NamespaceTest, get_prefix) { + EXPECT_EQ("", _get_ros_prefix_if_exists("")); + EXPECT_EQ("", _get_ros_prefix_if_exists("not/a_ros_prefix")); + for (const auto & prefix : _get_all_ros_prefixes()) { + EXPECT_EQ("", _get_ros_prefix_if_exists(prefix)); + EXPECT_EQ("", _get_ros_prefix_if_exists(prefix + "_should_not_match")); + EXPECT_EQ("", _get_ros_prefix_if_exists("th/is_should_not_match/" + prefix)); + EXPECT_EQ(prefix, _get_ros_prefix_if_exists(prefix + "/")); + EXPECT_EQ(prefix, _get_ros_prefix_if_exists(prefix + "/should_match")); + } +} + +TEST(NamespaceTest, strip_prefix) { + EXPECT_EQ("", _strip_ros_prefix_if_exists("")); + EXPECT_EQ("/no_ros_prefix/test", _strip_ros_prefix_if_exists("/no_ros_prefix/test")); + for (const auto & prefix : _get_all_ros_prefixes()) { + EXPECT_EQ(prefix, _strip_ros_prefix_if_exists(prefix)); + EXPECT_EQ("/", _strip_ros_prefix_if_exists(prefix + "/")); + EXPECT_EQ( + prefix + "should_not_be_stripped", + _strip_ros_prefix_if_exists(prefix + "should_not_be_stripped")); + EXPECT_EQ( + "th/is_should_not_be_stripped/" + prefix, + _strip_ros_prefix_if_exists("th/is_should_not_be_stripped/" + prefix)); + EXPECT_EQ("/should_be_stripped", _strip_ros_prefix_if_exists(prefix + "/should_be_stripped")); + } +} + +TEST(NamespaceTest, resolve_prefix) { + EXPECT_EQ("", _resolve_prefix("", "")); + EXPECT_EQ("", _resolve_prefix("", "some_ros_prefix")); + EXPECT_EQ("", _resolve_prefix("/test", "some_ros_prefix")); + EXPECT_EQ("/test", _resolve_prefix("/test", "")); + EXPECT_EQ("", _resolve_prefix("some_ros_prefix", "some_ros_prefix")); + EXPECT_EQ("/", _resolve_prefix("some_ros_prefix/", "some_ros_prefix")); + EXPECT_EQ( + "/test_some_ros_prefix", + _resolve_prefix("some_ros_prefix/test_some_ros_prefix", "some_ros_prefix")); + EXPECT_EQ( + "", _resolve_prefix("some_ros_prefix_test", "some_ros_prefix")); + EXPECT_EQ( + "", _resolve_prefix("this_ros_prefix/test/some_ros_prefix", "some_ros_prefix")); +} + +TEST(NamespaceTest, name_mangling) { + rmw_qos_profile_t qos_profile = rmw_qos_profile_unknown; + qos_profile.avoid_ros_namespace_conventions = false; + + EXPECT_DEATH(_create_topic_name(nullptr, "", "", ""), ""); + + EXPECT_DEATH(_create_topic_name(&qos_profile, "", nullptr, ""), ""); + + EXPECT_STREQ( + "some_ros_prefix/test__suffix", _create_topic_name( + &qos_profile, "some_ros_prefix", "/test", "__suffix").c_str()); + + EXPECT_STREQ( + "/test__suffix", _create_topic_name( + &qos_profile, nullptr, "/test", "__suffix").c_str()); + + EXPECT_STREQ( + "some_ros_prefix/test", _create_topic_name( + &qos_profile, "some_ros_prefix", "/test", nullptr).c_str()); + + qos_profile.avoid_ros_namespace_conventions = true; + EXPECT_STREQ( + "/test__suffix", _create_topic_name( + &qos_profile, "some_ros_prefix", "/test", "__suffix").c_str()); +}