Cleanup parse_xml.cpp
* add appendChildren (that corresponds to parseChildren)
* add appendTextElements and parseTextElements
* Detect duplicated manifest.hal and compatibility-matrix.hal entry
* Put more error messages
Bug: 34620633
Test: libvintf_test
Change-Id: Ice0e99bc9faca7bc61cddd5a2a27c16750fb88a7
diff --git a/parse_xml.cpp b/parse_xml.cpp
index c58e0f3..4bcdb9c 100644
--- a/parse_xml.cpp
+++ b/parse_xml.cpp
@@ -75,14 +75,6 @@
parent->InsertEndChild(d->NewText(text.c_str()));
}
-// text -> <name>text</name>
-inline void appendTextElement(NodeType *parent, const std::string &name,
- const std::string &text, DocType *d) {
- NodeType *c = createNode(name, d);
- appendText(c, text, d);
- appendChild(parent, c);
-}
-
inline std::string nameOf(NodeType *root) {
return root->Name() == NULL ? "" : root->Name();
}
@@ -181,6 +173,33 @@
return appendStrAttr(e, attrName, attr ? "true" : "false");
}
+ // text -> <name>text</name>
+ inline void appendTextElement(NodeType *parent, const std::string &name,
+ const std::string &text, DocType *d) const {
+ NodeType *c = createNode(name, d);
+ appendText(c, text, d);
+ appendChild(parent, c);
+ }
+
+ // text -> <name>text</name>
+ template<typename Array>
+ inline void appendTextElements(NodeType *parent, const std::string &name,
+ const Array &array, DocType *d) const {
+ for (const std::string &text : array) {
+ NodeType *c = createNode(name, d);
+ appendText(c, text, d);
+ appendChild(parent, c);
+ }
+ }
+
+ template<typename T, typename Array>
+ inline void appendChildren(NodeType *parent, const XmlNodeConverter<T> &conv,
+ const Array &array, DocType *d) const {
+ for (const T &t : array) {
+ appendChild(parent, conv(t, d));
+ }
+ }
+
template <typename T>
inline bool parseAttr(NodeType *root, const std::string &attrName, T *attr) const {
std::string attrText;
@@ -229,6 +248,16 @@
return true;
}
+ inline bool parseTextElements(NodeType *root, const std::string &elementName,
+ std::vector<std::string> *v) const {
+ auto nodes = getChildren(root, elementName);
+ v->resize(nodes.size());
+ for (size_t i = 0; i < nodes.size(); ++i) {
+ v->at(i) = getText(nodes[i]);
+ }
+ return true;
+ }
+
template <typename T>
inline bool parseChild(NodeType *root, const XmlNodeConverter<T> &conv, T *t) const {
NodeType *child = getChild(root, conv.elementName());
@@ -309,6 +338,7 @@
return false;
}
if (!::android::vintf::parseKernelConfigValue(stringValue, object)) {
+ this->mLastError = "Could not parse kernel config value \"" + stringValue + "\"";
return false;
}
return true;
@@ -340,9 +370,7 @@
appendAttr(root, "format", hal.format);
appendAttr(root, "optional", hal.optional);
appendTextElement(root, "name", hal.name, d);
- for (const auto &version : hal.versionRanges) {
- appendChild(root, versionRangeConverter(version, d));
- }
+ appendChildren(root, versionRangeConverter, hal.versionRanges, d);
}
bool buildObject(MatrixHal *object, NodeType *root) const override {
if (!parseAttr(root, "format", &object->format) ||
@@ -362,9 +390,7 @@
void mutateNode(const MatrixKernel &kernel, NodeType *root, DocType *d) const override {
appendAttr(root, "version", Version{kernel.mMinLts.version, kernel.mMinLts.majorRev});
appendAttr(root, "minlts", kernel.mMinLts);
- for (const KernelConfig &config : kernel.mConfigs) {
- appendChild(root, kernelConfigConverter(config, d));
- }
+ appendChildren(root, kernelConfigConverter, kernel.mConfigs, d);
}
bool buildObject(MatrixKernel *object, NodeType *root) const override {
Version v;
@@ -405,11 +431,8 @@
appendAttr(root, "format", hal.format);
appendTextElement(root, "name", hal.name, d);
appendChild(root, transportConverter(hal.transport, d));
- appendChild(root,
- halImplementationConverter(hal.impl, d));
- for (const auto &version : hal.versions) {
- appendChild(root, versionConverter(version, d));
- }
+ appendChild(root, halImplementationConverter(hal.impl, d));
+ appendChildren(root, versionConverter, hal.versions, d);
}
bool buildObject(ManifestHal *object, NodeType *root) const override {
if (!parseAttr(root, "format", &object->format) ||
@@ -450,9 +473,7 @@
std::string elementName() const override { return "manifest"; }
void mutateNode(const HalManifest &m, NodeType *root, DocType *d) const override {
appendAttr(root, "version", HalManifest::kVersion);
- for (const auto &hal : m.getHals()) {
- appendChild(root, manifestHalConverter(hal, d));
- }
+ appendChildren(root, manifestHalConverter, m.getHals(), d);
}
bool buildObject(HalManifest *object, NodeType *root) const override {
std::vector<ManifestHal> hals;
@@ -460,7 +481,10 @@
return false;
}
for (auto &&hal : hals) {
- object->add(std::move(hal));
+ if (!object->add(std::move(hal))) {
+ this->mLastError = "Duplicated manifest.hal entry";
+ return false;
+ }
}
return true;
}
@@ -472,12 +496,8 @@
std::string elementName() const override { return "compatibility-matrix"; }
void mutateNode(const CompatibilityMatrix &m, NodeType *root, DocType *d) const override {
appendAttr(root, "version", CompatibilityMatrix::kVersion);
- for (const auto &pair : m.mHals) {
- appendChild(root, matrixHalConverter(pair.second, d));
- }
- for (const auto &kernel : m.mKernels) {
- appendChild(root, matrixKernelConverter(kernel, d));
- }
+ appendChildren(root, matrixHalConverter, iterateValues(m.mHals), d);
+ appendChildren(root, matrixKernelConverter, m.mKernels, d);
appendChild(root, sepolicyConverter(m.mSepolicy, d));
}
bool buildObject(CompatibilityMatrix *object, NodeType *root) const override {
@@ -488,7 +508,10 @@
return false;
}
for (auto &&hal : hals) {
- object->add(std::move(hal));
+ if (!object->add(std::move(hal))) {
+ this->mLastError = "Duplicated compatibility-matrix.hal entry";
+ return false;
+ }
}
return true;
}