AAPT2

First checking of AAPT2. The individual phases of AAPT2 work, but there
are some missing pieces.

For early testing we are missing:
- Need to properly mark file references and include them in package
- Need to package into zip

Final AAPT for apps we are missing:
- Need to crush PNGs
- Need to parse 9-patches
- Need to validate all of AndroidManifest.xml
- Need to write align method to align resource tables for splits.

Final AAPT for apps + system we are missing:
- Need to handle overlays
- Need to store comments for R file
- Need to handle --shared-lib (dynamic references too).

New AAPT features coming:
- Need to import compiled libraries
    - Name mangling
    - R file generation for library code

Change-Id: I95f8a63581b81a1f424ae6fb2c373c883b72c18d
diff --git a/tools/aapt2/Resource.h b/tools/aapt2/Resource.h
new file mode 100644
index 0000000..3fd678e
--- /dev/null
+++ b/tools/aapt2/Resource.h
@@ -0,0 +1,276 @@
+/*
+ * 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_RESOURCE_H
+#define AAPT_RESOURCE_H
+
+#include "StringPiece.h"
+
+#include <iomanip>
+#include <string>
+#include <tuple>
+
+namespace aapt {
+
+/**
+ * The various types of resource types available. Corresponds
+ * to the 'type' in package:type/entry.
+ */
+enum class ResourceType {
+    kAnim,
+    kAnimator,
+    kArray,
+    kAttr,
+    kAttrPrivate,
+    kBool,
+    kColor,
+    kDimen,
+    kDrawable,
+    kFraction,
+    kId,
+    kInteger,
+    kIntegerArray,
+    kInterpolator,
+    kLayout,
+    kMenu,
+    kMipmap,
+    kPlurals,
+    kRaw,
+    kString,
+    kStyle,
+    kStyleable,
+    kTransition,
+    kXml,
+};
+
+StringPiece16 toString(ResourceType type);
+
+/**
+ * Returns a pointer to a valid ResourceType, or nullptr if
+ * the string was invalid.
+ */
+const ResourceType* parseResourceType(const StringPiece16& str);
+
+/**
+ * A resource's name. This can uniquely identify
+ * a resource in the ResourceTable.
+ */
+struct ResourceName {
+    std::u16string package;
+    ResourceType type;
+    std::u16string entry;
+
+    bool isValid() const;
+    bool operator<(const ResourceName& rhs) const;
+    bool operator==(const ResourceName& rhs) const;
+    bool operator!=(const ResourceName& rhs) const;
+};
+
+/**
+ * Same as ResourceName, but uses StringPieces instead.
+ * Use this if you need to avoid copying and know that
+ * the lifetime of this object is shorter than that
+ * of the original string.
+ */
+struct ResourceNameRef {
+    StringPiece16 package;
+    ResourceType type;
+    StringPiece16 entry;
+
+    ResourceNameRef() = default;
+    ResourceNameRef(const ResourceNameRef&) = default;
+    ResourceNameRef(ResourceNameRef&&) = default;
+    ResourceNameRef(const ResourceName& rhs);
+    ResourceNameRef(const StringPiece16& p, ResourceType t, const StringPiece16& e);
+    ResourceNameRef& operator=(const ResourceName& rhs);
+
+    ResourceName toResourceName() const;
+    bool isValid() const;
+
+    bool operator<(const ResourceNameRef& rhs) const;
+    bool operator==(const ResourceNameRef& rhs) const;
+    bool operator!=(const ResourceNameRef& rhs) const;
+};
+
+/**
+ * A binary identifier representing a resource. Internally it
+ * is a 32bit integer split as follows:
+ *
+ * 0xPPTTEEEE
+ *
+ * PP: 8 bit package identifier. 0x01 is reserved for system
+ *     and 0x7f is reserved for the running app.
+ * TT: 8 bit type identifier. 0x00 is invalid.
+ * EEEE: 16 bit entry identifier.
+ */
+struct ResourceId {
+    uint32_t id;
+
+    ResourceId();
+    ResourceId(const ResourceId& rhs);
+    ResourceId(uint32_t resId);
+    ResourceId(size_t p, size_t t, size_t e);
+
+    bool isValid() const;
+    uint8_t packageId() const;
+    uint8_t typeId() const;
+    uint16_t entryId() const;
+    bool operator<(const ResourceId& rhs) const;
+};
+
+//
+// ResourceId implementation.
+//
+
+inline ResourceId::ResourceId() : id(0) {
+}
+
+inline ResourceId::ResourceId(const ResourceId& rhs) : id(rhs.id) {
+}
+
+inline ResourceId::ResourceId(uint32_t resId) : id(resId) {
+}
+
+inline ResourceId::ResourceId(size_t p, size_t t, size_t e) : id(0) {
+    if (p > std::numeric_limits<uint8_t>::max() ||
+            t > std::numeric_limits<uint8_t>::max() ||
+            e > std::numeric_limits<uint16_t>::max()) {
+        // This will leave the ResourceId in an invalid state.
+        return;
+    }
+
+    id = (static_cast<uint8_t>(p) << 24) |
+         (static_cast<uint8_t>(t) << 16) |
+         static_cast<uint16_t>(e);
+}
+
+inline bool ResourceId::isValid() const {
+    return (id & 0xff000000u) != 0 && (id & 0x00ff0000u) != 0;
+}
+
+inline uint8_t ResourceId::packageId() const {
+    return static_cast<uint8_t>(id >> 24);
+}
+
+inline uint8_t ResourceId::typeId() const {
+    return static_cast<uint8_t>(id >> 16);
+}
+
+inline uint16_t ResourceId::entryId() const {
+    return static_cast<uint16_t>(id);
+}
+
+inline bool ResourceId::operator<(const ResourceId& rhs) const {
+    return id < rhs.id;
+}
+
+inline ::std::ostream& operator<<(::std::ostream& out,
+        const ResourceId& resId) {
+    std::ios_base::fmtflags oldFlags = out.flags();
+    char oldFill = out.fill();
+    out << "0x" << std::internal << std::setfill('0') << std::setw(8)
+        << std::hex << resId.id;
+    out.flags(oldFlags);
+    out.fill(oldFill);
+    return out;
+}
+
+//
+// ResourceType implementation.
+//
+
+inline ::std::ostream& operator<<(::std::ostream& out,
+        const ResourceType& val) {
+    return out << toString(val);
+}
+
+//
+// ResourceName implementation.
+//
+
+inline bool ResourceName::isValid() const {
+    return !package.empty() && !entry.empty();
+}
+
+inline bool ResourceName::operator<(const ResourceName& rhs) const {
+    return std::tie(package, type, entry)
+            < std::tie(rhs.package, rhs.type, rhs.entry);
+}
+
+inline bool ResourceName::operator==(const ResourceName& rhs) const {
+    return std::tie(package, type, entry)
+            == std::tie(rhs.package, rhs.type, rhs.entry);
+}
+
+inline bool ResourceName::operator!=(const ResourceName& rhs) const {
+    return std::tie(package, type, entry)
+            != std::tie(rhs.package, rhs.type, rhs.entry);
+}
+
+//
+// ResourceNameRef implementation.
+//
+
+inline ResourceNameRef::ResourceNameRef(const ResourceName& rhs) :
+        package(rhs.package), type(rhs.type), entry(rhs.entry) {
+}
+
+inline ResourceNameRef::ResourceNameRef(const StringPiece16& p, ResourceType t,
+                                        const StringPiece16& e) :
+        package(p), type(t), entry(e) {
+}
+
+inline ResourceNameRef& ResourceNameRef::operator=(const ResourceName& rhs) {
+    package = rhs.package;
+    type = rhs.type;
+    entry = rhs.entry;
+    return *this;
+}
+
+inline ResourceName ResourceNameRef::toResourceName() const {
+    return { package.toString(), type, entry.toString() };
+}
+
+inline bool ResourceNameRef::isValid() const {
+    return !package.empty() && !entry.empty();
+}
+
+inline bool ResourceNameRef::operator<(const ResourceNameRef& rhs) const {
+    return std::tie(package, type, entry)
+            < std::tie(rhs.package, rhs.type, rhs.entry);
+}
+
+inline bool ResourceNameRef::operator==(const ResourceNameRef& rhs) const {
+    return std::tie(package, type, entry)
+            == std::tie(rhs.package, rhs.type, rhs.entry);
+}
+
+inline bool ResourceNameRef::operator!=(const ResourceNameRef& rhs) const {
+    return std::tie(package, type, entry)
+            != std::tie(rhs.package, rhs.type, rhs.entry);
+}
+
+inline ::std::ostream& operator<<(::std::ostream& out,
+        const ResourceNameRef& name) {
+    if (!name.package.empty()) {
+        out << name.package << ":";
+    }
+    return out << name.type << "/" << name.entry;
+}
+
+} // namespace aapt
+
+#endif // AAPT_RESOURCE_H