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 29namespace aapt { 30namespace xml { 31 32struct Visitor; 33 34/** 35 * The type of node. Can be used to downcast to the concrete XML node 36 * class. 37 */ 38enum class NodeType { 39 kNamespace, 40 kElement, 41 kText, 42}; 43 44/** 45 * Base class for all XML nodes. 46 */ 47struct 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 */ 66template <typename Derived> 67struct 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 */ 75struct 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 */ 86struct Attribute { 87 std::u16string namespaceUri; 88 std::u16string name; 89 std::u16string value; 90}; 91 92/** 93 * An Element XML node. 94 */ 95struct 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 */ 112struct 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 */ 123std::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 */ 129std::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 */ 134struct 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 142template <typename Derived> 143BaseNode<Derived>::BaseNode(NodeType type) : Node(type) { 144} 145 146template <typename Derived> 147void 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