30 #include <console_bridge/console.h>
32 #include <boost/serialization/access.hpp>
33 #include <boost/serialization/nvp.hpp>
34 #include <boost/serialization/shared_ptr.hpp>
35 #include <boost/serialization/vector.hpp>
36 #include <boost/algorithm/string/classification.hpp>
37 #include <boost/algorithm/string/split.hpp>
48 std::filesystem::path path(url);
49 return (url.find(
"file:///") != 0 && url.find(
"package://") != 0 && path.is_relative());
55 template <
class Archive>
62 for (
const auto& env_variable : environment_variables)
69 const std::vector<std::string>& environment_variables)
71 for (
const auto& path : paths)
76 for (
const auto& env_variable : environment_variables)
84 char* ros_package_paths = std::getenv(environment_variable.c_str());
85 if (ros_package_paths !=
nullptr)
87 std::vector<std::string> tokens;
89 boost::split(tokens, ros_package_paths, boost::is_any_of(
":"), boost::token_compress_on);
91 boost::split(tokens, ros_package_paths, boost::is_any_of(
";"), boost::token_compress_on);
93 for (
const auto& token : tokens)
103 if (std::filesystem::is_directory(path) && std::filesystem::exists(path))
109 CONSOLE_BRIDGE_logError(
"Package Path does not exist: %s", path.string().c_str());
115 std::filesystem::path d(token);
116 if (std::filesystem::is_directory(d) && std::filesystem::exists(d))
119 std::filesystem::path check = d;
120 check.append(
"package.xml");
121 if (std::filesystem::exists(check))
123 std::string dir_name = d.filename().string();
129 std::filesystem::recursive_directory_iterator dir(d), end;
132 std::filesystem::path check = dir->path();
133 check.append(
"package.xml");
134 if (std::filesystem::exists(check))
136 std::string dir_name = dir->path().filename().string();
140 dir.disable_recursion_pending();
148 CONSOLE_BRIDGE_logError(
"Package Path does not exist: %s", token.c_str());
154 const size_t pos_slash = str.find(
'/');
155 const size_t pos_backslash = str.find(
'\\');
157 if (pos_slash != std::string::npos && pos_backslash != std::string::npos)
158 return std::min(pos_slash, pos_backslash);
160 if (pos_slash != std::string::npos)
163 if (pos_backslash != std::string::npos)
164 return pos_backslash;
166 return std::string::npos;
171 std::string mod_url = url;
172 if (url.find(
"file:///") == 0)
174 mod_url.erase(0, strlen(
"file://"));
176 if (pos == std::string::npos)
179 else if (url.find(
"package://") == 0)
181 mod_url.erase(0, strlen(
"package://"));
183 if (pos == std::string::npos)
186 std::string
package = mod_url.substr(0, pos);
187 mod_url.erase(0, pos);
192 mod_url = find_package->second + mod_url;
196 CONSOLE_BRIDGE_logError(
"Failed to find package resource %s for %s", package.c_str(), url.c_str());
201 if (!std::filesystem::path(mod_url).is_absolute())
203 CONSOLE_BRIDGE_logWarn(
"Resource not handled: %s", mod_url.c_str());
207 return std::make_shared<SimpleLocatedResource>(url, mod_url, std::make_shared<GeneralResourceLocator>(*
this));
213 template <
class Archive>
222 template <
class Archive>
229 : url_(std::move(url)), filename_(std::move(filename)), parent_(std::move(parent))
243 std::ifstream ifs(
filename_, std::ios::binary | std::ios::ate);
246 CONSOLE_BRIDGE_logError(
"Could not read all bytes from file: %s",
filename_.c_str());
249 std::ifstream::pos_type pos = ifs.tellg();
251 std::vector<uint8_t> file_contents(
static_cast<size_t>(pos));
253 ifs.seekg(0, std::ios::beg);
254 ifs.read(
reinterpret_cast<std::ifstream::char_type*
>(&file_contents[0]), pos);
256 return file_contents;
261 std::shared_ptr<std::ifstream> ifs = std::make_shared<std::ifstream>(
filename_, std::ios::binary);
264 CONSOLE_BRIDGE_logError(
"Could not get resource: %s",
filename_.c_str());
272 if (
parent_ ==
nullptr || url.empty())
278 std::size_t last_slash =
url_.find_last_of(
'/');
279 std::size_t last_backslash =
url_.find_last_of(
'\\');
280 std::size_t last_separator{ 0 };
281 if (last_slash != std::string::npos && last_backslash != std::string::npos)
282 last_separator = std::max(last_slash, last_backslash);
283 else if (last_slash != std::string::npos)
284 last_separator = last_slash;
285 else if (last_backslash != std::string::npos)
286 last_separator = last_backslash;
290 std::filesystem::path path(url);
291 std::string url_base_path =
url_.substr(0, last_separator);
292 std::string new_url =
293 url_base_path + std::string(1, std::filesystem::path::preferred_separator) + path.filename().string();
294 CONSOLE_BRIDGE_logDebug(
"new_url: %s", new_url.c_str());
295 return parent_->locateResource(new_url);
298 return parent_->locateResource(url);
313 template <
class Archive>
316 ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(
Resource);
317 ar& BOOST_SERIALIZATION_NVP(
url_);
319 ar& BOOST_SERIALIZATION_NVP(
parent_);
323 : url_(std::move(url)), bytes_(std::move(bytes)), parent_(std::move(parent))
328 : url_(std::move(url))
329 , bytes_(std::vector<uint8_t>(bytes, bytes + bytes_len))
330 , parent_(std::move(parent))
340 std::shared_ptr<std::stringstream> o = std::make_shared<std::stringstream>();
341 o->write((
const char*)&
bytes_.at(0),
static_cast<std::streamsize
>(
bytes_.size()));
342 o->seekg(0, std::stringstream::beg);
348 if (
parent_ ==
nullptr || url.empty())
352 if (resource !=
nullptr)
358 auto last_slash =
url_.find_last_of(
'/');
359 if (last_slash == std::string::npos)
362 std::filesystem::path path(url);
363 std::string url_base_path =
url_.substr(0, last_slash);
364 std::string new_url = url_base_path +
"/" + path.filename().string();
365 return parent_->locateResource(new_url);
380 template <
class Archive>
383 ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(
Resource);
384 ar& BOOST_SERIALIZATION_NVP(
url_);
385 ar& BOOST_SERIALIZATION_NVP(
bytes_);
386 ar& BOOST_SERIALIZATION_NVP(
parent_);