1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef AAPT_XML_DOM_H
18 #define AAPT_XML_DOM_H
19 
20 #include "Logger.h"
21 #include "StringPiece.h"
22 
23 #include <istream>
24 #include <libexpat/expat.h>
25 #include <memory>
26 #include <string>
27 #include <vector>
28 
29 namespace aapt {
30 namespace xml {
31 
32 struct Visitor;
33 
34 /**
35  * The type of node. Can be used to downcast to the concrete XML node
36  * class.
37  */
38 enum class NodeType {
39     kNamespace,
40     kElement,
41     kText,
42 };
43 
44 /**
45  * Base class for all XML nodes.
46  */
47 struct Node {
48     NodeType type;
49     Node* parent;
50     size_t lineNumber;
51     size_t columnNumber;
52     std::u16string comment;
53     std::vector<std::unique_ptr<Node>> children;
54 
55     Node(NodeType type);
56     void addChild(std::unique_ptr<Node> child);
57     virtual std::unique_ptr<Node> clone() const = 0;
58     virtual void accept(Visitor* visitor) = 0;
~NodeNode59     virtual ~Node() {}
60 };
61 
62 /**
63  * Base class that implements the visitor methods for a
64  * subclass of Node.
65  */
66 template <typename Derived>
67 struct BaseNode : public Node {
68     BaseNode(NodeType t);
69     virtual void accept(Visitor* visitor) override;
70 };
71 
72 /**
73  * A Namespace XML node. Can only have one child.
74  */
75 struct Namespace : public BaseNode<Namespace> {
76     std::u16string namespacePrefix;
77     std::u16string namespaceUri;
78 
79     Namespace();
80     virtual std::unique_ptr<Node> clone() const override;
81 };
82 
83 /**
84  * An XML attribute.
85  */
86 struct Attribute {
87     std::u16string namespaceUri;
88     std::u16string name;
89     std::u16string value;
90 };
91 
92 /**
93  * An Element XML node.
94  */
95 struct Element : public BaseNode<Element> {
96     std::u16string namespaceUri;
97     std::u16string name;
98     std::vector<Attribute> attributes;
99 
100     Element();
101     virtual std::unique_ptr<Node> clone() const override;
102     Attribute* findAttribute(const StringPiece16& ns, const StringPiece16& name);
103     xml::Element* findChild(const StringPiece16& ns, const StringPiece16& name);
104     xml::Element* findChildWithAttribute(const StringPiece16& ns, const StringPiece16& name,
105                                          const xml::Attribute* reqAttr);
106     std::vector<xml::Element*> getChildElements();
107 };
108 
109 /**
110  * A Text (CDATA) XML node. Can not have any children.
111  */
112 struct Text : public BaseNode<Text> {
113     std::u16string text;
114 
115     Text();
116     virtual std::unique_ptr<Node> clone() const override;
117 };
118 
119 /**
120  * Inflates an XML DOM from a text stream, logging errors to the logger.
121  * Returns the root node on success, or nullptr on failure.
122  */
123 std::unique_ptr<Node> inflate(std::istream* in, SourceLogger* logger);
124 
125 /**
126  * Inflates an XML DOM from a binary ResXMLTree, logging errors to the logger.
127  * Returns the root node on success, or nullptr on failure.
128  */
129 std::unique_ptr<Node> inflate(const void* data, size_t dataLen, SourceLogger* logger);
130 
131 /**
132  * A visitor interface for the different XML Node subtypes.
133  */
134 struct Visitor {
135     virtual void visit(Namespace* node) = 0;
136     virtual void visit(Element* node) = 0;
137     virtual void visit(Text* text) = 0;
138 };
139 
140 // Implementations
141 
142 template <typename Derived>
BaseNode(NodeType type)143 BaseNode<Derived>::BaseNode(NodeType type) : Node(type) {
144 }
145 
146 template <typename Derived>
accept(Visitor * visitor)147 void BaseNode<Derived>::accept(Visitor* visitor) {
148     visitor->visit(static_cast<Derived*>(this));
149 }
150 
151 } // namespace xml
152 } // namespace aapt
153 
154 #endif // AAPT_XML_DOM_H
155