1676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong/* 2676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong * Copyright (C) 2017 The Android Open Source Project 3676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong * 4676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong * Licensed under the Apache License, Version 2.0 (the "License"); 5676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong * you may not use this file except in compliance with the License. 6676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong * You may obtain a copy of the License at 7676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong * 8676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong * http://www.apache.org/licenses/LICENSE-2.0 9676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong * 10676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong * Unless required by applicable law or agreed to in writing, software 11676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong * distributed under the License is distributed on an "AS IS" BASIS, 12676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong * See the License for the specific language governing permissions and 14676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong * limitations under the License. 15676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong */ 16676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 17676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong// Convert objects from and to xml. 18676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 19676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong#include <tinyxml2.h> 20676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 21676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong#include "parse_string.h" 22676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong#include "parse_xml.h" 23676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 24676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongnamespace android { 25676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongnamespace vintf { 26676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 27676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong// --------------- tinyxml2 details 28676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 29676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongusing NodeType = tinyxml2::XMLElement; 30676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongusing DocType = tinyxml2::XMLDocument; 31676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 32676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong// caller is responsible for deleteDocument() call 33676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Honginline DocType *createDocument() { 34676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return new tinyxml2::XMLDocument(); 35676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong} 36676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 37676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong// caller is responsible for deleteDocument() call 38676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Honginline DocType *createDocument(const std::string &xml) { 39676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong DocType *doc = new tinyxml2::XMLDocument(); 40676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong if (doc->Parse(xml.c_str()) == tinyxml2::XML_NO_ERROR) { 41676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return doc; 42676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 43676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong delete doc; 44676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return nullptr; 45676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong} 46676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 47676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Honginline void deleteDocument(DocType *d) { 48676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong delete d; 49676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong} 50676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 51676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Honginline std::string printDocument(DocType *d) { 52676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong tinyxml2::XMLPrinter p; 53676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong d->Print(&p); 54676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return std::string{p.CStr()}; 55676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong} 56676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 57676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Honginline NodeType *createNode(const std::string &name, DocType *d) { 58676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return d->NewElement(name.c_str()); 59676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong} 60676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 61676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Honginline void appendChild(NodeType *parent, NodeType *child) { 62676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong parent->InsertEndChild(child); 63676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong} 64676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 65676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Honginline void appendChild(DocType *parent, NodeType *child) { 66676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong parent->InsertEndChild(child); 67676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong} 68676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 69676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Honginline void appendStrAttr(NodeType *e, const std::string &attrName, const std::string &attr) { 70676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong e->SetAttribute(attrName.c_str(), attr.c_str()); 71676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong} 72676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 73676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong// text -> text 74676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Honginline void appendText(NodeType *parent, const std::string &text, DocType *d) { 75676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong parent->InsertEndChild(d->NewText(text.c_str())); 76676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong} 77676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 78676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Honginline std::string nameOf(NodeType *root) { 79cd41ffc75e885e2b407e4eff3d761d59ffa0d766Yifan Hong return root->Name() == NULL ? "" : root->Name(); 80676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong} 81676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 82676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Honginline std::string getText(NodeType *root) { 83cd41ffc75e885e2b407e4eff3d761d59ffa0d766Yifan Hong return root->GetText() == NULL ? "" : root->GetText(); 84676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong} 85676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 86676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Honginline NodeType *getChild(NodeType *parent, const std::string &name) { 87676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return parent->FirstChildElement(name.c_str()); 88676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong} 89676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 90676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Honginline NodeType *getRootChild(DocType *parent) { 91676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return parent->FirstChildElement(); 92676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong} 93676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 94676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Honginline std::vector<NodeType *> getChildren(NodeType *parent, const std::string &name) { 95676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong std::vector<NodeType *> v; 96676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong for (NodeType *child = parent->FirstChildElement(name.c_str()); 97676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong child != nullptr; 98676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong child = child->NextSiblingElement(name.c_str())) { 99676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong v.push_back(child); 100676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 101676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return v; 102676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong} 103676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 104676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Honginline bool getAttr(NodeType *root, const std::string &attrName, std::string *s) { 105676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong const char *c = root->Attribute(attrName.c_str()); 106676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong if (c == NULL) 107676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return false; 108676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong *s = c; 109676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return true; 110676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong} 111676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 112676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong// --------------- tinyxml2 details end. 113676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 1148e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong// Helper functions for XmlConverter 1158e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hongstatic bool parse(const std::string &attrText, bool *attr) { 1168e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong if (attrText == "true" || attrText == "1") { 1178e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong *attr = true; 1188e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong return true; 1198e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong } 1208e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong if (attrText == "false" || attrText == "0") { 1218e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong *attr = false; 1228e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong return true; 1238e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong } 1248e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong return false; 1258e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong} 1268e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong 127676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong// ---------------------- XmlNodeConverter definitions 128676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 129676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongtemplate<typename Object> 130676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongstruct XmlNodeConverter : public XmlConverter<Object> { 131676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong XmlNodeConverter() {} 132676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong virtual ~XmlNodeConverter() {} 133676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 134676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong // sub-types should implement these. 135676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong virtual void mutateNode(const Object &o, NodeType *n, DocType *d) const = 0; 136676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong virtual bool buildObject(Object *o, NodeType *n) const = 0; 137676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong virtual std::string elementName() const = 0; 138676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 139676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong // convenience methods for user 140676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong inline const std::string &lastError() const { return mLastError; } 141676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong inline NodeType *serialize(const Object &o, DocType *d) const { 142676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong NodeType *root = createNode(this->elementName(), d); 143676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong this->mutateNode(o, root, d); 144676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return root; 145676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 146676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong inline std::string serialize(const Object &o) const { 147676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong DocType *doc = createDocument(); 148676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong appendChild(doc, serialize(o, doc)); 149676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong std::string s = printDocument(doc); 150676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong deleteDocument(doc); 151676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return s; 152676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 153676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong inline bool deserialize(Object *object, NodeType *root) const { 154676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong if (nameOf(root) != this->elementName()) { 155676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return false; 156676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 157676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return this->buildObject(object, root); 158676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 159676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong inline bool deserialize(Object *o, const std::string &xml) const { 160676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong DocType *doc = createDocument(xml); 161685ce898962e83f09c0b7eaf079a6542b71e7f3dYifan Hong if (doc == nullptr) { 162685ce898962e83f09c0b7eaf079a6542b71e7f3dYifan Hong this->mLastError = "Not a valid XML"; 163685ce898962e83f09c0b7eaf079a6542b71e7f3dYifan Hong return false; 164685ce898962e83f09c0b7eaf079a6542b71e7f3dYifan Hong } 165685ce898962e83f09c0b7eaf079a6542b71e7f3dYifan Hong bool ret = deserialize(o, getRootChild(doc)); 166676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong deleteDocument(doc); 167676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return ret; 168676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 169676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong inline NodeType *operator()(const Object &o, DocType *d) const { 170676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return serialize(o, d); 171676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 172676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong inline std::string operator()(const Object &o) const { 173676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return serialize(o); 174676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 175676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong inline bool operator()(Object *o, NodeType *node) const { 176676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return deserialize(o, node); 177676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 178676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong inline bool operator()(Object *o, const std::string &xml) const { 179676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return deserialize(o, xml); 180676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 181676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 182676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong // convenience methods for implementor. 1838e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong 1848e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong // All append* functions helps mutateNode() to serialize the object into XML. 185676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong template <typename T> 186676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong inline void appendAttr(NodeType *e, const std::string &attrName, const T &attr) const { 187676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return appendStrAttr(e, attrName, ::android::vintf::to_string(attr)); 188676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 189676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 190676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong inline void appendAttr(NodeType *e, const std::string &attrName, bool attr) const { 191676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return appendStrAttr(e, attrName, attr ? "true" : "false"); 192676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 193676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 19433466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong // text -> <name>text</name> 19533466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong inline void appendTextElement(NodeType *parent, const std::string &name, 19633466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong const std::string &text, DocType *d) const { 19733466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong NodeType *c = createNode(name, d); 19833466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong appendText(c, text, d); 19933466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong appendChild(parent, c); 20033466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong } 20133466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong 20233466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong // text -> <name>text</name> 20333466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong template<typename Array> 20433466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong inline void appendTextElements(NodeType *parent, const std::string &name, 20533466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong const Array &array, DocType *d) const { 20633466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong for (const std::string &text : array) { 20733466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong NodeType *c = createNode(name, d); 20833466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong appendText(c, text, d); 20933466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong appendChild(parent, c); 21033466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong } 21133466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong } 21233466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong 21333466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong template<typename T, typename Array> 21433466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong inline void appendChildren(NodeType *parent, const XmlNodeConverter<T> &conv, 21533466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong const Array &array, DocType *d) const { 21633466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong for (const T &t : array) { 21733466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong appendChild(parent, conv(t, d)); 21833466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong } 21933466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong } 22033466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong 2218e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong // All parse* functions helps buildObject() to deserialize XML to the object. Returns 2228e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong // true if deserialization is successful, false if any error, and mLastError will be 2238e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong // set to error message. 2248e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong template <typename T> 2258e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong inline bool parseOptionalAttr(NodeType *root, const std::string &attrName, 2268e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong T &&defaultValue, T *attr) const { 2278e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong std::string attrText; 2288e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong bool success = getAttr(root, attrName, &attrText) && 2298e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong ::android::vintf::parse(attrText, attr); 2308e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong if (!success) { 2318e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong *attr = std::move(defaultValue); 2328e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong } 2338e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong return true; 2348e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong } 2358e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong 236676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong template <typename T> 237676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong inline bool parseAttr(NodeType *root, const std::string &attrName, T *attr) const { 238676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong std::string attrText; 239676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong bool ret = getAttr(root, attrName, &attrText) && ::android::vintf::parse(attrText, attr); 240676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong if (!ret) { 2416dbf63f40e00dfd74639c84a3ed4c9284a3ab2c7Yifan Hong mLastError = "Could not find/parse attr with name \"" + attrName + "\" for element <" 2426dbf63f40e00dfd74639c84a3ed4c9284a3ab2c7Yifan Hong + elementName() + ">"; 243676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 244676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return ret; 245676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 246676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 247676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong inline bool parseAttr(NodeType *root, const std::string &attrName, std::string *attr) const { 248676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong bool ret = getAttr(root, attrName, attr); 249676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong if (!ret) { 2506dbf63f40e00dfd74639c84a3ed4c9284a3ab2c7Yifan Hong mLastError = "Could not find attr with name \"" + attrName + "\" for element <" 2516dbf63f40e00dfd74639c84a3ed4c9284a3ab2c7Yifan Hong + elementName() + ">"; 252676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 253676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return ret; 254676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 255676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 256676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong inline bool parseTextElement(NodeType *root, 257676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong const std::string &elementName, std::string *s) const { 258676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong NodeType *child = getChild(root, elementName); 259676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong if (child == nullptr) { 2606dbf63f40e00dfd74639c84a3ed4c9284a3ab2c7Yifan Hong mLastError = "Could not find element with name <" + elementName + "> in element <" 2616dbf63f40e00dfd74639c84a3ed4c9284a3ab2c7Yifan Hong + this->elementName() + ">"; 262676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return false; 263676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 264676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong *s = getText(child); 265676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return true; 266676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 267676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 26833466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong inline bool parseTextElements(NodeType *root, const std::string &elementName, 26933466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong std::vector<std::string> *v) const { 27033466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong auto nodes = getChildren(root, elementName); 27133466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong v->resize(nodes.size()); 27233466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong for (size_t i = 0; i < nodes.size(); ++i) { 27333466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong v->at(i) = getText(nodes[i]); 27433466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong } 27533466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong return true; 27633466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong } 27733466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong 278676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong template <typename T> 279676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong inline bool parseChild(NodeType *root, const XmlNodeConverter<T> &conv, T *t) const { 280676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong NodeType *child = getChild(root, conv.elementName()); 281676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong if (child == nullptr) { 2826dbf63f40e00dfd74639c84a3ed4c9284a3ab2c7Yifan Hong mLastError = "Could not find element with name <" + conv.elementName() + "> in element <" 2836dbf63f40e00dfd74639c84a3ed4c9284a3ab2c7Yifan Hong + this->elementName() + ">"; 284676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return false; 285676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 286676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong bool success = conv.deserialize(t, child); 287676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong if (!success) { 288676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong mLastError = conv.lastError(); 289676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 290676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return success; 291676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 292676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 293676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong template <typename T> 2948e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong inline bool parseOptionalChild(NodeType *root, const XmlNodeConverter<T> &conv, 2958e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong T &&defaultValue, T *t) const { 2968e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong NodeType *child = getChild(root, conv.elementName()); 2978e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong if (child == nullptr) { 2988e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong *t = std::move(defaultValue); 2998e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong return true; 3008e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong } 3018e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong bool success = conv.deserialize(t, child); 3028e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong if (!success) { 3038e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong mLastError = conv.lastError(); 3048e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong } 3058e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong return success; 3068e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong } 3078e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong 3088e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong template <typename T> 309676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong inline bool parseChildren(NodeType *root, const XmlNodeConverter<T> &conv, std::vector<T> *v) const { 310676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong auto nodes = getChildren(root, conv.elementName()); 311676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong v->resize(nodes.size()); 312676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong for (size_t i = 0; i < nodes.size(); ++i) { 313676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong if (!conv.deserialize(&v->at(i), nodes[i])) { 3146dbf63f40e00dfd74639c84a3ed4c9284a3ab2c7Yifan Hong mLastError = "Could not parse element with name <" + conv.elementName() 3156dbf63f40e00dfd74639c84a3ed4c9284a3ab2c7Yifan Hong + "> in element <" + this->elementName() + ">: " + conv.lastError(); 316676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return false; 317676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 318676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 319676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return true; 320676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 321676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 32257b7f0c0360b2603e348ffa5892438754041a95dYifan Hong template <typename T> 32357b7f0c0360b2603e348ffa5892438754041a95dYifan Hong inline bool parseChildren(NodeType *root, const XmlNodeConverter<T> &conv, std::set<T> *s) const { 32457b7f0c0360b2603e348ffa5892438754041a95dYifan Hong std::vector<T> vec; 32557b7f0c0360b2603e348ffa5892438754041a95dYifan Hong if (!parseChildren(root, conv, &vec)) { 32657b7f0c0360b2603e348ffa5892438754041a95dYifan Hong return false; 32757b7f0c0360b2603e348ffa5892438754041a95dYifan Hong } 32857b7f0c0360b2603e348ffa5892438754041a95dYifan Hong s->clear(); 32957b7f0c0360b2603e348ffa5892438754041a95dYifan Hong s->insert(vec.begin(), vec.end()); 33057b7f0c0360b2603e348ffa5892438754041a95dYifan Hong if (s->size() != vec.size()) { 33157b7f0c0360b2603e348ffa5892438754041a95dYifan Hong mLastError = "Duplicated elements <" + conv.elementName() + "> in element <" 33257b7f0c0360b2603e348ffa5892438754041a95dYifan Hong + this->elementName() + ">"; 33357b7f0c0360b2603e348ffa5892438754041a95dYifan Hong s->clear(); 33457b7f0c0360b2603e348ffa5892438754041a95dYifan Hong return false; 33557b7f0c0360b2603e348ffa5892438754041a95dYifan Hong } 33657b7f0c0360b2603e348ffa5892438754041a95dYifan Hong return true; 33757b7f0c0360b2603e348ffa5892438754041a95dYifan Hong } 33857b7f0c0360b2603e348ffa5892438754041a95dYifan Hong 339676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong inline bool parseText(NodeType *node, std::string *s) const { 340676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong *s = getText(node); 341676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return true; 342676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 343676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 344c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hong template <typename T> 345c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hong inline bool parseText(NodeType *node, T *s) const { 3466dbf63f40e00dfd74639c84a3ed4c9284a3ab2c7Yifan Hong std::string text = getText(node); 3476dbf63f40e00dfd74639c84a3ed4c9284a3ab2c7Yifan Hong bool ret = ::android::vintf::parse(text, s); 3486dbf63f40e00dfd74639c84a3ed4c9284a3ab2c7Yifan Hong if (!ret) { 3496dbf63f40e00dfd74639c84a3ed4c9284a3ab2c7Yifan Hong mLastError = "Could not parse text \"" + text + "\" in element <" + elementName() + ">"; 3506dbf63f40e00dfd74639c84a3ed4c9284a3ab2c7Yifan Hong } 3516dbf63f40e00dfd74639c84a3ed4c9284a3ab2c7Yifan Hong return ret; 352c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hong } 353676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongprotected: 354676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong mutable std::string mLastError; 355676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong}; 356676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 357676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongtemplate<typename Object> 358676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongstruct XmlTextConverter : public XmlNodeConverter<Object> { 359676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong XmlTextConverter(const std::string &elementName) 360676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong : mElementName(elementName) {} 361676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 362676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong virtual void mutateNode(const Object &object, NodeType *root, DocType *d) const override { 363676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong appendText(root, ::android::vintf::to_string(object), d); 364676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 365676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong virtual bool buildObject(Object *object, NodeType *root) const override { 3666dbf63f40e00dfd74639c84a3ed4c9284a3ab2c7Yifan Hong return this->parseText(root, object); 367676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 368676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong virtual std::string elementName() const { return mElementName; }; 369676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongprivate: 370676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong std::string mElementName; 371676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong}; 372676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 373676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong// ---------------------- XmlNodeConverter definitions end 374676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 375676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongconst XmlTextConverter<Version> versionConverter{"version"}; 376676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 377676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongconst XmlTextConverter<VersionRange> versionRangeConverter{"version"}; 378676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 3793f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hongconst XmlTextConverter<KernelConfigKey> kernelConfigKeyConverter{"key"}; 3803f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong 381c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hongstruct TransportArchConverter : public XmlNodeConverter<TransportArch> { 382c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hong std::string elementName() const override { return "transport"; } 383c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hong void mutateNode(const TransportArch &object, NodeType *root, DocType *d) const override { 384c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hong if (object.arch != Arch::ARCH_EMPTY) { 385c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hong appendAttr(root, "arch", object.arch); 386c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hong } 387c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hong appendText(root, ::android::vintf::to_string(object.transport), d); 388c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hong } 389c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hong bool buildObject(TransportArch *object, NodeType *root) const override { 390c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hong if (!parseOptionalAttr(root, "arch", Arch::ARCH_EMPTY, &object->arch) || 391c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hong !parseText(root, &object->transport)) { 392c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hong return false; 393c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hong } 394c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hong if (!object->isValid()) { 395c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hong this->mLastError = "transport == " + ::android::vintf::to_string(object->transport) + 396c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hong " and arch == " + ::android::vintf::to_string(object->arch) + 397c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hong " is not a valid combination."; 398c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hong return false; 399c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hong } 400c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hong return true; 401c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hong } 402c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hong}; 403c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hong 404c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hongconst TransportArchConverter transportArchConverter{}; 405c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hong 4063f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hongstruct KernelConfigTypedValueConverter : public XmlNodeConverter<KernelConfigTypedValue> { 4073f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong std::string elementName() const override { return "value"; } 4083f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong void mutateNode(const KernelConfigTypedValue &object, NodeType *root, DocType *d) const override { 4093f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong appendAttr(root, "type", object.mType); 4103f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong appendText(root, ::android::vintf::to_string(object), d); 4113f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong } 4123f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong bool buildObject(KernelConfigTypedValue *object, NodeType *root) const override { 4133f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong std::string stringValue; 4143f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong if (!parseAttr(root, "type", &object->mType) || 4153f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong !parseText(root, &stringValue)) { 4163f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong return false; 4173f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong } 4183f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong if (!::android::vintf::parseKernelConfigValue(stringValue, object)) { 41933466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong this->mLastError = "Could not parse kernel config value \"" + stringValue + "\""; 4203f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong return false; 4213f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong } 4223f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong return true; 4233f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong } 4243f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong}; 4253f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong 4263f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hongconst KernelConfigTypedValueConverter kernelConfigTypedValueConverter{}; 4273f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong 4283f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hongstruct KernelConfigConverter : public XmlNodeConverter<KernelConfig> { 4293f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong std::string elementName() const override { return "config"; } 4303f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong void mutateNode(const KernelConfig &object, NodeType *root, DocType *d) const override { 4313f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong appendChild(root, kernelConfigKeyConverter(object.first, d)); 4323f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong appendChild(root, kernelConfigTypedValueConverter(object.second, d)); 4333f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong } 4343f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong bool buildObject(KernelConfig *object, NodeType *root) const override { 4353f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong if ( !parseChild(root, kernelConfigKeyConverter, &object->first) 4363f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong || !parseChild(root, kernelConfigTypedValueConverter, &object->second)) { 4373f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong return false; 4383f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong } 4393f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong return true; 4403f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong } 4413f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong}; 4423f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong 4433f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hongconst KernelConfigConverter kernelConfigConverter{}; 4443f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong 44596d4649f72786806e4c385817d05a2b921c2f4ecYifan Hongstruct HalInterfaceConverter : public XmlNodeConverter<HalInterface> { 44696d4649f72786806e4c385817d05a2b921c2f4ecYifan Hong std::string elementName() const override { return "interface"; } 44796d4649f72786806e4c385817d05a2b921c2f4ecYifan Hong void mutateNode(const HalInterface &intf, NodeType *root, DocType *d) const override { 44896d4649f72786806e4c385817d05a2b921c2f4ecYifan Hong appendTextElement(root, "name", intf.name, d); 44996d4649f72786806e4c385817d05a2b921c2f4ecYifan Hong appendTextElements(root, "instance", intf.instances, d); 45096d4649f72786806e4c385817d05a2b921c2f4ecYifan Hong } 45196d4649f72786806e4c385817d05a2b921c2f4ecYifan Hong bool buildObject(HalInterface *intf, NodeType *root) const override { 45296d4649f72786806e4c385817d05a2b921c2f4ecYifan Hong std::vector<std::string> instances; 45396d4649f72786806e4c385817d05a2b921c2f4ecYifan Hong if (!parseTextElement(root, "name", &intf->name) || 45496d4649f72786806e4c385817d05a2b921c2f4ecYifan Hong !parseTextElements(root, "instance", &instances)) { 45596d4649f72786806e4c385817d05a2b921c2f4ecYifan Hong return false; 45696d4649f72786806e4c385817d05a2b921c2f4ecYifan Hong } 45796d4649f72786806e4c385817d05a2b921c2f4ecYifan Hong intf->instances.clear(); 45896d4649f72786806e4c385817d05a2b921c2f4ecYifan Hong intf->instances.insert(instances.begin(), instances.end()); 45996d4649f72786806e4c385817d05a2b921c2f4ecYifan Hong if (intf->instances.size() != instances.size()) { 46096d4649f72786806e4c385817d05a2b921c2f4ecYifan Hong this->mLastError = "Duplicated instances in " + intf->name; 46196d4649f72786806e4c385817d05a2b921c2f4ecYifan Hong return false; 46296d4649f72786806e4c385817d05a2b921c2f4ecYifan Hong } 46396d4649f72786806e4c385817d05a2b921c2f4ecYifan Hong return true; 46496d4649f72786806e4c385817d05a2b921c2f4ecYifan Hong } 46596d4649f72786806e4c385817d05a2b921c2f4ecYifan Hong}; 46696d4649f72786806e4c385817d05a2b921c2f4ecYifan Hong 46796d4649f72786806e4c385817d05a2b921c2f4ecYifan Hongconst HalInterfaceConverter halInterfaceConverter{}; 46896d4649f72786806e4c385817d05a2b921c2f4ecYifan Hong 469a9993574bc1fb7a99ebf05cdc69d99cd208b8cf5Yifan Hongstruct MatrixHalConverter : public XmlNodeConverter<MatrixHal> { 470676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong std::string elementName() const override { return "hal"; } 471676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong void mutateNode(const MatrixHal &hal, NodeType *root, DocType *d) const override { 472676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong appendAttr(root, "format", hal.format); 473676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong appendAttr(root, "optional", hal.optional); 474676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong appendTextElement(root, "name", hal.name, d); 47533466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong appendChildren(root, versionRangeConverter, hal.versionRanges, d); 47643e2aaeb4b857cc7a2f55e6aeb5f8ec9bcc63c7dYifan Hong appendChildren(root, halInterfaceConverter, iterateValues(hal.interfaces), d); 477676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 478676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong bool buildObject(MatrixHal *object, NodeType *root) const override { 47943e2aaeb4b857cc7a2f55e6aeb5f8ec9bcc63c7dYifan Hong std::vector<HalInterface> interfaces; 4808e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong if (!parseOptionalAttr(root, "format", HalFormat::HIDL, &object->format) || 4818e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong !parseOptionalAttr(root, "optional", false /* defaultValue */, &object->optional) || 482a70b274227269d2e924a6f570015879c7c9f8f86Yifan Hong !parseTextElement(root, "name", &object->name) || 48343e2aaeb4b857cc7a2f55e6aeb5f8ec9bcc63c7dYifan Hong !parseChildren(root, versionRangeConverter, &object->versionRanges) || 48443e2aaeb4b857cc7a2f55e6aeb5f8ec9bcc63c7dYifan Hong !parseChildren(root, halInterfaceConverter, &interfaces)) { 485676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return false; 486676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 48743e2aaeb4b857cc7a2f55e6aeb5f8ec9bcc63c7dYifan Hong for (auto&& interface : interfaces) { 48843e2aaeb4b857cc7a2f55e6aeb5f8ec9bcc63c7dYifan Hong std::string name{interface.name}; 48943e2aaeb4b857cc7a2f55e6aeb5f8ec9bcc63c7dYifan Hong auto res = object->interfaces.emplace(std::move(name), std::move(interface)); 49043e2aaeb4b857cc7a2f55e6aeb5f8ec9bcc63c7dYifan Hong if (!res.second) { 49143e2aaeb4b857cc7a2f55e6aeb5f8ec9bcc63c7dYifan Hong this->mLastError = "Duplicated instance entry " + res.first->first; 49243e2aaeb4b857cc7a2f55e6aeb5f8ec9bcc63c7dYifan Hong return false; 49343e2aaeb4b857cc7a2f55e6aeb5f8ec9bcc63c7dYifan Hong } 49443e2aaeb4b857cc7a2f55e6aeb5f8ec9bcc63c7dYifan Hong } 495676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return true; 496676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 497676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong}; 498676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 499676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongconst MatrixHalConverter matrixHalConverter{}; 500676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 501a9993574bc1fb7a99ebf05cdc69d99cd208b8cf5Yifan Hongstruct MatrixKernelConverter : public XmlNodeConverter<MatrixKernel> { 502676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong std::string elementName() const override { return "kernel"; } 503676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong void mutateNode(const MatrixKernel &kernel, NodeType *root, DocType *d) const override { 504c3066898a725859cc2a6d4c0d3dce88284807e76Yifan Hong appendAttr(root, "version", kernel.mMinLts); 50533466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong appendChildren(root, kernelConfigConverter, kernel.mConfigs, d); 506676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 507676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong bool buildObject(MatrixKernel *object, NodeType *root) const override { 508c3066898a725859cc2a6d4c0d3dce88284807e76Yifan Hong if (!parseAttr(root, "version", &object->mMinLts) || 509a70b274227269d2e924a6f570015879c7c9f8f86Yifan Hong !parseChildren(root, kernelConfigConverter, &object->mConfigs)) { 5103f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong return false; 5113f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong } 512676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return true; 513676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 514676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong}; 515676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 516676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongconst MatrixKernelConverter matrixKernelConverter{}; 517676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 518a9993574bc1fb7a99ebf05cdc69d99cd208b8cf5Yifan Hongstruct ManifestHalConverter : public XmlNodeConverter<ManifestHal> { 519676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong std::string elementName() const override { return "hal"; } 520676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong void mutateNode(const ManifestHal &hal, NodeType *root, DocType *d) const override { 521676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong appendAttr(root, "format", hal.format); 522676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong appendTextElement(root, "name", hal.name, d); 523c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hong if (!hal.transportArch.empty()) { 524c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hong appendChild(root, transportArchConverter(hal.transportArch, d)); 525c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hong } 52633466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong appendChildren(root, versionConverter, hal.versions, d); 52796d4649f72786806e4c385817d05a2b921c2f4ecYifan Hong appendChildren(root, halInterfaceConverter, iterateValues(hal.interfaces), d); 528676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 529676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong bool buildObject(ManifestHal *object, NodeType *root) const override { 53096d4649f72786806e4c385817d05a2b921c2f4ecYifan Hong std::vector<HalInterface> interfaces; 5318e9c669c47a9b59bc49d5c95922c17f1d75a6620Yifan Hong if (!parseOptionalAttr(root, "format", HalFormat::HIDL, &object->format) || 532a70b274227269d2e924a6f570015879c7c9f8f86Yifan Hong !parseTextElement(root, "name", &object->name) || 533c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hong !parseChild(root, transportArchConverter, &object->transportArch) || 534ec3b9b7cf729c8cc47421dcc316d7b2d1f37c2ffYifan Hong !parseChildren(root, versionConverter, &object->versions) || 53596d4649f72786806e4c385817d05a2b921c2f4ecYifan Hong !parseChildren(root, halInterfaceConverter, &interfaces)) { 536676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return false; 537676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 538ec3b9b7cf729c8cc47421dcc316d7b2d1f37c2ffYifan Hong object->interfaces.clear(); 539ec3b9b7cf729c8cc47421dcc316d7b2d1f37c2ffYifan Hong for (auto &&interface : interfaces) { 540ec3b9b7cf729c8cc47421dcc316d7b2d1f37c2ffYifan Hong auto res = object->interfaces.emplace(interface.name, 541ec3b9b7cf729c8cc47421dcc316d7b2d1f37c2ffYifan Hong std::move(interface)); 542ec3b9b7cf729c8cc47421dcc316d7b2d1f37c2ffYifan Hong if (!res.second) { 543ec3b9b7cf729c8cc47421dcc316d7b2d1f37c2ffYifan Hong this->mLastError = "Duplicated instance entry " + res.first->first; 544ec3b9b7cf729c8cc47421dcc316d7b2d1f37c2ffYifan Hong return false; 545ec3b9b7cf729c8cc47421dcc316d7b2d1f37c2ffYifan Hong } 546ec3b9b7cf729c8cc47421dcc316d7b2d1f37c2ffYifan Hong } 547c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hong if (!object->isValid()) { 548c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hong this->mLastError = "'" + object->name + "' is not a valid Manifest HAL."; 549c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hong return false; 550c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hong } 551c54d32cb0b20308a0ecea7864016a2a5dc512f71Yifan Hong return true; 552676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 553676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong}; 554676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 5554a5eb7ba6b9474aec95c3aa79a606f0b7a6b31b2Yifan Hong// Convert ManifestHal from and to XML. Returned object is guaranteed to have 5564a5eb7ba6b9474aec95c3aa79a606f0b7a6b31b2Yifan Hong// .isValid() == true. 557676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongconst ManifestHalConverter manifestHalConverter{}; 558676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 559558380a7b95de37f6c74de683102f78e97e4fbf0Yifan Hongconst XmlTextConverter<KernelSepolicyVersion> kernelSepolicyVersionConverter{"kernel-sepolicy-version"}; 5603916619e525f6aed4a3ef93881452157ce12d76eYifan Hongconst XmlTextConverter<VersionRange> sepolicyVersionConverter{"sepolicy-version"}; 561558380a7b95de37f6c74de683102f78e97e4fbf0Yifan Hong 562a9993574bc1fb7a99ebf05cdc69d99cd208b8cf5Yifan Hongstruct SepolicyConverter : public XmlNodeConverter<Sepolicy> { 563676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong std::string elementName() const override { return "sepolicy"; } 564558380a7b95de37f6c74de683102f78e97e4fbf0Yifan Hong void mutateNode(const Sepolicy &object, NodeType *root, DocType *d) const override { 565558380a7b95de37f6c74de683102f78e97e4fbf0Yifan Hong appendChild(root, kernelSepolicyVersionConverter(object.kernelSepolicyVersion(), d)); 5663916619e525f6aed4a3ef93881452157ce12d76eYifan Hong appendChildren(root, sepolicyVersionConverter, object.sepolicyVersions(), d); 567676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 568558380a7b95de37f6c74de683102f78e97e4fbf0Yifan Hong bool buildObject(Sepolicy *object, NodeType *root) const override { 569558380a7b95de37f6c74de683102f78e97e4fbf0Yifan Hong if (!parseChild(root, kernelSepolicyVersionConverter, &object->mKernelSepolicyVersion) || 5703916619e525f6aed4a3ef93881452157ce12d76eYifan Hong !parseChildren(root, sepolicyVersionConverter, &object->mSepolicyVersionRanges)) { 571558380a7b95de37f6c74de683102f78e97e4fbf0Yifan Hong return false; 572558380a7b95de37f6c74de683102f78e97e4fbf0Yifan Hong } 573676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return true; 574676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 575676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong}; 576676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongconst SepolicyConverter sepolicyConverter{}; 577676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 57857b7f0c0360b2603e348ffa5892438754041a95dYifan Hongconst XmlTextConverter<VndkVersionRange> vndkVersionRangeConverter{"version"}; 57957b7f0c0360b2603e348ffa5892438754041a95dYifan Hongconst XmlTextConverter<std::string> vndkLibraryConverter{"library"}; 58057b7f0c0360b2603e348ffa5892438754041a95dYifan Hong 58157b7f0c0360b2603e348ffa5892438754041a95dYifan Hongstruct VndkConverter : public XmlNodeConverter<Vndk> { 58257b7f0c0360b2603e348ffa5892438754041a95dYifan Hong std::string elementName() const override { return "vndk"; } 58357b7f0c0360b2603e348ffa5892438754041a95dYifan Hong void mutateNode(const Vndk &object, NodeType *root, DocType *d) const override { 58457b7f0c0360b2603e348ffa5892438754041a95dYifan Hong appendChild(root, vndkVersionRangeConverter(object.mVersionRange, d)); 58557b7f0c0360b2603e348ffa5892438754041a95dYifan Hong appendChildren(root, vndkLibraryConverter, object.mLibraries, d); 58657b7f0c0360b2603e348ffa5892438754041a95dYifan Hong } 58757b7f0c0360b2603e348ffa5892438754041a95dYifan Hong bool buildObject(Vndk *object, NodeType *root) const override { 58857b7f0c0360b2603e348ffa5892438754041a95dYifan Hong if (!parseChild(root, vndkVersionRangeConverter, &object->mVersionRange) || 58957b7f0c0360b2603e348ffa5892438754041a95dYifan Hong !parseChildren(root, vndkLibraryConverter, &object->mLibraries)) { 59057b7f0c0360b2603e348ffa5892438754041a95dYifan Hong return false; 59157b7f0c0360b2603e348ffa5892438754041a95dYifan Hong } 59257b7f0c0360b2603e348ffa5892438754041a95dYifan Hong return true; 59357b7f0c0360b2603e348ffa5892438754041a95dYifan Hong } 59457b7f0c0360b2603e348ffa5892438754041a95dYifan Hong}; 59557b7f0c0360b2603e348ffa5892438754041a95dYifan Hong 59657b7f0c0360b2603e348ffa5892438754041a95dYifan Hongconst VndkConverter vndkConverter{}; 59757b7f0c0360b2603e348ffa5892438754041a95dYifan Hong 598d19539c0858b168e6417a7eb88c1f47a388652f2Yifan Hongstruct HalManifestSepolicyConverter : public XmlNodeConverter<Version> { 599d19539c0858b168e6417a7eb88c1f47a388652f2Yifan Hong std::string elementName() const override { return "sepolicy"; } 600d19539c0858b168e6417a7eb88c1f47a388652f2Yifan Hong void mutateNode(const Version &m, NodeType *root, DocType *d) const override { 601d19539c0858b168e6417a7eb88c1f47a388652f2Yifan Hong appendChild(root, versionConverter(m, d)); 602d19539c0858b168e6417a7eb88c1f47a388652f2Yifan Hong } 603d19539c0858b168e6417a7eb88c1f47a388652f2Yifan Hong bool buildObject(Version *object, NodeType *root) const override { 604d19539c0858b168e6417a7eb88c1f47a388652f2Yifan Hong return parseChild(root, versionConverter, object); 605d19539c0858b168e6417a7eb88c1f47a388652f2Yifan Hong } 606d19539c0858b168e6417a7eb88c1f47a388652f2Yifan Hong}; 607d19539c0858b168e6417a7eb88c1f47a388652f2Yifan Hongconst HalManifestSepolicyConverter halManifestSepolicyConverter{}; 608d19539c0858b168e6417a7eb88c1f47a388652f2Yifan Hong 609d2b7e64894cd739da60f129ac38d0cf035238206Yifan Hongstruct HalManifestConverter : public XmlNodeConverter<HalManifest> { 610676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong std::string elementName() const override { return "manifest"; } 611d2b7e64894cd739da60f129ac38d0cf035238206Yifan Hong void mutateNode(const HalManifest &m, NodeType *root, DocType *d) const override { 612d2b7e64894cd739da60f129ac38d0cf035238206Yifan Hong appendAttr(root, "version", HalManifest::kVersion); 613f3a68574718c38ef9445f1cf49104a6130c5b23aYifan Hong appendAttr(root, "type", m.mType); 61433466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong appendChildren(root, manifestHalConverter, m.getHals(), d); 615d19539c0858b168e6417a7eb88c1f47a388652f2Yifan Hong if (m.mType == SchemaType::DEVICE) { 616d19539c0858b168e6417a7eb88c1f47a388652f2Yifan Hong appendChild(root, halManifestSepolicyConverter(m.device.mSepolicyVersion, d)); 61757b7f0c0360b2603e348ffa5892438754041a95dYifan Hong } else if (m.mType == SchemaType::FRAMEWORK) { 61857b7f0c0360b2603e348ffa5892438754041a95dYifan Hong appendChildren(root, vndkConverter, m.framework.mVndks, d); 619d19539c0858b168e6417a7eb88c1f47a388652f2Yifan Hong } 620676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 621d2b7e64894cd739da60f129ac38d0cf035238206Yifan Hong bool buildObject(HalManifest *object, NodeType *root) const override { 622f3a68574718c38ef9445f1cf49104a6130c5b23aYifan Hong Version version; 623676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong std::vector<ManifestHal> hals; 624f3a68574718c38ef9445f1cf49104a6130c5b23aYifan Hong if (!parseAttr(root, "version", &version) || 625f3a68574718c38ef9445f1cf49104a6130c5b23aYifan Hong !parseAttr(root, "type", &object->mType) || 626f3a68574718c38ef9445f1cf49104a6130c5b23aYifan Hong !parseChildren(root, manifestHalConverter, &hals)) { 627f3a68574718c38ef9445f1cf49104a6130c5b23aYifan Hong return false; 628f3a68574718c38ef9445f1cf49104a6130c5b23aYifan Hong } 629f3a68574718c38ef9445f1cf49104a6130c5b23aYifan Hong if (version != HalManifest::kVersion) { 630f3a68574718c38ef9445f1cf49104a6130c5b23aYifan Hong this->mLastError = "Unrecognized manifest.version"; 631676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return false; 632676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 633d19539c0858b168e6417a7eb88c1f47a388652f2Yifan Hong if (object->mType == SchemaType::DEVICE) { 634d19539c0858b168e6417a7eb88c1f47a388652f2Yifan Hong // tags for device hal manifest only. 635d73ef5d7f1b48adf07a9b09c4ef89ba79f5fa166Yifan Hong // <sepolicy> can be missing because it can be determined at build time, not hard-coded 636d73ef5d7f1b48adf07a9b09c4ef89ba79f5fa166Yifan Hong // in the XML file. 637d19539c0858b168e6417a7eb88c1f47a388652f2Yifan Hong if (!parseOptionalChild(root, halManifestSepolicyConverter, {}, 638d19539c0858b168e6417a7eb88c1f47a388652f2Yifan Hong &object->device.mSepolicyVersion)) { 639d19539c0858b168e6417a7eb88c1f47a388652f2Yifan Hong return false; 640d19539c0858b168e6417a7eb88c1f47a388652f2Yifan Hong } 64157b7f0c0360b2603e348ffa5892438754041a95dYifan Hong } else if (object->mType == SchemaType::FRAMEWORK) { 64257b7f0c0360b2603e348ffa5892438754041a95dYifan Hong if (!parseChildren(root, vndkConverter, &object->framework.mVndks)) { 64357b7f0c0360b2603e348ffa5892438754041a95dYifan Hong return false; 64457b7f0c0360b2603e348ffa5892438754041a95dYifan Hong } 64557b7f0c0360b2603e348ffa5892438754041a95dYifan Hong for (const auto &vndk : object->framework.mVndks) { 64657b7f0c0360b2603e348ffa5892438754041a95dYifan Hong if (!vndk.mVersionRange.isSingleVersion()) { 64757b7f0c0360b2603e348ffa5892438754041a95dYifan Hong this->mLastError = "vndk.version " + to_string(vndk.mVersionRange) 64857b7f0c0360b2603e348ffa5892438754041a95dYifan Hong + " cannot be a range for manifests"; 64957b7f0c0360b2603e348ffa5892438754041a95dYifan Hong return false; 65057b7f0c0360b2603e348ffa5892438754041a95dYifan Hong } 65157b7f0c0360b2603e348ffa5892438754041a95dYifan Hong } 652d19539c0858b168e6417a7eb88c1f47a388652f2Yifan Hong } 653676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong for (auto &&hal : hals) { 65413d12186a0c49a10bff1dc47c3fe0437fcfa1f67Yifan Hong std::string description{hal.name}; 65533466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong if (!object->add(std::move(hal))) { 65613d12186a0c49a10bff1dc47c3fe0437fcfa1f67Yifan Hong this->mLastError = "Duplicated manifest.hal entry " + description; 65733466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong return false; 65833466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong } 659676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 660676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return true; 661676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 662676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong}; 663676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 664d2b7e64894cd739da60f129ac38d0cf035238206Yifan Hongconst HalManifestConverter halManifestConverter{}; 665676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 666dc145b385fc9d369335d8176ff6b504b6c37f219Yifan Hongconst XmlTextConverter<Version> avbVersionConverter{"vbmeta-version"}; 667dc145b385fc9d369335d8176ff6b504b6c37f219Yifan Hongstruct AvbConverter : public XmlNodeConverter<Version> { 668dc145b385fc9d369335d8176ff6b504b6c37f219Yifan Hong std::string elementName() const override { return "avb"; } 669dc145b385fc9d369335d8176ff6b504b6c37f219Yifan Hong void mutateNode(const Version &m, NodeType *root, DocType *d) const override { 670dc145b385fc9d369335d8176ff6b504b6c37f219Yifan Hong appendChild(root, avbVersionConverter(m, d)); 671dc145b385fc9d369335d8176ff6b504b6c37f219Yifan Hong } 672dc145b385fc9d369335d8176ff6b504b6c37f219Yifan Hong bool buildObject(Version *object, NodeType *root) const override { 673dc145b385fc9d369335d8176ff6b504b6c37f219Yifan Hong return parseChild(root, avbVersionConverter, object); 674dc145b385fc9d369335d8176ff6b504b6c37f219Yifan Hong } 675dc145b385fc9d369335d8176ff6b504b6c37f219Yifan Hong}; 676dc145b385fc9d369335d8176ff6b504b6c37f219Yifan Hongconst AvbConverter avbConverter{}; 677dc145b385fc9d369335d8176ff6b504b6c37f219Yifan Hong 678a9993574bc1fb7a99ebf05cdc69d99cd208b8cf5Yifan Hongstruct CompatibilityMatrixConverter : public XmlNodeConverter<CompatibilityMatrix> { 679676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong std::string elementName() const override { return "compatibility-matrix"; } 680676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong void mutateNode(const CompatibilityMatrix &m, NodeType *root, DocType *d) const override { 681676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong appendAttr(root, "version", CompatibilityMatrix::kVersion); 682f3a68574718c38ef9445f1cf49104a6130c5b23aYifan Hong appendAttr(root, "type", m.mType); 68333466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong appendChildren(root, matrixHalConverter, iterateValues(m.mHals), d); 684f3a68574718c38ef9445f1cf49104a6130c5b23aYifan Hong if (m.mType == SchemaType::FRAMEWORK) { 685f3a68574718c38ef9445f1cf49104a6130c5b23aYifan Hong appendChildren(root, matrixKernelConverter, m.framework.mKernels, d); 686f3a68574718c38ef9445f1cf49104a6130c5b23aYifan Hong appendChild(root, sepolicyConverter(m.framework.mSepolicy, d)); 687dc145b385fc9d369335d8176ff6b504b6c37f219Yifan Hong appendChild(root, avbConverter(m.framework.mAvbMetaVersion, d)); 688d32fafa76e3b9661dfa81c266a64b8d46f95af20Yifan Hong } else if (m.mType == SchemaType::DEVICE) { 689d32fafa76e3b9661dfa81c266a64b8d46f95af20Yifan Hong appendChild(root, vndkConverter(m.device.mVndk, d)); 690f3a68574718c38ef9445f1cf49104a6130c5b23aYifan Hong } 691676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 692676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong bool buildObject(CompatibilityMatrix *object, NodeType *root) const override { 693f3a68574718c38ef9445f1cf49104a6130c5b23aYifan Hong Version version; 694676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong std::vector<MatrixHal> hals; 695f3a68574718c38ef9445f1cf49104a6130c5b23aYifan Hong if (!parseAttr(root, "version", &version) || 696f3a68574718c38ef9445f1cf49104a6130c5b23aYifan Hong !parseAttr(root, "type", &object->mType) || 697f3a68574718c38ef9445f1cf49104a6130c5b23aYifan Hong !parseChildren(root, matrixHalConverter, &hals)) { 698f3a68574718c38ef9445f1cf49104a6130c5b23aYifan Hong return false; 699f3a68574718c38ef9445f1cf49104a6130c5b23aYifan Hong } 700f3a68574718c38ef9445f1cf49104a6130c5b23aYifan Hong 701f3a68574718c38ef9445f1cf49104a6130c5b23aYifan Hong if (object->mType == SchemaType::FRAMEWORK) { 7022272bf856d9c6a55c7faf81408e0e808664569f3Yifan Hong // <avb> and <sepolicy> can be missing because it can be determined at build time, not 7032272bf856d9c6a55c7faf81408e0e808664569f3Yifan Hong // hard-coded in the XML file. 704f3a68574718c38ef9445f1cf49104a6130c5b23aYifan Hong if (!parseChildren(root, matrixKernelConverter, &object->framework.mKernels) || 7052272bf856d9c6a55c7faf81408e0e808664569f3Yifan Hong !parseOptionalChild(root, sepolicyConverter, {}, &object->framework.mSepolicy) || 706a34a71c7176a5e95c71d6934731b7eeb2ff6c573Yifan Hong !parseOptionalChild(root, avbConverter, {}, &object->framework.mAvbMetaVersion)) { 707f3a68574718c38ef9445f1cf49104a6130c5b23aYifan Hong return false; 708f3a68574718c38ef9445f1cf49104a6130c5b23aYifan Hong } 70957b7f0c0360b2603e348ffa5892438754041a95dYifan Hong } else if (object->mType == SchemaType::DEVICE) { 7103740ba7aafa6e309c3b307ff0c6616335b3ffb61Yifan Hong // <vndk> can be missing because it can be determined at build time, not hard-coded 7113740ba7aafa6e309c3b307ff0c6616335b3ffb61Yifan Hong // in the XML file. 7123740ba7aafa6e309c3b307ff0c6616335b3ffb61Yifan Hong if (!parseOptionalChild(root, vndkConverter, {}, &object->device.mVndk)) { 71357b7f0c0360b2603e348ffa5892438754041a95dYifan Hong return false; 71457b7f0c0360b2603e348ffa5892438754041a95dYifan Hong } 715f3a68574718c38ef9445f1cf49104a6130c5b23aYifan Hong } 716f3a68574718c38ef9445f1cf49104a6130c5b23aYifan Hong 717f3a68574718c38ef9445f1cf49104a6130c5b23aYifan Hong if (version != CompatibilityMatrix::kVersion) { 718f3a68574718c38ef9445f1cf49104a6130c5b23aYifan Hong this->mLastError = "Unrecognized compatibility-matrix.version"; 719676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return false; 720676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 721676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong for (auto &&hal : hals) { 72233466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong if (!object->add(std::move(hal))) { 72333466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong this->mLastError = "Duplicated compatibility-matrix.hal entry"; 72433466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong return false; 72533466ad37b05f0da75b4b22a2d3f342f60ebfbc6Yifan Hong } 726676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 727676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong return true; 728676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong } 729676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong}; 730676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 731676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongconst CompatibilityMatrixConverter compatibilityMatrixConverter{}; 7324a5eb7ba6b9474aec95c3aa79a606f0b7a6b31b2Yifan Hong 7334a5eb7ba6b9474aec95c3aa79a606f0b7a6b31b2Yifan Hong// Publicly available as in parse_xml.h 734d2b7e64894cd739da60f129ac38d0cf035238206Yifan Hongconst XmlConverter<HalManifest> &gHalManifestConverter = halManifestConverter; 735676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongconst XmlConverter<CompatibilityMatrix> &gCompatibilityMatrixConverter 736676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong = compatibilityMatrixConverter; 737676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong 7384a5eb7ba6b9474aec95c3aa79a606f0b7a6b31b2Yifan Hong// For testing in LibVintfTest 7394a5eb7ba6b9474aec95c3aa79a606f0b7a6b31b2Yifan Hongconst XmlConverter<Version> &gVersionConverter = versionConverter; 7404a5eb7ba6b9474aec95c3aa79a606f0b7a6b31b2Yifan Hongconst XmlConverter<KernelConfigTypedValue> &gKernelConfigTypedValueConverter 7414a5eb7ba6b9474aec95c3aa79a606f0b7a6b31b2Yifan Hong = kernelConfigTypedValueConverter; 7424a5eb7ba6b9474aec95c3aa79a606f0b7a6b31b2Yifan Hongconst XmlConverter<MatrixHal> &gMatrixHalConverter = matrixHalConverter; 743037f12a8b5cabf45a8f69f41e886f017b33ce21eYifan Hongconst XmlConverter<ManifestHal> &gManifestHalConverter = manifestHalConverter; 7444a5eb7ba6b9474aec95c3aa79a606f0b7a6b31b2Yifan Hong 745676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong} // namespace vintf 746676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong} // namespace android 747