parse_xml.cpp revision 558380a7b95de37f6c74de683102f78e97e4fbf0
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 Hong// text -> <name>text</name>
79676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Honginline void appendTextElement(NodeType *parent, const std::string &name,
80676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            const std::string &text, DocType *d) {
81676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    NodeType *c = createNode(name, d);
82676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    appendText(c, text, d);
83676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    appendChild(parent, c);
84676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong}
85676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
86676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Honginline std::string nameOf(NodeType *root) {
87cd41ffc75e885e2b407e4eff3d761d59ffa0d766Yifan Hong    return root->Name() == NULL ? "" : root->Name();
88676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong}
89676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
90676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Honginline std::string getText(NodeType *root) {
91cd41ffc75e885e2b407e4eff3d761d59ffa0d766Yifan Hong    return root->GetText() == NULL ? "" : root->GetText();
92676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong}
93676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
94676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Honginline NodeType *getChild(NodeType *parent, const std::string &name) {
95676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    return parent->FirstChildElement(name.c_str());
96676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong}
97676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
98676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Honginline NodeType *getRootChild(DocType *parent) {
99676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    return parent->FirstChildElement();
100676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong}
101676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
102676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Honginline std::vector<NodeType *> getChildren(NodeType *parent, const std::string &name) {
103676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    std::vector<NodeType *> v;
104676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    for (NodeType *child = parent->FirstChildElement(name.c_str());
105676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong         child != nullptr;
106676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong         child = child->NextSiblingElement(name.c_str())) {
107676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        v.push_back(child);
108676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    }
109676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    return v;
110676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong}
111676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
112676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Honginline bool getAttr(NodeType *root, const std::string &attrName, std::string *s) {
113676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    const char *c = root->Attribute(attrName.c_str());
114676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    if (c == NULL)
115676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        return false;
116676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    *s = c;
117676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    return true;
118676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong}
119676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
120676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong// --------------- tinyxml2 details end.
121676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
122676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong// ---------------------- XmlNodeConverter definitions
123676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
124676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongtemplate<typename Object>
125676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongstruct XmlNodeConverter : public XmlConverter<Object> {
126676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    XmlNodeConverter() {}
127676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    virtual ~XmlNodeConverter() {}
128676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
129676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    // sub-types should implement these.
130676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    virtual void mutateNode(const Object &o, NodeType *n, DocType *d) const = 0;
131676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    virtual bool buildObject(Object *o, NodeType *n) const = 0;
132676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    virtual std::string elementName() const = 0;
133676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
134676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    // convenience methods for user
135676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    inline const std::string &lastError() const { return mLastError; }
136676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    inline NodeType *serialize(const Object &o, DocType *d) const {
137676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        NodeType *root = createNode(this->elementName(), d);
138676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        this->mutateNode(o, root, d);
139676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        return root;
140676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    }
141676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    inline std::string serialize(const Object &o) const {
142676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        DocType *doc = createDocument();
143676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        appendChild(doc, serialize(o, doc));
144676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        std::string s = printDocument(doc);
145676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        deleteDocument(doc);
146676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        return s;
147676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    }
148676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    inline bool deserialize(Object *object, NodeType *root) const {
149676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        if (nameOf(root) != this->elementName()) {
150676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            return false;
151676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        }
152676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        return this->buildObject(object, root);
153676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    }
154676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    inline bool deserialize(Object *o, const std::string &xml) const {
155676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        DocType *doc = createDocument(xml);
156676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        bool ret = doc != nullptr
157676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            && deserialize(o, getRootChild(doc));
158676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        deleteDocument(doc);
159676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        return ret;
160676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    }
161676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    inline NodeType *operator()(const Object &o, DocType *d) const {
162676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        return serialize(o, d);
163676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    }
164676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    inline std::string operator()(const Object &o) const {
165676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        return serialize(o);
166676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    }
167676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    inline bool operator()(Object *o, NodeType *node) const {
168676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        return deserialize(o, node);
169676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    }
170676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    inline bool operator()(Object *o, const std::string &xml) const {
171676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        return deserialize(o, xml);
172676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    }
173676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
174676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    // convenience methods for implementor.
175676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    template <typename T>
176676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    inline void appendAttr(NodeType *e, const std::string &attrName, const T &attr) const {
177676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        return appendStrAttr(e, attrName, ::android::vintf::to_string(attr));
178676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    }
179676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
180676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    inline void appendAttr(NodeType *e, const std::string &attrName, bool attr) const {
181676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        return appendStrAttr(e, attrName, attr ? "true" : "false");
182676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    }
183676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
184676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    template <typename T>
185676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    inline bool parseAttr(NodeType *root, const std::string &attrName, T *attr) const {
186676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        std::string attrText;
187676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        bool ret = getAttr(root, attrName, &attrText) && ::android::vintf::parse(attrText, attr);
188676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        if (!ret) {
189676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            mLastError = "Could not parse attr with name " + attrName;
190676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        }
191676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        return ret;
192676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    }
193676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
194676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    inline bool parseAttr(NodeType *root, const std::string &attrName, std::string *attr) const {
195676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        bool ret = getAttr(root, attrName, attr);
196676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        if (!ret) {
197676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            mLastError = "Could not find attr with name " + attrName;
198676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        }
199676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        return ret;
200676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    }
201676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
202676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    inline bool parseAttr(NodeType *root, const std::string &attrName, bool *attr) const {
203676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        std::string attrText;
204676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        if (!getAttr(root, attrName, &attrText)) {
205676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            mLastError = "Could not find attr with name " + attrName;
206676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            return false;
207676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        }
208676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        if (attrText == "true" || attrText == "1") {
209676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            *attr = true;
210676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            return true;
211676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        }
212676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        if (attrText == "false" || attrText == "0") {
213676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            *attr = false;
214676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            return true;
215676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        }
216676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        mLastError = "Could not parse attr with name \"" + attrName
217676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong                + "\" and value \"" + attrText + "\"";
218676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        return false;
219676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    }
220676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
221676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    inline bool parseTextElement(NodeType *root,
222676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            const std::string &elementName, std::string *s) const {
223676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        NodeType *child = getChild(root, elementName);
224676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        if (child == nullptr) {
225676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            mLastError = "Could not find element with name " + elementName;
226676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            return false;
227676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        }
228676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        *s = getText(child);
229676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        return true;
230676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    }
231676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
232676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    template <typename T>
233676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    inline bool parseChild(NodeType *root, const XmlNodeConverter<T> &conv, T *t) const {
234676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        NodeType *child = getChild(root, conv.elementName());
235676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        if (child == nullptr) {
236676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            mLastError = "Could not find element with name " + conv.elementName();
237676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            return false;
238676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        }
239676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        bool success = conv.deserialize(t, child);
240676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        if (!success) {
241676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            mLastError = conv.lastError();
242676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        }
243676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        return success;
244676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    }
245676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
246676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    template <typename T>
247676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    inline bool parseChildren(NodeType *root, const XmlNodeConverter<T> &conv, std::vector<T> *v) const {
248676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        auto nodes = getChildren(root, conv.elementName());
249676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        v->resize(nodes.size());
250676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        for (size_t i = 0; i < nodes.size(); ++i) {
251676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            if (!conv.deserialize(&v->at(i), nodes[i])) {
252676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong                mLastError = "Could not parse element with name " + conv.elementName();
253676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong                return false;
254676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            }
255676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        }
256676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        return true;
257676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    }
258676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
259676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    inline bool parseText(NodeType *node, std::string *s) const {
260676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        *s = getText(node);
261676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        return true;
262676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    }
263676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
264676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongprotected:
265676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    mutable std::string mLastError;
266676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong};
267676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
268676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongtemplate<typename Object>
269676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongstruct XmlTextConverter : public XmlNodeConverter<Object> {
270676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    XmlTextConverter(const std::string &elementName)
271676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        : mElementName(elementName) {}
272676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
273676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    virtual void mutateNode(const Object &object, NodeType *root, DocType *d) const override {
274676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        appendText(root, ::android::vintf::to_string(object), d);
275676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    }
276676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    virtual bool buildObject(Object *object, NodeType *root) const override {
277676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        std::string text = getText(root);
278676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        bool ret = ::android::vintf::parse(text, object);
279676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        if (!ret) {
280676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            this->mLastError = "Could not parse " + text;
281676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        }
282676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        return ret;
283676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    }
284676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    virtual std::string elementName() const { return mElementName; };
285676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongprivate:
286676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    std::string mElementName;
287676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong};
288676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
289676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong// ---------------------- XmlNodeConverter definitions end
290676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
291676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongconst XmlTextConverter<Version> versionConverter{"version"};
292676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongconst XmlConverter<Version> &gVersionConverter = versionConverter;
293676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
294676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongconst XmlTextConverter<VersionRange> versionRangeConverter{"version"};
295676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongconst XmlConverter<VersionRange> &gVersionRangeConverter = versionRangeConverter;
296676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
297676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongconst XmlTextConverter<Transport> transportConverter{"transport"};
298676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongconst XmlConverter<Transport> &gTransportConverter = transportConverter;
299676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
3003f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hongconst XmlTextConverter<KernelConfigKey> kernelConfigKeyConverter{"key"};
3013f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong
3023f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hongstruct KernelConfigTypedValueConverter : public XmlNodeConverter<KernelConfigTypedValue> {
3033f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong    std::string elementName() const override { return "value"; }
3043f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong    void mutateNode(const KernelConfigTypedValue &object, NodeType *root, DocType *d) const override {
3053f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong        appendAttr(root, "type", object.mType);
3063f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong        appendText(root, ::android::vintf::to_string(object), d);
3073f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong    }
3083f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong    bool buildObject(KernelConfigTypedValue *object, NodeType *root) const override {
3093f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong        std::string stringValue;
3103f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong        if (!parseAttr(root, "type", &object->mType) ||
3113f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong            !parseText(root, &stringValue)) {
3123f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong            return false;
3133f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong        }
3143f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong        if (!::android::vintf::parseKernelConfigValue(stringValue, object)) {
3153f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong            return false;
3163f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong        }
3173f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong        return true;
3183f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong    }
3193f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong};
3203f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong
3213f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hongconst KernelConfigTypedValueConverter kernelConfigTypedValueConverter{};
3223f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hongconst XmlConverter<KernelConfigTypedValue> &gKernelConfigTypedValueConverter = kernelConfigTypedValueConverter;
3233f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong
3243f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hongstruct KernelConfigConverter : public XmlNodeConverter<KernelConfig> {
3253f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong    std::string elementName() const override { return "config"; }
3263f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong    void mutateNode(const KernelConfig &object, NodeType *root, DocType *d) const override {
3273f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong        appendChild(root, kernelConfigKeyConverter(object.first, d));
3283f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong        appendChild(root, kernelConfigTypedValueConverter(object.second, d));
3293f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong    }
3303f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong    bool buildObject(KernelConfig *object, NodeType *root) const override {
3313f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong        if (   !parseChild(root, kernelConfigKeyConverter, &object->first)
3323f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong            || !parseChild(root, kernelConfigTypedValueConverter, &object->second)) {
3333f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong            return false;
3343f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong        }
3353f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong        return true;
3363f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong    }
3373f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong};
3383f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong
3393f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hongconst KernelConfigConverter kernelConfigConverter{};
3403f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong
341a9993574bc1fb7a99ebf05cdc69d99cd208b8cf5Yifan Hongstruct MatrixHalConverter : public XmlNodeConverter<MatrixHal> {
342676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    std::string elementName() const override { return "hal"; }
343676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    void mutateNode(const MatrixHal &hal, NodeType *root, DocType *d) const override {
344676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        appendAttr(root, "format", hal.format);
345676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        appendAttr(root, "optional", hal.optional);
346676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        appendTextElement(root, "name", hal.name, d);
347676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        for (const auto &version : hal.versionRanges) {
348676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            appendChild(root, versionRangeConverter(version, d));
349676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        }
350676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    }
351676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    bool buildObject(MatrixHal *object, NodeType *root) const override {
352676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        if (   !parseAttr(root, "format", &object->format)
353676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            || !parseAttr(root, "optional", &object->optional)
354676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            || !parseTextElement(root, "name", &object->name)
355676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            || !parseChildren(root, versionRangeConverter, &object->versionRanges)) {
356676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            return false;
357676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        }
358676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        return true;
359676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    }
360676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong};
361676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
362676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongconst MatrixHalConverter matrixHalConverter{};
363676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongconst XmlConverter<MatrixHal> &gMatrixHalConverter = matrixHalConverter;
364676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
365a9993574bc1fb7a99ebf05cdc69d99cd208b8cf5Yifan Hongstruct MatrixKernelConverter : public XmlNodeConverter<MatrixKernel> {
366676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    std::string elementName() const override { return "kernel"; }
367676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    void mutateNode(const MatrixKernel &kernel, NodeType *root, DocType *d) const override {
3683f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong        appendAttr(root, "version", Version{kernel.mMinLts.version, kernel.mMinLts.majorRev});
3693f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong        appendAttr(root, "minlts", kernel.mMinLts);
3703f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong        for (const KernelConfig &config : kernel.mConfigs) {
371676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            appendChild(root, kernelConfigConverter(config, d));
372676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        }
373676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    }
374676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    bool buildObject(MatrixKernel *object, NodeType *root) const override {
3753f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong        Version v;
3763f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong        if (   !parseAttr(root, "minlts", &object->mMinLts)
3773f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong            || !parseAttr(root, "version", &v)
3783f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong            || !parseChildren(root, kernelConfigConverter, &object->mConfigs)) {
3793f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong            return false;
3803f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong        }
3813f5489a519f5f1a7eb8bd7873a3170057502d93bYifan Hong        if (v != Version{object->mMinLts.version, object->mMinLts.majorRev}) {
382676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            return false;
383676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        }
384676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        return true;
385676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    }
386676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong};
387676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
388676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongconst MatrixKernelConverter matrixKernelConverter{};
389676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongconst XmlConverter<MatrixKernel> &gMatrixKernelConverter = matrixKernelConverter;
390676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
391a9993574bc1fb7a99ebf05cdc69d99cd208b8cf5Yifan Hongstruct HalImplementationConverter : public XmlNodeConverter<HalImplementation> {
392676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    std::string elementName() const override { return "impl"; }
393676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    void mutateNode(const HalImplementation &impl, NodeType *root, DocType *d) const override {
394676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        appendAttr(root, "level", impl.implLevel);
395676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        appendText(root, impl.impl, d);
396676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    }
397676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    bool buildObject(HalImplementation *object, NodeType *root) const override {
398676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        if (   !parseAttr(root, "level", &object->implLevel)
399676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            || !parseText(root, &object->impl)) {
400676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            return false;
401676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        }
402676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        return true;
403676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    }
404676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong};
405676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
406676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongconst HalImplementationConverter halImplementationConverter{};
407676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongconst XmlConverter<HalImplementation> &gHalImplementationConverter = halImplementationConverter;
408676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
409a9993574bc1fb7a99ebf05cdc69d99cd208b8cf5Yifan Hongstruct ManifestHalConverter : public XmlNodeConverter<ManifestHal> {
410676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    std::string elementName() const override { return "hal"; }
411676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    void mutateNode(const ManifestHal &hal, NodeType *root, DocType *d) const override {
412676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        appendAttr(root, "format", hal.format);
413676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        appendTextElement(root, "name", hal.name, d);
414676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        appendChild(root, transportConverter(hal.transport, d));
415676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        appendChild(root,
416676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            halImplementationConverter(hal.impl, d));
417676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        for (const auto &version : hal.versions) {
418676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            appendChild(root, versionConverter(version, d));
419676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        }
420676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    }
421676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    bool buildObject(ManifestHal *object, NodeType *root) const override {
422676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        if (   !parseAttr(root, "format", &object->format)
423676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            || !parseTextElement(root, "name", &object->name)
424676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            || !parseChild(root, transportConverter, &object->transport)
425676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            || !parseChild(root, halImplementationConverter, &object->impl)
426676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            || !parseChildren(root, versionConverter, &object->versions)) {
427676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            return false;
428676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        }
4295a06ef717dbc3e417c35dc08543144386a277a6cYifan Hong        return object->isValid();
430676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    }
431676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong};
432676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
433676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongconst ManifestHalConverter manifestHalConverter{};
434676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongconst XmlConverter<ManifestHal> &gManifestHalConverter = manifestHalConverter;
435676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
436558380a7b95de37f6c74de683102f78e97e4fbf0Yifan Hongconst XmlTextConverter<KernelSepolicyVersion> kernelSepolicyVersionConverter{"kernel-sepolicy-version"};
437558380a7b95de37f6c74de683102f78e97e4fbf0Yifan Hongconst XmlTextConverter<SepolicyVersion> sepolicyVersionConverter{"sepolicy-version"};
438558380a7b95de37f6c74de683102f78e97e4fbf0Yifan Hong
439a9993574bc1fb7a99ebf05cdc69d99cd208b8cf5Yifan Hongstruct SepolicyConverter : public XmlNodeConverter<Sepolicy> {
440676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    std::string elementName() const override { return "sepolicy"; }
441558380a7b95de37f6c74de683102f78e97e4fbf0Yifan Hong    void mutateNode(const Sepolicy &object, NodeType *root, DocType *d) const override {
442558380a7b95de37f6c74de683102f78e97e4fbf0Yifan Hong        appendChild(root, kernelSepolicyVersionConverter(object.kernelSepolicyVersion(), d));
443558380a7b95de37f6c74de683102f78e97e4fbf0Yifan Hong        appendChild(root, sepolicyVersionConverter(object.sepolicyVersion(), d));
444676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    }
445558380a7b95de37f6c74de683102f78e97e4fbf0Yifan Hong    bool buildObject(Sepolicy *object, NodeType *root) const override {
446558380a7b95de37f6c74de683102f78e97e4fbf0Yifan Hong        if (!parseChild(root, kernelSepolicyVersionConverter, &object->mKernelSepolicyVersion) ||
447558380a7b95de37f6c74de683102f78e97e4fbf0Yifan Hong            !parseChild(root, sepolicyVersionConverter, &object->mSepolicyVersion)) {
448558380a7b95de37f6c74de683102f78e97e4fbf0Yifan Hong            return false;
449558380a7b95de37f6c74de683102f78e97e4fbf0Yifan Hong        }
450676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        return true;
451676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    }
452676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong};
453676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongconst SepolicyConverter sepolicyConverter{};
454676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongconst XmlConverter<Sepolicy> &gSepolicyConverter = sepolicyConverter;
455676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
456a9993574bc1fb7a99ebf05cdc69d99cd208b8cf5Yifan Hongstruct VendorManifestConverter : public XmlNodeConverter<VendorManifest> {
457676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    std::string elementName() const override { return "manifest"; }
458676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    void mutateNode(const VendorManifest &m, NodeType *root, DocType *d) const override {
459676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        appendAttr(root, "version", VendorManifest::kVersion);
460ef6d4d3854b9d41ce70a6330fa5a3e19138fa641Yifan Hong        for (const auto &hal : m.getHals()) {
461ef6d4d3854b9d41ce70a6330fa5a3e19138fa641Yifan Hong            appendChild(root, manifestHalConverter(hal, d));
462676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        }
463676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    }
464676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    bool buildObject(VendorManifest *object, NodeType *root) const override {
465676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        std::vector<ManifestHal> hals;
466676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        if (!parseChildren(root, manifestHalConverter, &hals)) {
467676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            return false;
468676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        }
469676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        for (auto &&hal : hals) {
470676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            object->add(std::move(hal));
471676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        }
472676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        return true;
473676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    }
474676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong};
475676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
476676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongconst VendorManifestConverter vendorManifestConverter{};
477676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongconst XmlConverter<VendorManifest> &gVendorManifestConverter = vendorManifestConverter;
478676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
479a9993574bc1fb7a99ebf05cdc69d99cd208b8cf5Yifan Hongstruct CompatibilityMatrixConverter : public XmlNodeConverter<CompatibilityMatrix> {
480676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    std::string elementName() const override { return "compatibility-matrix"; }
481676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    void mutateNode(const CompatibilityMatrix &m, NodeType *root, DocType *d) const override {
482676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        appendAttr(root, "version", CompatibilityMatrix::kVersion);
483676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        for (const auto &pair : m.hals) {
484676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            appendChild(root, matrixHalConverter(pair.second, d));
485676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        }
486676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        for (const auto &kernel : m.kernels) {
487676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            appendChild(root, matrixKernelConverter(kernel, d));
488676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        }
489676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        appendChild(root, sepolicyConverter(m.sepolicy, d));
490676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    }
491676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    bool buildObject(CompatibilityMatrix *object, NodeType *root) const override {
492676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        std::vector<MatrixHal> hals;
493676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        if (   !parseChildren(root, matrixHalConverter, &hals)
494676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            || !parseChildren(root, matrixKernelConverter, &object->kernels)
495676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            || !parseChild(root, sepolicyConverter, &object->sepolicy)) {
496676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            return false;
497676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        }
498676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        for (auto &&hal : hals) {
499676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong            object->add(std::move(hal));
500676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        }
501676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        return true;
502676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong    }
503676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong};
504676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
505676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongconst CompatibilityMatrixConverter compatibilityMatrixConverter{};
506676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hongconst XmlConverter<CompatibilityMatrix> &gCompatibilityMatrixConverter
507676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong        = compatibilityMatrixConverter;
508676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong
509676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong} // namespace vintf
510676447acd00ebf93d1023f79fc02b5cbbb86dda2Yifan Hong} // namespace android
511