16f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/*
26f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Copyright (C) 2015 The Android Open Source Project
36f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski *
46f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
56f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * you may not use this file except in compliance with the License.
66f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * You may obtain a copy of the License at
76f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski *
86f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
96f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski *
106f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Unless required by applicable law or agreed to in writing, software
116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * See the License for the specific language governing permissions and
146f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * limitations under the License.
156f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */
166f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
176f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#ifndef AAPT_RESOURCE_H
186f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#define AAPT_RESOURCE_H
196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
206f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <iomanip>
21ca2fc353c2b07e24e297fdc8426c7abd601d908bAdam Lesinski#include <limits>
22d0f116b619feede0cfdb647157ce5ab4d50a1c46Adam Lesinski#include <sstream>
236f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <string>
246f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <tuple>
251ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include <vector>
266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
27d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski#include "androidfw/StringPiece.h"
28ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include "utils/JenkinsHash.h"
29ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski
30ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include "ConfigDescription.h"
31ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include "Source.h"
32ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski
336f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskinamespace aapt {
346f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
356f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/**
366f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * The various types of resource types available. Corresponds
376f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * to the 'type' in package:type/entry.
386f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */
396f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskienum class ResourceType {
40cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  kAnim,
41cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  kAnimator,
42cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  kArray,
43cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  kAttr,
44cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  kAttrPrivate,
45cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  kBool,
46cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  kColor,
4786d67df8d57b9537666f9b54a9ca563779a2288bAdam Lesinski
4886d67df8d57b9537666f9b54a9ca563779a2288bAdam Lesinski  // Not really a type, but it shows up in some CTS tests and
4986d67df8d57b9537666f9b54a9ca563779a2288bAdam Lesinski  // we need to continue respecting it.
5086d67df8d57b9537666f9b54a9ca563779a2288bAdam Lesinski  kConfigVarying,
5186d67df8d57b9537666f9b54a9ca563779a2288bAdam Lesinski
52cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  kDimen,
53cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  kDrawable,
54c0c366394c658e3787b12e65833b520c9a9a34d9Adam Lesinski  kFont,
55cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  kFraction,
56cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  kId,
57cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  kInteger,
58cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  kInterpolator,
59cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  kLayout,
60cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  kMenu,
61cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  kMipmap,
62ee0e486d3617bdc31ae6e42414bbf2316dee164cAdam Lesinski  kNavigation,
63cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  kPlurals,
64cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  kRaw,
65cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  kString,
66cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  kStyle,
67cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  kStyleable,
68cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  kTransition,
69cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  kXml,
706f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski};
716f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
72d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskiandroid::StringPiece ToString(ResourceType type);
736f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
746f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/**
756f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Returns a pointer to a valid ResourceType, or nullptr if
766f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * the string was invalid.
776f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */
78d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskiconst ResourceType* ParseResourceType(const android::StringPiece& str);
796f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
806f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/**
816f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * A resource's name. This can uniquely identify
826f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * a resource in the ResourceTable.
836f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */
846f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistruct ResourceName {
85cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  std::string package;
86ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  ResourceType type = ResourceType::kRaw;
87cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  std::string entry;
886f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
89ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  ResourceName() = default;
90d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski  ResourceName(const android::StringPiece& p, ResourceType t, const android::StringPiece& e);
919ba47d813075fcb05c5e1532c137c93b394631cbAdam Lesinski
92cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  int compare(const ResourceName& other) const;
938197cc460e02c6445434eace435e3d38ebe475c6Adam Lesinski
94ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  bool is_valid() const;
95ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  std::string ToString() const;
966f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski};
976f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
986f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/**
996f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Same as ResourceName, but uses StringPieces instead.
1006f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Use this if you need to avoid copying and know that
1016f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * the lifetime of this object is shorter than that
1026f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * of the original string.
1036f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */
1046f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistruct ResourceNameRef {
105d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski  android::StringPiece package;
106ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  ResourceType type = ResourceType::kRaw;
107d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski  android::StringPiece entry;
108cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
109cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ResourceNameRef() = default;
110cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ResourceNameRef(const ResourceNameRef&) = default;
111cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ResourceNameRef(ResourceNameRef&&) = default;
112cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ResourceNameRef(const ResourceName& rhs);  // NOLINT(implicit)
113d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski  ResourceNameRef(const android::StringPiece& p, ResourceType t, const android::StringPiece& e);
114cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ResourceNameRef& operator=(const ResourceNameRef& rhs) = default;
115cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ResourceNameRef& operator=(ResourceNameRef&& rhs) = default;
116cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ResourceNameRef& operator=(const ResourceName& rhs);
117cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
118ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  ResourceName ToResourceName() const;
119ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  bool is_valid() const;
1206f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski};
1216f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
122b5dc4bd49a036e3403ca17e961d2c8e13e038295Adam Lesinskiconstexpr const uint8_t kAppPackageId = 0x7fu;
123b5dc4bd49a036e3403ca17e961d2c8e13e038295Adam Lesinskiconstexpr const uint8_t kFrameworkPackageId = 0x01u;
124b5dc4bd49a036e3403ca17e961d2c8e13e038295Adam Lesinski
1256f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/**
1266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * A binary identifier representing a resource. Internally it
1276f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * is a 32bit integer split as follows:
1286f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski *
1296f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * 0xPPTTEEEE
1306f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski *
1316f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * PP: 8 bit package identifier. 0x01 is reserved for system
1326f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski *     and 0x7f is reserved for the running app.
1336f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * TT: 8 bit type identifier. 0x00 is invalid.
1346f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * EEEE: 16 bit entry identifier.
1356f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */
1366f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistruct ResourceId {
137cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  uint32_t id;
1386f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
139cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ResourceId();
140cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ResourceId(const ResourceId& rhs);
141ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  ResourceId(uint32_t res_id);  // NOLINT(implicit)
142cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ResourceId(uint8_t p, uint8_t t, uint16_t e);
1436f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
144ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  bool is_valid() const;
145ceb9b2f80f853059233cdd29057f39a5960a74aeAdam Lesinski
146ceb9b2f80f853059233cdd29057f39a5960a74aeAdam Lesinski  // Returns true if the ID is a valid ID or dynamic ID (package ID can be 0).
147ceb9b2f80f853059233cdd29057f39a5960a74aeAdam Lesinski  bool is_valid_dynamic() const;
148ceb9b2f80f853059233cdd29057f39a5960a74aeAdam Lesinski
149ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  uint8_t package_id() const;
150ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  uint8_t type_id() const;
151ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  uint16_t entry_id() const;
1526f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski};
1536f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1541ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskistruct SourcedResourceName {
155cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ResourceName name;
156cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  size_t line;
1571ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski};
1581ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
1591ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskistruct ResourceFile {
160cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  // Name
161cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ResourceName name;
1621ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
163cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  // Configuration
164cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ConfigDescription config;
1651ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
166cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  // Source
167cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  Source source;
1681ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
169cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  // Exported symbols
170ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  std::vector<SourcedResourceName> exported_symbols;
1711ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski};
1721ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
173a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski/**
174cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski * Useful struct used as a key to represent a unique resource in associative
175cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski * containers.
176a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski */
177a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinskistruct ResourceKey {
178cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ResourceName name;
179cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ConfigDescription config;
180a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski};
181a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski
182a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinskibool operator<(const ResourceKey& a, const ResourceKey& b);
183a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski
184a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski/**
185cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski * Useful struct used as a key to represent a unique resource in associative
186cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski * containers.
187a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski * Holds a reference to the name, so that name better live longer than this key!
188a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski */
189a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinskistruct ResourceKeyRef {
190cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ResourceNameRef name;
191cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ConfigDescription config;
192a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski
193cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ResourceKeyRef() = default;
194cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ResourceKeyRef(const ResourceNameRef& n, const ConfigDescription& c)
195cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      : name(n), config(c) {}
196a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski
197cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  /**
198cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   * Prevent taking a reference to a temporary. This is bad.
199cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   */
200cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ResourceKeyRef(ResourceName&& n, const ConfigDescription& c) = delete;
201a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski};
202a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski
203a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinskibool operator<(const ResourceKeyRef& a, const ResourceKeyRef& b);
204a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski
2056f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski//
2066f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski// ResourceId implementation.
2076f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski//
2086f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
209cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinskiinline ResourceId::ResourceId() : id(0) {}
2106f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
211cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinskiinline ResourceId::ResourceId(const ResourceId& rhs) : id(rhs.id) {}
2126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
213ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskiinline ResourceId::ResourceId(uint32_t res_id) : id(res_id) {}
2146f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
215cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinskiinline ResourceId::ResourceId(uint8_t p, uint8_t t, uint16_t e)
216cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    : id((p << 24) | (t << 16) | e) {}
2176f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
218ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskiinline bool ResourceId::is_valid() const {
219cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return (id & 0xff000000u) != 0 && (id & 0x00ff0000u) != 0;
2206f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
2216f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
222ceb9b2f80f853059233cdd29057f39a5960a74aeAdam Lesinskiinline bool ResourceId::is_valid_dynamic() const { return (id & 0x00ff0000u) != 0; }
223ceb9b2f80f853059233cdd29057f39a5960a74aeAdam Lesinski
224ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskiinline uint8_t ResourceId::package_id() const {
225cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return static_cast<uint8_t>(id >> 24);
2266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
2276f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
228ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskiinline uint8_t ResourceId::type_id() const {
229cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return static_cast<uint8_t>(id >> 16);
2306f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
2316f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
232ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskiinline uint16_t ResourceId::entry_id() const {
233cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return static_cast<uint16_t>(id);
2346f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
2356f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
23674605cd40256ca75b44cc3182eeeb886c92d737cAdam Lesinskiinline bool operator<(const ResourceId& lhs, const ResourceId& rhs) {
237cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return lhs.id < rhs.id;
23874605cd40256ca75b44cc3182eeeb886c92d737cAdam Lesinski}
23974605cd40256ca75b44cc3182eeeb886c92d737cAdam Lesinski
24074605cd40256ca75b44cc3182eeeb886c92d737cAdam Lesinskiinline bool operator>(const ResourceId& lhs, const ResourceId& rhs) {
241cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return lhs.id > rhs.id;
24274605cd40256ca75b44cc3182eeeb886c92d737cAdam Lesinski}
24374605cd40256ca75b44cc3182eeeb886c92d737cAdam Lesinski
24474605cd40256ca75b44cc3182eeeb886c92d737cAdam Lesinskiinline bool operator==(const ResourceId& lhs, const ResourceId& rhs) {
245cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return lhs.id == rhs.id;
2466f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
2476f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
24874605cd40256ca75b44cc3182eeeb886c92d737cAdam Lesinskiinline bool operator!=(const ResourceId& lhs, const ResourceId& rhs) {
249cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return lhs.id != rhs.id;
25024aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski}
25124aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski
252cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinskiinline ::std::ostream& operator<<(::std::ostream& out,
253ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski                                  const ResourceId& res_id) {
254ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  std::ios_base::fmtflags old_flags = out.flags();
255ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  char old_fill = out.fill();
256cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  out << "0x" << std::internal << std::setfill('0') << std::setw(8) << std::hex
257ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      << res_id.id;
258ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  out.flags(old_flags);
259ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  out.fill(old_fill);
260cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return out;
2616f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
2626f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2636f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski//
2646f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski// ResourceType implementation.
2656f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski//
2666f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
267cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinskiinline ::std::ostream& operator<<(::std::ostream& out,
268cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski                                  const ResourceType& val) {
269ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  return out << ToString(val);
2706f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
2716f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2726f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski//
2736f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski// ResourceName implementation.
2746f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski//
2756f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
276d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskiinline ResourceName::ResourceName(const android::StringPiece& p, ResourceType t,
277d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski                                  const android::StringPiece& e)
278d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski    : package(p.to_string()), type(t), entry(e.to_string()) {}
2799ba47d813075fcb05c5e1532c137c93b394631cbAdam Lesinski
2808197cc460e02c6445434eace435e3d38ebe475c6Adam Lesinskiinline int ResourceName::compare(const ResourceName& other) const {
281cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  int cmp = package.compare(other.package);
282cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (cmp != 0) return cmp;
283cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  cmp = static_cast<int>(type) - static_cast<int>(other.type);
284cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (cmp != 0) return cmp;
285cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  cmp = entry.compare(other.entry);
286cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return cmp;
2878197cc460e02c6445434eace435e3d38ebe475c6Adam Lesinski}
2888197cc460e02c6445434eace435e3d38ebe475c6Adam Lesinski
289ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskiinline bool ResourceName::is_valid() const {
290cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return !package.empty() && !entry.empty();
2916f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
2926f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
29374605cd40256ca75b44cc3182eeeb886c92d737cAdam Lesinskiinline bool operator<(const ResourceName& lhs, const ResourceName& rhs) {
294cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return std::tie(lhs.package, lhs.type, lhs.entry) <
295cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski         std::tie(rhs.package, rhs.type, rhs.entry);
2966f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
2976f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
29874605cd40256ca75b44cc3182eeeb886c92d737cAdam Lesinskiinline bool operator==(const ResourceName& lhs, const ResourceName& rhs) {
299cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return std::tie(lhs.package, lhs.type, lhs.entry) ==
300cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski         std::tie(rhs.package, rhs.type, rhs.entry);
3016f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
3026f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
30374605cd40256ca75b44cc3182eeeb886c92d737cAdam Lesinskiinline bool operator!=(const ResourceName& lhs, const ResourceName& rhs) {
304cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return std::tie(lhs.package, lhs.type, lhs.entry) !=
305cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski         std::tie(rhs.package, rhs.type, rhs.entry);
3066f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
3076f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
308cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinskiinline ::std::ostream& operator<<(::std::ostream& out,
309cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski                                  const ResourceName& name) {
310cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (!name.package.empty()) {
311cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    out << name.package << ":";
312cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
313cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return out << name.type << "/" << name.entry;
314769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski}
315769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
316ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskiinline std::string ResourceName::ToString() const {
317cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  std::stringstream stream;
318cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  stream << *this;
319cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return stream.str();
320d0f116b619feede0cfdb647157ce5ab4d50a1c46Adam Lesinski}
321769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
3226f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski//
3236f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski// ResourceNameRef implementation.
3246f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski//
3256f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
326cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinskiinline ResourceNameRef::ResourceNameRef(const ResourceName& rhs)
327cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    : package(rhs.package), type(rhs.type), entry(rhs.entry) {}
3286f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
329d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskiinline ResourceNameRef::ResourceNameRef(const android::StringPiece& p, ResourceType t,
330d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski                                        const android::StringPiece& e)
331cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    : package(p), type(t), entry(e) {}
3326f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
3336f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline ResourceNameRef& ResourceNameRef::operator=(const ResourceName& rhs) {
334cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  package = rhs.package;
335cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  type = rhs.type;
336cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  entry = rhs.entry;
337cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return *this;
3386f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
3396f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
340ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskiinline ResourceName ResourceNameRef::ToResourceName() const {
341cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return ResourceName(package, type, entry);
3426f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
3436f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
344ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskiinline bool ResourceNameRef::is_valid() const {
345cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return !package.empty() && !entry.empty();
3466f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
3476f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
34874605cd40256ca75b44cc3182eeeb886c92d737cAdam Lesinskiinline bool operator<(const ResourceNameRef& lhs, const ResourceNameRef& rhs) {
349cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return std::tie(lhs.package, lhs.type, lhs.entry) <
350cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski         std::tie(rhs.package, rhs.type, rhs.entry);
3516f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
3526f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
35374605cd40256ca75b44cc3182eeeb886c92d737cAdam Lesinskiinline bool operator==(const ResourceNameRef& lhs, const ResourceNameRef& rhs) {
354cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return std::tie(lhs.package, lhs.type, lhs.entry) ==
355cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski         std::tie(rhs.package, rhs.type, rhs.entry);
3566f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
3576f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
35874605cd40256ca75b44cc3182eeeb886c92d737cAdam Lesinskiinline bool operator!=(const ResourceNameRef& lhs, const ResourceNameRef& rhs) {
359cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return std::tie(lhs.package, lhs.type, lhs.entry) !=
360cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski         std::tie(rhs.package, rhs.type, rhs.entry);
3616f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
3626f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
363cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinskiinline ::std::ostream& operator<<(::std::ostream& out,
364cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski                                  const ResourceNameRef& name) {
365cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (!name.package.empty()) {
366cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    out << name.package << ":";
367cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
368cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return out << name.type << "/" << name.entry;
3696f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
3706f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
37174605cd40256ca75b44cc3182eeeb886c92d737cAdam Lesinskiinline bool operator<(const ResourceName& lhs, const ResourceNameRef& b) {
372cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return ResourceNameRef(lhs) < b;
37374605cd40256ca75b44cc3182eeeb886c92d737cAdam Lesinski}
37474605cd40256ca75b44cc3182eeeb886c92d737cAdam Lesinski
37574605cd40256ca75b44cc3182eeeb886c92d737cAdam Lesinskiinline bool operator!=(const ResourceName& lhs, const ResourceNameRef& rhs) {
376cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return ResourceNameRef(lhs) != rhs;
37774605cd40256ca75b44cc3182eeeb886c92d737cAdam Lesinski}
37874605cd40256ca75b44cc3182eeeb886c92d737cAdam Lesinski
379cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinskiinline bool operator==(const SourcedResourceName& lhs,
380cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski                       const SourcedResourceName& rhs) {
381cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return lhs.name == rhs.name && lhs.line == rhs.line;
38274605cd40256ca75b44cc3182eeeb886c92d737cAdam Lesinski}
38374605cd40256ca75b44cc3182eeeb886c92d737cAdam Lesinski
384cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski}  // namespace aapt
3856f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
386bf0bd0f9ac1ffa0231cff0f6591dede48b3c6d52Adam Lesinskinamespace std {
387bf0bd0f9ac1ffa0231cff0f6591dede48b3c6d52Adam Lesinski
388cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinskitemplate <>
389cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinskistruct hash<aapt::ResourceName> {
390cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  size_t operator()(const aapt::ResourceName& name) const {
391cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    android::hash_t h = 0;
392c744ae8aca97edfb2422598ea620e8219449fa9bAdam Lesinski    h = android::JenkinsHashMix(h, static_cast<uint32_t>(hash<string>()(name.package)));
393cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    h = android::JenkinsHashMix(h, static_cast<uint32_t>(name.type));
394c744ae8aca97edfb2422598ea620e8219449fa9bAdam Lesinski    h = android::JenkinsHashMix(h, static_cast<uint32_t>(hash<string>()(name.entry)));
395cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return static_cast<size_t>(h);
396cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
397bf0bd0f9ac1ffa0231cff0f6591dede48b3c6d52Adam Lesinski};
398bf0bd0f9ac1ffa0231cff0f6591dede48b3c6d52Adam Lesinski
399c744ae8aca97edfb2422598ea620e8219449fa9bAdam Lesinskitemplate <>
400c744ae8aca97edfb2422598ea620e8219449fa9bAdam Lesinskistruct hash<aapt::ResourceId> {
401c744ae8aca97edfb2422598ea620e8219449fa9bAdam Lesinski  size_t operator()(const aapt::ResourceId& id) const {
402c744ae8aca97edfb2422598ea620e8219449fa9bAdam Lesinski    return id.id;
403c744ae8aca97edfb2422598ea620e8219449fa9bAdam Lesinski  }
404c744ae8aca97edfb2422598ea620e8219449fa9bAdam Lesinski};
405c744ae8aca97edfb2422598ea620e8219449fa9bAdam Lesinski
406cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski}  // namespace std
407bf0bd0f9ac1ffa0231cff0f6591dede48b3c6d52Adam Lesinski
408cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski#endif  // AAPT_RESOURCE_H
409