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 changes to enable searching for .msg files in sub-directories #1218

Open
wants to merge 7 commits into
base: rolling
Choose a base branch
from
Open
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
1 change: 0 additions & 1 deletion mcap_vendor/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ macro(build_mcap_vendor)
include(FetchContent)
fetchcontent_declare(mcap
URL https://github.com/foxglove/mcap/archive/refs/tags/releases/cpp/v0.8.0.tar.gz
URL_HASH SHA1=b44637791da2c9c1cec61a3ba6994f1ef63a228c # v0.8.0
)
fetchcontent_makeavailable(mcap)

Expand Down
50 changes: 44 additions & 6 deletions rosbag2_storage_mcap/src/message_definition_cache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <string>
#include <unordered_set>
#include <utility>
#include <filesystem>

namespace rosbag2_storage_mcap::internal
{
Expand Down Expand Up @@ -119,6 +120,24 @@ static std::string delimiter(const DefinitionIdentifier & definition_identifier)
return result;
}

static std::vector<std::string> split_string(const std::string & str,
const std::string & delimiter = "\n")
{
std::vector<std::string> strings;
std::string::size_type pos = 0;
std::string::size_type prev = 0;

while ((pos = str.find(delimiter, prev)) != std::string::npos) {
strings.push_back(str.substr(prev, pos - prev));
prev = pos + delimiter.size();
}

// Get the last substring (or only, if delimiter is not found)
strings.push_back(str.substr(prev));

return strings;
}

MessageSpec::MessageSpec(Format format, std::string text, const std::string & package_context)
: dependencies(parse_dependencies(format, text, package_context))
, text(std::move(text))
Expand All @@ -139,15 +158,34 @@ const MessageSpec & MessageDefinitionCache::load_message_spec(
throw std::invalid_argument("Invalid package resource name: " +
definition_identifier.package_resource_name);
}
std::string package = match[1];
std::string share_dir = ament_index_cpp::get_package_share_directory(package);
std::ifstream file{share_dir + "/msg/" + match[2].str() +
extension_for_format(definition_identifier.format)};
if (!file.good()) {
const std::string package = match[1].str();
const std::string filename = match[2].str() + extension_for_format(definition_identifier.format);

// Get the package share directory, or throw a PackageNotFoundError
const std::string share_dir = ament_index_cpp::get_package_share_directory(package);

// Get the rosidl_interfaces index contents for this package
std::string index_contents;
if (!ament_index_cpp::get_resource("rosidl_interfaces", package, index_contents)) {
throw DefinitionNotFoundError(definition_identifier.package_resource_name);
}

std::string contents{std::istreambuf_iterator(file), {}};
// Find the first line that ends with the filename we're looking for
const auto lines = split_string(index_contents);
const auto it = std::find_if(lines.begin(), lines.end(), [&filename](const std::string & line) {
std::filesystem::path filePath(line);
return filePath.filename() == filename;
});
if (it == lines.end()) {
throw DefinitionNotFoundError(definition_identifier.package_resource_name);
}

// Read the file
const std::string full_path = share_dir + std::filesystem::path::preferred_separator + *it;
std::ifstream file{full_path};

const std::string contents{std::istreambuf_iterator(file), {}};

const MessageSpec & spec =
msg_specs_by_definition_identifier_
.emplace(definition_identifier,
Expand Down