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; 59 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> 143 BaseNode<Derived>::BaseNode(NodeType type) : Node(type) { 144 } 145 146 template <typename Derived> 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