summaryrefslogtreecommitdiff
path: root/tools/aapt2/xml/XmlDom.h
diff options
context:
space:
mode:
Diffstat (limited to 'tools/aapt2/xml/XmlDom.h')
-rw-r--r--tools/aapt2/xml/XmlDom.h220
1 files changed, 220 insertions, 0 deletions
diff --git a/tools/aapt2/xml/XmlDom.h b/tools/aapt2/xml/XmlDom.h
new file mode 100644
index 000000000000..033b0a4d031c
--- /dev/null
+++ b/tools/aapt2/xml/XmlDom.h
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef AAPT_XML_DOM_H
+#define AAPT_XML_DOM_H
+
+#include "Diagnostics.h"
+#include "Resource.h"
+#include "ResourceValues.h"
+#include "util/StringPiece.h"
+#include "util/Util.h"
+#include "xml/XmlUtil.h"
+
+#include <istream>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace aapt {
+namespace xml {
+
+struct RawVisitor;
+
+/**
+ * Base class for all XML nodes.
+ */
+struct Node {
+ Node* parent = nullptr;
+ size_t lineNumber = 0;
+ size_t columnNumber = 0;
+ std::u16string comment;
+ std::vector<std::unique_ptr<Node>> children;
+
+ virtual ~Node() = default;
+
+ void addChild(std::unique_ptr<Node> child);
+ virtual void accept(RawVisitor* visitor) = 0;
+};
+
+/**
+ * Base class that implements the visitor methods for a
+ * subclass of Node.
+ */
+template <typename Derived>
+struct BaseNode : public Node {
+ virtual void accept(RawVisitor* visitor) override;
+};
+
+/**
+ * A Namespace XML node. Can only have one child.
+ */
+struct Namespace : public BaseNode<Namespace> {
+ std::u16string namespacePrefix;
+ std::u16string namespaceUri;
+};
+
+struct AaptAttribute {
+ ResourceId id;
+ aapt::Attribute attribute;
+};
+
+/**
+ * An XML attribute.
+ */
+struct Attribute {
+ std::u16string namespaceUri;
+ std::u16string name;
+ std::u16string value;
+
+ Maybe<AaptAttribute> compiledAttribute;
+ std::unique_ptr<Item> compiledValue;
+};
+
+/**
+ * An Element XML node.
+ */
+struct Element : public BaseNode<Element> {
+ std::u16string namespaceUri;
+ std::u16string name;
+ std::vector<Attribute> attributes;
+
+ Attribute* findAttribute(const StringPiece16& ns, const StringPiece16& name);
+ xml::Element* findChild(const StringPiece16& ns, const StringPiece16& name);
+ xml::Element* findChildWithAttribute(const StringPiece16& ns, const StringPiece16& name,
+ const StringPiece16& attrNs,
+ const StringPiece16& attrName,
+ const StringPiece16& attrValue);
+ std::vector<xml::Element*> getChildElements();
+};
+
+/**
+ * A Text (CDATA) XML node. Can not have any children.
+ */
+struct Text : public BaseNode<Text> {
+ std::u16string text;
+};
+
+/**
+ * An XML resource with a source, name, and XML tree.
+ */
+struct XmlResource {
+ ResourceFile file;
+ std::unique_ptr<xml::Node> root;
+};
+
+/**
+ * Inflates an XML DOM from a text stream, logging errors to the logger.
+ * Returns the root node on success, or nullptr on failure.
+ */
+std::unique_ptr<XmlResource> inflate(std::istream* in, IDiagnostics* diag, const Source& source);
+
+/**
+ * Inflates an XML DOM from a binary ResXMLTree, logging errors to the logger.
+ * Returns the root node on success, or nullptr on failure.
+ */
+std::unique_ptr<XmlResource> inflate(const void* data, size_t dataLen, IDiagnostics* diag,
+ const Source& source);
+
+Element* findRootElement(XmlResource* doc);
+Element* findRootElement(Node* node);
+
+/**
+ * A visitor interface for the different XML Node subtypes. This will not traverse into
+ * children. Use Visitor for that.
+ */
+struct RawVisitor {
+ virtual ~RawVisitor() = default;
+
+ virtual void visit(Namespace* node) {}
+ virtual void visit(Element* node) {}
+ virtual void visit(Text* text) {}
+};
+
+/**
+ * Visitor whose default implementation visits the children nodes of any node.
+ */
+struct Visitor : public RawVisitor {
+ using RawVisitor::visit;
+
+ void visit(Namespace* node) override {
+ visitChildren(node);
+ }
+
+ void visit(Element* node) override {
+ visitChildren(node);
+ }
+
+ void visit(Text* text) override {
+ visitChildren(text);
+ }
+
+ void visitChildren(Node* node) {
+ for (auto& child : node->children) {
+ child->accept(this);
+ }
+ }
+};
+
+/**
+ * An XML DOM visitor that will record the package name for a namespace prefix.
+ */
+class PackageAwareVisitor : public Visitor, public IPackageDeclStack {
+private:
+ struct PackageDecl {
+ std::u16string prefix;
+ ExtractedPackage package;
+ };
+
+ std::vector<PackageDecl> mPackageDecls;
+
+public:
+ using Visitor::visit;
+
+ void visit(Namespace* ns) override;
+ Maybe<ExtractedPackage> transformPackageAlias(
+ const StringPiece16& alias, const StringPiece16& localPackage) const override;
+};
+
+// Implementations
+
+template <typename Derived>
+void BaseNode<Derived>::accept(RawVisitor* visitor) {
+ visitor->visit(static_cast<Derived*>(this));
+}
+
+template <typename T>
+struct NodeCastImpl : public RawVisitor {
+ using RawVisitor::visit;
+
+ T* value = nullptr;
+
+ void visit(T* v) override {
+ value = v;
+ }
+};
+
+template <typename T>
+T* nodeCast(Node* node) {
+ NodeCastImpl<T> visitor;
+ node->accept(&visitor);
+ return visitor.value;
+}
+
+} // namespace xml
+} // namespace aapt
+
+#endif // AAPT_XML_DOM_H