Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for parsing middle module name from type #128

Merged
merged 5 commits into from
Jun 11, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
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
6 changes: 6 additions & 0 deletions rosbag2/include/rosbag2/typesupport_helpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#define ROSBAG2__TYPESUPPORT_HELPERS_HPP_

#include <string>
#include <tuple>
#include <utility>

#include "rosidl_generator_cpp/message_type_support_decl.hpp"
Expand All @@ -28,9 +29,14 @@ ROSBAG2_PUBLIC
const rosidl_message_type_support_t *
get_typesupport(const std::string & type, const std::string & typesupport_identifier);

[[deprecated("use extract_type_identifier(const std::string & full_type) instead")]]
ROSBAG2_PUBLIC
const std::pair<std::string, std::string> extract_type_and_package(const std::string & full_type);

ROSBAG2_PUBLIC
const std::tuple<std::string, std::string, std::string>
extract_type_identifier(const std::string & full_type);

} // namespace rosbag2

#endif // ROSBAG2__TYPESUPPORT_HELPERS_HPP_
24 changes: 21 additions & 3 deletions rosbag2/src/rosbag2/typesupport_helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <memory>
#include <stdexcept>
#include <string>
#include <tuple>
#include <utility>

#include "ament_index_cpp/get_resources.hpp"
Expand Down Expand Up @@ -62,6 +63,17 @@ std::string get_typesupport_library_path(
}

const std::pair<std::string, std::string> extract_type_and_package(const std::string & full_type)
{
std::string package_name;
std::string type_name;

std::tie(package_name, std::ignore, type_name) = extract_type_identifier(full_type);

return {package_name, type_name};
}

const std::tuple<std::string, std::string, std::string>
extract_type_identifier(const std::string & full_type)
{
char type_separator = '/';
auto sep_position_back = full_type.find_last_of(type_separator);
Expand All @@ -75,17 +87,23 @@ const std::pair<std::string, std::string> extract_type_and_package(const std::st
}

std::string package_name = full_type.substr(0, sep_position_front);
std::string middle_module = "";
if (sep_position_back - sep_position_front > 0) {
middle_module =
full_type.substr(sep_position_front + 1, sep_position_back - sep_position_front - 1);
}
std::string type_name = full_type.substr(sep_position_back + 1);

return {package_name, type_name};
return std::make_tuple(package_name, middle_module, type_name);
}

const rosidl_message_type_support_t *
get_typesupport(const std::string & type, const std::string & typesupport_identifier)
{
std::string package_name;
std::string middle_module;
std::string type_name;
std::tie(package_name, type_name) = extract_type_and_package(type);
std::tie(package_name, middle_module, type_name) = extract_type_identifier(type);

std::string poco_dynamic_loading_error = "Something went wrong loading the typesupport library "
"for message type " + package_name + "/" + type_name + ".";
Expand All @@ -96,7 +114,7 @@ get_typesupport(const std::string & type, const std::string & typesupport_identi
auto typesupport_library = std::make_shared<Poco::SharedLibrary>(library_path);

auto symbol_name = typesupport_identifier + "__get_message_type_support_handle__" +
package_name + "__msg__" + type_name;
package_name + "__" + (middle_module.empty() ? "msg" : middle_module) + "__" + type_name;

if (!typesupport_library->hasSymbol(symbol_name)) {
throw std::runtime_error(poco_dynamic_loading_error + " Symbol not found.");
Expand Down
60 changes: 52 additions & 8 deletions rosbag2/test/rosbag2/test_typesupport_helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,25 @@
using namespace ::testing; // NOLINT

TEST(TypesupportHelpersTest, throws_exception_if_filetype_has_no_type) {
EXPECT_ANY_THROW(rosbag2::extract_type_and_package("just_a_package_name"));
EXPECT_ANY_THROW(rosbag2::extract_type_identifier("just_a_package_name"));
}

TEST(TypesupportHelpersTest, throws_exception_if_filetype_has_slash_at_the_start_only) {
EXPECT_ANY_THROW(rosbag2::extract_type_and_package("/name_with_slash_at_start"));
EXPECT_ANY_THROW(rosbag2::extract_type_identifier("/name_with_slash_at_start"));
}

TEST(TypesupportHelpersTest, throws_exception_if_filetype_has_slash_at_the_end_only) {
EXPECT_ANY_THROW(rosbag2::extract_type_and_package("name_with_slash_at_end/"));
EXPECT_ANY_THROW(rosbag2::extract_type_identifier("name_with_slash_at_end/"));
}

TEST(TypesupportHelpersTest, separates_into_package_and_name_for_correct_package) {
#if !defined(_WIN32)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#else // !defined(_WIN32)
# pragma warning(push)
# pragma warning(disable: 4996)
#endif
TEST(TypesupportHelpersTest, separates_into_package_and_name_for_correct_package_legacy) {
std::string package;
std::string name;
std::tie(package, name) = rosbag2::extract_type_and_package("package/name");
Expand All @@ -44,24 +51,61 @@ TEST(TypesupportHelpersTest, separates_into_package_and_name_for_correct_package
EXPECT_THAT(name, StrEq("name"));
}

TEST(TypesupportHelpersTest, separates_into_package_and_name_for_multiple_slashes_legacy) {
std::string package;
std::string name;
std::tie(package, name) =
rosbag2::extract_type_and_package("package/middle_module/name");

EXPECT_THAT(package, StrEq("package"));
EXPECT_THAT(name, StrEq("name"));
}
#if !defined(_WIN32)
# pragma GCC diagnostic pop
#else // !defined(_WIN32)
# pragma warning(pop)
#endif

TEST(TypesupportHelpersTest, separates_into_package_and_name_for_correct_package) {
std::string package;
std::string middle_module;
std::string name;
std::tie(package, middle_module, name) = rosbag2::extract_type_identifier("package/name");

EXPECT_THAT(package, StrEq("package"));
EXPECT_THAT(middle_module, StrEq(""));
EXPECT_THAT(name, StrEq("name"));
}

TEST(TypesupportHelpersTest, separates_into_package_and_name_for_multiple_slashes) {
std::string package;
std::string middle_module;
std::string name;
std::tie(package, name) = rosbag2::extract_type_and_package("name/with/multiple_slashes");
std::tie(package, middle_module, name) =
rosbag2::extract_type_identifier("package/middle_module/name");

EXPECT_THAT(package, StrEq("name"));
EXPECT_THAT(name, StrEq("multiple_slashes"));
EXPECT_THAT(package, StrEq("package"));
EXPECT_THAT(middle_module, StrEq("middle_module"));
EXPECT_THAT(name, StrEq("name"));
}

TEST(TypesupportHelpersTest, throws_exception_if_library_cannot_be_found) {
EXPECT_THROW(
rosbag2::get_typesupport("invalid/message", "rosidl_typesupport_cpp"), std::runtime_error);
}

TEST(TypesupportHelpersTest, returns_c_type_info_for_valid_library) {
TEST(TypesupportHelpersTest, returns_c_type_info_for_valid_legacy_library) {
auto string_typesupport =
rosbag2::get_typesupport("test_msgs/BasicTypes", "rosidl_typesupport_cpp");

EXPECT_THAT(std::string(string_typesupport->typesupport_identifier),
ContainsRegex("rosidl_typesupport"));
}

TEST(TypesupportHelpersTest, returns_c_type_info_for_valid_library) {
auto string_typesupport =
rosbag2::get_typesupport("test_msgs/msg/BasicTypes", "rosidl_typesupport_cpp");

EXPECT_THAT(std::string(string_typesupport->typesupport_identifier),
ContainsRegex("rosidl_typesupport"));
}