Support FilePaths instead of raw strings in XML code.

PiperOrigin-RevId: 655177026
Change-Id: I55b055551384b01ba7a4baa5d75fbe3329b7d25d
This commit is contained in:
Kyle Bayes
2024-07-23 08:35:56 -07:00
committed by Copybara-Service
parent 2d24c58819
commit 2746cb8559
10 changed files with 195 additions and 179 deletions
+35 -33
View File
@@ -45,6 +45,7 @@ namespace {
using tinyxml2::XMLAttribute;
using tinyxml2::XMLElement;
using mujoco::user::FilePath;
namespace mju = ::mujoco::util;
@@ -74,6 +75,36 @@ static std::optional<T> ParseInfOrNan(const std::string& s) {
return std::nullopt;
}
FilePath ResolveFilePath(XMLElement* e, const FilePath& filename,
const FilePath& dir) {
std::string path = "";
if (filename.IsAbs()) {
return filename;
}
// TODO(kylebayes): We first look in the base model directory for files to
// remain backwards compatible.
FilePath fullname = dir + filename;
mjResource *resource = mju_openResource(fullname.c_str(), nullptr,
nullptr, 0);
if (resource != nullptr) {
mju_closeResource(resource);
return filename;
}
XMLElement* parent = e->Parent()->ToElement();
for (; parent; parent = parent->Parent()->ToElement()) {
if (!std::strcmp(parent->Value(), "include")) {
auto file_attr = mjXUtil::ReadAttrStr(parent, "dir", false);
if (file_attr.has_value()) {
path = file_attr.value();
}
break;
}
}
return FilePath(path) + filename;
}
} // namespace
@@ -155,36 +186,6 @@ XMLElement* NextSiblingElement(XMLElement* e, const char* name) {
return nullptr;
}
static std::string ResolveFilePath(XMLElement* e, std::string filename,
const std::string& dir) {
std::string path = "";
if (mjuu_isabspath(filename)) {
return filename;
}
// TODO(kylebayes): We first look in the base model directory for files to
// remain backwards compatible.
std::string full_filename = mjuu_combinePaths(dir, filename);
mjResource *resource = mju_openResource(full_filename.c_str(), nullptr,
nullptr, 0);
if (resource != nullptr) {
mju_closeResource(resource);
return filename;
}
XMLElement* parent = e->Parent()->ToElement();
for (; parent; parent = parent->Parent()->ToElement()) {
if (!std::strcmp(parent->Value(), "include")) {
auto file_attr = mjXUtil::ReadAttrStr(parent, "dir", false);
if (file_attr.has_value()) {
path = file_attr.value();
}
break;
}
}
return mjuu_combinePaths(path, filename);
}
// constructor
mjXSchema::mjXSchema(const char* schema[][mjXATTRNUM], unsigned nrow) {
// set name and type
@@ -621,14 +622,15 @@ mjXUtil::ReadAttrStr(XMLElement* elem, const char* attr, bool required) {
}
// if attribute is present, return attribute as a filename
std::optional<std::string>
std::optional<FilePath>
mjXUtil::ReadAttrFile(XMLElement* elem, const char* attr,
const std::string& dir, bool required) {
const FilePath& dir, bool required) {
auto maybe_str = ReadAttrStr(elem, attr, required);
if (!maybe_str.has_value()) {
return std::nullopt;
}
return ResolveFilePath(elem, maybe_str.value(), dir);
FilePath filename(maybe_str.value());
return ResolveFilePath(elem, filename, dir);
}
// if attribute is present, return numerical value of attribute