Add ReadAttrVec, ReadAttrArr, ReadAttrStr, and ReadAttrNum to XML utils.
Moving forward, the compiler objects should have encapsulated data, therefore the old ReadAttr* methods are being deprecated as they require raw pointers to read into. No external changes other than minor improvements to ReadAttr and ReadVector. PiperOrigin-RevId: 550880401 Change-Id: I632f40322ccd935f9af9b69e66b056c5cda6face
This commit is contained in:
committed by
Copybara-Service
parent
5b4b3415fa
commit
5f246ef210
+51
-5
@@ -16,7 +16,9 @@
|
||||
#ifndef MUJOCO_SRC_XML_XML_UTIL_H_
|
||||
#define MUJOCO_SRC_XML_XML_UTIL_H_
|
||||
|
||||
// stl
|
||||
#include <array>
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
@@ -98,21 +100,60 @@ class mjXUtil {
|
||||
// find value in map, return key ("": not found)
|
||||
static std::string FindValue(const mjMap* map, int mapsz, int value);
|
||||
|
||||
// read any type from attribute, return number read
|
||||
// if attribute is present, return vector of numerical data
|
||||
template<typename T>
|
||||
static std::optional<std::vector<T>> ReadAttrVec(tinyxml2::XMLElement* elem, const char* attr,
|
||||
bool required = false);
|
||||
|
||||
// if attribute is present, return attribute as a string
|
||||
static std::optional<std::string> ReadAttrStr(tinyxml2::XMLElement* elem, const char* attr,
|
||||
bool required = false);
|
||||
|
||||
// if attribute is present, return numerical value of attribute
|
||||
template<typename T>
|
||||
static std::optional<T> ReadAttrNum(tinyxml2::XMLElement* elem, const char* attr,
|
||||
bool required = false);
|
||||
|
||||
// if attribute is present, return array of numerical data
|
||||
// N should be small as data is allocated on the stack
|
||||
template<typename T, int N>
|
||||
static std::optional<std::array<T, N>> ReadAttrArr(tinyxml2::XMLElement* elem, const char* attr,
|
||||
bool required = false) {
|
||||
std::array<T, N> arr;
|
||||
int n = 0;
|
||||
if (!ReadAttrValues<T>(elem, attr, [&](int i, T num) { arr[i] = num; n++; }, N)) {
|
||||
throw mjXError(elem, "attribute '%s' has too much data", attr);
|
||||
}
|
||||
|
||||
if (!n) {
|
||||
if (required) {
|
||||
throw mjXError(elem, "required attribute missing: '%s'", attr);
|
||||
} else {
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
if (n < N) {
|
||||
throw mjXError(elem, "attribute '%s' does not have enough data", attr);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
// deprecated: use ReadAttrVec or ReadAttrArr
|
||||
template<typename T>
|
||||
static int ReadAttr(tinyxml2::XMLElement* elem, const char* attr, const int len,
|
||||
T* data, std::string& text,
|
||||
bool required = false, bool exact = true);
|
||||
|
||||
// read DOUBLE array into C++ vector, return number read
|
||||
// deprecated: use ReadAttrVec
|
||||
static int ReadVector(tinyxml2::XMLElement* elem, const char* attr,
|
||||
std::vector<double>& vec, std::string& text, bool required = false);
|
||||
|
||||
// read text attribute
|
||||
// deprecated: use ReadAttrStr
|
||||
static bool ReadAttrTxt(tinyxml2::XMLElement* elem, const char* attr, std::string& text,
|
||||
bool required = false);
|
||||
|
||||
// read int attribute
|
||||
// deprecated: use ReadAttrNum
|
||||
static bool ReadAttrInt(tinyxml2::XMLElement* elem, const char* attr, int* data,
|
||||
bool required = false);
|
||||
|
||||
@@ -155,6 +196,11 @@ class mjXUtil {
|
||||
// write attribute- keyword
|
||||
static void WriteAttrKey(tinyxml2::XMLElement* elem, std::string name,
|
||||
const mjMap* map, int mapsz, int data, int def = -12345);
|
||||
|
||||
private:
|
||||
template<typename T>
|
||||
static bool ReadAttrValues(tinyxml2::XMLElement* elem, const char* attr,
|
||||
std::function<void (int, T)> push, int max = -1);
|
||||
};
|
||||
|
||||
#endif // MUJOCO_SRC_XML_XML_UTIL_H_
|
||||
|
||||
Reference in New Issue
Block a user