1*d57664e9SAndroid Build Coastguard Worker /*
2*d57664e9SAndroid Build Coastguard Worker * Copyright (C) 2015 The Android Open Source Project
3*d57664e9SAndroid Build Coastguard Worker *
4*d57664e9SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*d57664e9SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*d57664e9SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*d57664e9SAndroid Build Coastguard Worker *
8*d57664e9SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*d57664e9SAndroid Build Coastguard Worker *
10*d57664e9SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*d57664e9SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*d57664e9SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*d57664e9SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*d57664e9SAndroid Build Coastguard Worker * limitations under the License.
15*d57664e9SAndroid Build Coastguard Worker */
16*d57664e9SAndroid Build Coastguard Worker
17*d57664e9SAndroid Build Coastguard Worker #ifndef AAPT_RESOURCE_H
18*d57664e9SAndroid Build Coastguard Worker #define AAPT_RESOURCE_H
19*d57664e9SAndroid Build Coastguard Worker
20*d57664e9SAndroid Build Coastguard Worker #include <iomanip>
21*d57664e9SAndroid Build Coastguard Worker #include <limits>
22*d57664e9SAndroid Build Coastguard Worker #include <optional>
23*d57664e9SAndroid Build Coastguard Worker #include <sstream>
24*d57664e9SAndroid Build Coastguard Worker #include <string>
25*d57664e9SAndroid Build Coastguard Worker #include <tuple>
26*d57664e9SAndroid Build Coastguard Worker #include <vector>
27*d57664e9SAndroid Build Coastguard Worker
28*d57664e9SAndroid Build Coastguard Worker #include "androidfw/ConfigDescription.h"
29*d57664e9SAndroid Build Coastguard Worker #include "androidfw/Source.h"
30*d57664e9SAndroid Build Coastguard Worker #include "androidfw/StringPiece.h"
31*d57664e9SAndroid Build Coastguard Worker #include "utils/JenkinsHash.h"
32*d57664e9SAndroid Build Coastguard Worker
33*d57664e9SAndroid Build Coastguard Worker namespace aapt {
34*d57664e9SAndroid Build Coastguard Worker
35*d57664e9SAndroid Build Coastguard Worker /**
36*d57664e9SAndroid Build Coastguard Worker * The various types of resource types available.
37*d57664e9SAndroid Build Coastguard Worker */
38*d57664e9SAndroid Build Coastguard Worker enum class ResourceType {
39*d57664e9SAndroid Build Coastguard Worker kAnim,
40*d57664e9SAndroid Build Coastguard Worker kAnimator,
41*d57664e9SAndroid Build Coastguard Worker kArray,
42*d57664e9SAndroid Build Coastguard Worker kAttr,
43*d57664e9SAndroid Build Coastguard Worker kAttrPrivate,
44*d57664e9SAndroid Build Coastguard Worker kBool,
45*d57664e9SAndroid Build Coastguard Worker kColor,
46*d57664e9SAndroid Build Coastguard Worker
47*d57664e9SAndroid Build Coastguard Worker // Not really a type, but it shows up in some CTS tests and
48*d57664e9SAndroid Build Coastguard Worker // we need to continue respecting it.
49*d57664e9SAndroid Build Coastguard Worker kConfigVarying,
50*d57664e9SAndroid Build Coastguard Worker
51*d57664e9SAndroid Build Coastguard Worker kDimen,
52*d57664e9SAndroid Build Coastguard Worker kDrawable,
53*d57664e9SAndroid Build Coastguard Worker kFont,
54*d57664e9SAndroid Build Coastguard Worker kFraction,
55*d57664e9SAndroid Build Coastguard Worker kId,
56*d57664e9SAndroid Build Coastguard Worker kInteger,
57*d57664e9SAndroid Build Coastguard Worker kInterpolator,
58*d57664e9SAndroid Build Coastguard Worker kLayout,
59*d57664e9SAndroid Build Coastguard Worker kMacro,
60*d57664e9SAndroid Build Coastguard Worker kMenu,
61*d57664e9SAndroid Build Coastguard Worker kMipmap,
62*d57664e9SAndroid Build Coastguard Worker kNavigation,
63*d57664e9SAndroid Build Coastguard Worker kPlurals,
64*d57664e9SAndroid Build Coastguard Worker kRaw,
65*d57664e9SAndroid Build Coastguard Worker kString,
66*d57664e9SAndroid Build Coastguard Worker kStyle,
67*d57664e9SAndroid Build Coastguard Worker kStyleable,
68*d57664e9SAndroid Build Coastguard Worker kTransition,
69*d57664e9SAndroid Build Coastguard Worker kXml,
70*d57664e9SAndroid Build Coastguard Worker };
71*d57664e9SAndroid Build Coastguard Worker
72*d57664e9SAndroid Build Coastguard Worker enum class FlagStatus { NoFlag = 0, Disabled = 1, Enabled = 2 };
73*d57664e9SAndroid Build Coastguard Worker
74*d57664e9SAndroid Build Coastguard Worker struct FeatureFlagAttribute {
75*d57664e9SAndroid Build Coastguard Worker std::string name;
76*d57664e9SAndroid Build Coastguard Worker bool negated = false;
77*d57664e9SAndroid Build Coastguard Worker
ToStringFeatureFlagAttribute78*d57664e9SAndroid Build Coastguard Worker std::string ToString() {
79*d57664e9SAndroid Build Coastguard Worker return (negated ? "!" : "") + name;
80*d57664e9SAndroid Build Coastguard Worker }
81*d57664e9SAndroid Build Coastguard Worker
82*d57664e9SAndroid Build Coastguard Worker bool operator==(const FeatureFlagAttribute& o) const = default;
83*d57664e9SAndroid Build Coastguard Worker };
84*d57664e9SAndroid Build Coastguard Worker
85*d57664e9SAndroid Build Coastguard Worker android::StringPiece to_string(ResourceType type);
86*d57664e9SAndroid Build Coastguard Worker
87*d57664e9SAndroid Build Coastguard Worker /**
88*d57664e9SAndroid Build Coastguard Worker * Returns a pointer to a valid ResourceType, or nullptr if the string was invalid.
89*d57664e9SAndroid Build Coastguard Worker */
90*d57664e9SAndroid Build Coastguard Worker const ResourceType* ParseResourceType(android::StringPiece str);
91*d57664e9SAndroid Build Coastguard Worker
92*d57664e9SAndroid Build Coastguard Worker /**
93*d57664e9SAndroid Build Coastguard Worker * Pair of type name as in ResourceTable and actual resource type.
94*d57664e9SAndroid Build Coastguard Worker * Corresponds to the 'type' in package:type/entry.
95*d57664e9SAndroid Build Coastguard Worker *
96*d57664e9SAndroid Build Coastguard Worker * This is to support resource types with custom names inside resource tables.
97*d57664e9SAndroid Build Coastguard Worker */
98*d57664e9SAndroid Build Coastguard Worker struct ResourceNamedType {
99*d57664e9SAndroid Build Coastguard Worker std::string name;
100*d57664e9SAndroid Build Coastguard Worker ResourceType type = ResourceType::kRaw;
101*d57664e9SAndroid Build Coastguard Worker
102*d57664e9SAndroid Build Coastguard Worker ResourceNamedType() = default;
103*d57664e9SAndroid Build Coastguard Worker ResourceNamedType(android::StringPiece n, ResourceType t);
104*d57664e9SAndroid Build Coastguard Worker
105*d57664e9SAndroid Build Coastguard Worker int compare(const ResourceNamedType& other) const;
106*d57664e9SAndroid Build Coastguard Worker
107*d57664e9SAndroid Build Coastguard Worker const std::string& to_string() const;
108*d57664e9SAndroid Build Coastguard Worker };
109*d57664e9SAndroid Build Coastguard Worker
110*d57664e9SAndroid Build Coastguard Worker /**
111*d57664e9SAndroid Build Coastguard Worker * Same as ResourceNamedType, but uses StringPieces instead.
112*d57664e9SAndroid Build Coastguard Worker * Use this if you need to avoid copying and know that
113*d57664e9SAndroid Build Coastguard Worker * the lifetime of this object is shorter than that
114*d57664e9SAndroid Build Coastguard Worker * of the original string.
115*d57664e9SAndroid Build Coastguard Worker */
116*d57664e9SAndroid Build Coastguard Worker struct ResourceNamedTypeRef {
117*d57664e9SAndroid Build Coastguard Worker android::StringPiece name;
118*d57664e9SAndroid Build Coastguard Worker ResourceType type = ResourceType::kRaw;
119*d57664e9SAndroid Build Coastguard Worker
120*d57664e9SAndroid Build Coastguard Worker ResourceNamedTypeRef() = default;
121*d57664e9SAndroid Build Coastguard Worker ResourceNamedTypeRef(const ResourceNamedTypeRef&) = default;
122*d57664e9SAndroid Build Coastguard Worker ResourceNamedTypeRef(ResourceNamedTypeRef&&) = default;
123*d57664e9SAndroid Build Coastguard Worker ResourceNamedTypeRef(const ResourceNamedType& rhs); // NOLINT(google-explicit-constructor)
124*d57664e9SAndroid Build Coastguard Worker ResourceNamedTypeRef(android::StringPiece n, ResourceType t);
125*d57664e9SAndroid Build Coastguard Worker ResourceNamedTypeRef& operator=(const ResourceNamedTypeRef& rhs) = default;
126*d57664e9SAndroid Build Coastguard Worker ResourceNamedTypeRef& operator=(ResourceNamedTypeRef&& rhs) = default;
127*d57664e9SAndroid Build Coastguard Worker ResourceNamedTypeRef& operator=(const ResourceNamedType& rhs);
128*d57664e9SAndroid Build Coastguard Worker
129*d57664e9SAndroid Build Coastguard Worker ResourceNamedType ToResourceNamedType() const;
130*d57664e9SAndroid Build Coastguard Worker
131*d57664e9SAndroid Build Coastguard Worker std::string_view to_string() const;
132*d57664e9SAndroid Build Coastguard Worker };
133*d57664e9SAndroid Build Coastguard Worker
134*d57664e9SAndroid Build Coastguard Worker ResourceNamedTypeRef ResourceNamedTypeWithDefaultName(ResourceType t);
135*d57664e9SAndroid Build Coastguard Worker
136*d57664e9SAndroid Build Coastguard Worker std::optional<ResourceNamedTypeRef> ParseResourceNamedType(android::StringPiece s);
137*d57664e9SAndroid Build Coastguard Worker
138*d57664e9SAndroid Build Coastguard Worker /**
139*d57664e9SAndroid Build Coastguard Worker * A resource's name. This can uniquely identify
140*d57664e9SAndroid Build Coastguard Worker * a resource in the ResourceTable.
141*d57664e9SAndroid Build Coastguard Worker */
142*d57664e9SAndroid Build Coastguard Worker struct ResourceName {
143*d57664e9SAndroid Build Coastguard Worker std::string package;
144*d57664e9SAndroid Build Coastguard Worker ResourceNamedType type;
145*d57664e9SAndroid Build Coastguard Worker std::string entry;
146*d57664e9SAndroid Build Coastguard Worker
147*d57664e9SAndroid Build Coastguard Worker ResourceName() = default;
148*d57664e9SAndroid Build Coastguard Worker ResourceName(android::StringPiece p, const ResourceNamedTypeRef& t, android::StringPiece e);
149*d57664e9SAndroid Build Coastguard Worker ResourceName(android::StringPiece p, ResourceType t, android::StringPiece e);
150*d57664e9SAndroid Build Coastguard Worker
151*d57664e9SAndroid Build Coastguard Worker int compare(const ResourceName& other) const;
152*d57664e9SAndroid Build Coastguard Worker
153*d57664e9SAndroid Build Coastguard Worker bool is_valid() const;
154*d57664e9SAndroid Build Coastguard Worker std::string to_string() const;
155*d57664e9SAndroid Build Coastguard Worker };
156*d57664e9SAndroid Build Coastguard Worker
157*d57664e9SAndroid Build Coastguard Worker /**
158*d57664e9SAndroid Build Coastguard Worker * Same as ResourceName, but uses StringPieces instead.
159*d57664e9SAndroid Build Coastguard Worker * Use this if you need to avoid copying and know that
160*d57664e9SAndroid Build Coastguard Worker * the lifetime of this object is shorter than that
161*d57664e9SAndroid Build Coastguard Worker * of the original string.
162*d57664e9SAndroid Build Coastguard Worker */
163*d57664e9SAndroid Build Coastguard Worker struct ResourceNameRef {
164*d57664e9SAndroid Build Coastguard Worker android::StringPiece package;
165*d57664e9SAndroid Build Coastguard Worker ResourceNamedTypeRef type;
166*d57664e9SAndroid Build Coastguard Worker android::StringPiece entry;
167*d57664e9SAndroid Build Coastguard Worker
168*d57664e9SAndroid Build Coastguard Worker ResourceNameRef() = default;
169*d57664e9SAndroid Build Coastguard Worker ResourceNameRef(const ResourceNameRef&) = default;
170*d57664e9SAndroid Build Coastguard Worker ResourceNameRef(ResourceNameRef&&) = default;
171*d57664e9SAndroid Build Coastguard Worker ResourceNameRef(const ResourceName& rhs); // NOLINT(google-explicit-constructor)
172*d57664e9SAndroid Build Coastguard Worker ResourceNameRef(android::StringPiece p, const ResourceNamedTypeRef& t, android::StringPiece e);
173*d57664e9SAndroid Build Coastguard Worker ResourceNameRef(android::StringPiece p, ResourceType t, android::StringPiece e);
174*d57664e9SAndroid Build Coastguard Worker ResourceNameRef& operator=(const ResourceNameRef& rhs) = default;
175*d57664e9SAndroid Build Coastguard Worker ResourceNameRef& operator=(ResourceNameRef&& rhs) = default;
176*d57664e9SAndroid Build Coastguard Worker ResourceNameRef& operator=(const ResourceName& rhs);
177*d57664e9SAndroid Build Coastguard Worker
178*d57664e9SAndroid Build Coastguard Worker bool is_valid() const;
179*d57664e9SAndroid Build Coastguard Worker
180*d57664e9SAndroid Build Coastguard Worker ResourceName ToResourceName() const;
181*d57664e9SAndroid Build Coastguard Worker std::string to_string() const;
182*d57664e9SAndroid Build Coastguard Worker };
183*d57664e9SAndroid Build Coastguard Worker
184*d57664e9SAndroid Build Coastguard Worker constexpr const uint8_t kAppPackageId = 0x7fu;
185*d57664e9SAndroid Build Coastguard Worker constexpr const uint8_t kFrameworkPackageId = 0x01u;
186*d57664e9SAndroid Build Coastguard Worker
187*d57664e9SAndroid Build Coastguard Worker /**
188*d57664e9SAndroid Build Coastguard Worker * A binary identifier representing a resource. Internally it
189*d57664e9SAndroid Build Coastguard Worker * is a 32bit integer split as follows:
190*d57664e9SAndroid Build Coastguard Worker *
191*d57664e9SAndroid Build Coastguard Worker * 0xPPTTEEEE
192*d57664e9SAndroid Build Coastguard Worker *
193*d57664e9SAndroid Build Coastguard Worker * PP: 8 bit package identifier. 0x01 is reserved for system
194*d57664e9SAndroid Build Coastguard Worker * and 0x7f is reserved for the running app.
195*d57664e9SAndroid Build Coastguard Worker * TT: 8 bit type identifier. 0x00 is invalid.
196*d57664e9SAndroid Build Coastguard Worker * EEEE: 16 bit entry identifier.
197*d57664e9SAndroid Build Coastguard Worker */
198*d57664e9SAndroid Build Coastguard Worker struct ResourceId {
199*d57664e9SAndroid Build Coastguard Worker uint32_t id;
200*d57664e9SAndroid Build Coastguard Worker
201*d57664e9SAndroid Build Coastguard Worker ResourceId();
202*d57664e9SAndroid Build Coastguard Worker ResourceId(const ResourceId& rhs) = default;
203*d57664e9SAndroid Build Coastguard Worker ResourceId(uint32_t res_id); // NOLINT(google-explicit-constructor)
204*d57664e9SAndroid Build Coastguard Worker ResourceId(uint8_t p, uint8_t t, uint16_t e);
205*d57664e9SAndroid Build Coastguard Worker
206*d57664e9SAndroid Build Coastguard Worker // Returns true if the ID is a valid ID that is not dynamic (package ID cannot be 0)
207*d57664e9SAndroid Build Coastguard Worker bool is_valid_static() const;
208*d57664e9SAndroid Build Coastguard Worker
209*d57664e9SAndroid Build Coastguard Worker // Returns true if the ID is a valid ID or dynamic ID (package ID can be 0).
210*d57664e9SAndroid Build Coastguard Worker bool is_valid() const;
211*d57664e9SAndroid Build Coastguard Worker
212*d57664e9SAndroid Build Coastguard Worker uint8_t package_id() const;
213*d57664e9SAndroid Build Coastguard Worker uint8_t type_id() const;
214*d57664e9SAndroid Build Coastguard Worker uint16_t entry_id() const;
215*d57664e9SAndroid Build Coastguard Worker
216*d57664e9SAndroid Build Coastguard Worker std::string to_string() const;
217*d57664e9SAndroid Build Coastguard Worker };
218*d57664e9SAndroid Build Coastguard Worker
219*d57664e9SAndroid Build Coastguard Worker struct SourcedResourceName {
220*d57664e9SAndroid Build Coastguard Worker ResourceName name;
221*d57664e9SAndroid Build Coastguard Worker size_t line;
222*d57664e9SAndroid Build Coastguard Worker };
223*d57664e9SAndroid Build Coastguard Worker
224*d57664e9SAndroid Build Coastguard Worker struct ResourceFile {
225*d57664e9SAndroid Build Coastguard Worker enum class Type {
226*d57664e9SAndroid Build Coastguard Worker kUnknown,
227*d57664e9SAndroid Build Coastguard Worker kPng,
228*d57664e9SAndroid Build Coastguard Worker kBinaryXml,
229*d57664e9SAndroid Build Coastguard Worker kProtoXml,
230*d57664e9SAndroid Build Coastguard Worker };
231*d57664e9SAndroid Build Coastguard Worker
232*d57664e9SAndroid Build Coastguard Worker // Name
233*d57664e9SAndroid Build Coastguard Worker ResourceName name;
234*d57664e9SAndroid Build Coastguard Worker
235*d57664e9SAndroid Build Coastguard Worker // Configuration
236*d57664e9SAndroid Build Coastguard Worker android::ConfigDescription config;
237*d57664e9SAndroid Build Coastguard Worker
238*d57664e9SAndroid Build Coastguard Worker // Type
239*d57664e9SAndroid Build Coastguard Worker Type type;
240*d57664e9SAndroid Build Coastguard Worker
241*d57664e9SAndroid Build Coastguard Worker // Source
242*d57664e9SAndroid Build Coastguard Worker android::Source source;
243*d57664e9SAndroid Build Coastguard Worker
244*d57664e9SAndroid Build Coastguard Worker // Exported symbols
245*d57664e9SAndroid Build Coastguard Worker std::vector<SourcedResourceName> exported_symbols;
246*d57664e9SAndroid Build Coastguard Worker
247*d57664e9SAndroid Build Coastguard Worker // Flag status
248*d57664e9SAndroid Build Coastguard Worker FlagStatus flag_status = FlagStatus::NoFlag;
249*d57664e9SAndroid Build Coastguard Worker
250*d57664e9SAndroid Build Coastguard Worker // Flag
251*d57664e9SAndroid Build Coastguard Worker std::optional<FeatureFlagAttribute> flag;
252*d57664e9SAndroid Build Coastguard Worker };
253*d57664e9SAndroid Build Coastguard Worker
254*d57664e9SAndroid Build Coastguard Worker /**
255*d57664e9SAndroid Build Coastguard Worker * Useful struct used as a key to represent a unique resource in associative
256*d57664e9SAndroid Build Coastguard Worker * containers.
257*d57664e9SAndroid Build Coastguard Worker */
258*d57664e9SAndroid Build Coastguard Worker struct ResourceKey {
259*d57664e9SAndroid Build Coastguard Worker ResourceName name;
260*d57664e9SAndroid Build Coastguard Worker android::ConfigDescription config;
261*d57664e9SAndroid Build Coastguard Worker };
262*d57664e9SAndroid Build Coastguard Worker
263*d57664e9SAndroid Build Coastguard Worker bool operator<(const ResourceKey& a, const ResourceKey& b);
264*d57664e9SAndroid Build Coastguard Worker
265*d57664e9SAndroid Build Coastguard Worker /**
266*d57664e9SAndroid Build Coastguard Worker * Useful struct used as a key to represent a unique resource in associative
267*d57664e9SAndroid Build Coastguard Worker * containers.
268*d57664e9SAndroid Build Coastguard Worker * Holds a reference to the name, so that name better live longer than this key!
269*d57664e9SAndroid Build Coastguard Worker */
270*d57664e9SAndroid Build Coastguard Worker struct ResourceKeyRef {
271*d57664e9SAndroid Build Coastguard Worker ResourceNameRef name;
272*d57664e9SAndroid Build Coastguard Worker android::ConfigDescription config;
273*d57664e9SAndroid Build Coastguard Worker
274*d57664e9SAndroid Build Coastguard Worker ResourceKeyRef() = default;
ResourceKeyRefResourceKeyRef275*d57664e9SAndroid Build Coastguard Worker ResourceKeyRef(const ResourceNameRef& n, const android::ConfigDescription& c)
276*d57664e9SAndroid Build Coastguard Worker : name(n), config(c) {}
277*d57664e9SAndroid Build Coastguard Worker
278*d57664e9SAndroid Build Coastguard Worker /**
279*d57664e9SAndroid Build Coastguard Worker * Prevent taking a reference to a temporary. This is bad.
280*d57664e9SAndroid Build Coastguard Worker */
281*d57664e9SAndroid Build Coastguard Worker ResourceKeyRef(ResourceName&& n, const android::ConfigDescription& c) = delete;
282*d57664e9SAndroid Build Coastguard Worker };
283*d57664e9SAndroid Build Coastguard Worker
284*d57664e9SAndroid Build Coastguard Worker bool operator<(const ResourceKeyRef& a, const ResourceKeyRef& b);
285*d57664e9SAndroid Build Coastguard Worker
286*d57664e9SAndroid Build Coastguard Worker //
287*d57664e9SAndroid Build Coastguard Worker // ResourceId implementation.
288*d57664e9SAndroid Build Coastguard Worker //
289*d57664e9SAndroid Build Coastguard Worker
ResourceId()290*d57664e9SAndroid Build Coastguard Worker inline ResourceId::ResourceId() : id(0) {}
291*d57664e9SAndroid Build Coastguard Worker
ResourceId(uint32_t res_id)292*d57664e9SAndroid Build Coastguard Worker inline ResourceId::ResourceId(uint32_t res_id) : id(res_id) {}
293*d57664e9SAndroid Build Coastguard Worker
ResourceId(uint8_t p,uint8_t t,uint16_t e)294*d57664e9SAndroid Build Coastguard Worker inline ResourceId::ResourceId(uint8_t p, uint8_t t, uint16_t e)
295*d57664e9SAndroid Build Coastguard Worker : id((p << 24) | (t << 16) | e) {}
296*d57664e9SAndroid Build Coastguard Worker
is_valid_static()297*d57664e9SAndroid Build Coastguard Worker inline bool ResourceId::is_valid_static() const {
298*d57664e9SAndroid Build Coastguard Worker return (id & 0xff000000u) != 0 && (id & 0x00ff0000u) != 0;
299*d57664e9SAndroid Build Coastguard Worker }
300*d57664e9SAndroid Build Coastguard Worker
is_valid()301*d57664e9SAndroid Build Coastguard Worker inline bool ResourceId::is_valid() const {
302*d57664e9SAndroid Build Coastguard Worker return (id & 0x00ff0000u) != 0;
303*d57664e9SAndroid Build Coastguard Worker }
304*d57664e9SAndroid Build Coastguard Worker
package_id()305*d57664e9SAndroid Build Coastguard Worker inline uint8_t ResourceId::package_id() const {
306*d57664e9SAndroid Build Coastguard Worker return static_cast<uint8_t>(id >> 24);
307*d57664e9SAndroid Build Coastguard Worker }
308*d57664e9SAndroid Build Coastguard Worker
type_id()309*d57664e9SAndroid Build Coastguard Worker inline uint8_t ResourceId::type_id() const {
310*d57664e9SAndroid Build Coastguard Worker return static_cast<uint8_t>(id >> 16);
311*d57664e9SAndroid Build Coastguard Worker }
312*d57664e9SAndroid Build Coastguard Worker
entry_id()313*d57664e9SAndroid Build Coastguard Worker inline uint16_t ResourceId::entry_id() const {
314*d57664e9SAndroid Build Coastguard Worker return static_cast<uint16_t>(id);
315*d57664e9SAndroid Build Coastguard Worker }
316*d57664e9SAndroid Build Coastguard Worker
317*d57664e9SAndroid Build Coastguard Worker inline bool operator<(const ResourceId& lhs, const ResourceId& rhs) {
318*d57664e9SAndroid Build Coastguard Worker return lhs.id < rhs.id;
319*d57664e9SAndroid Build Coastguard Worker }
320*d57664e9SAndroid Build Coastguard Worker
321*d57664e9SAndroid Build Coastguard Worker inline bool operator>(const ResourceId& lhs, const ResourceId& rhs) {
322*d57664e9SAndroid Build Coastguard Worker return lhs.id > rhs.id;
323*d57664e9SAndroid Build Coastguard Worker }
324*d57664e9SAndroid Build Coastguard Worker
325*d57664e9SAndroid Build Coastguard Worker inline bool operator==(const ResourceId& lhs, const ResourceId& rhs) {
326*d57664e9SAndroid Build Coastguard Worker return lhs.id == rhs.id;
327*d57664e9SAndroid Build Coastguard Worker }
328*d57664e9SAndroid Build Coastguard Worker
329*d57664e9SAndroid Build Coastguard Worker inline bool operator!=(const ResourceId& lhs, const ResourceId& rhs) {
330*d57664e9SAndroid Build Coastguard Worker return lhs.id != rhs.id;
331*d57664e9SAndroid Build Coastguard Worker }
332*d57664e9SAndroid Build Coastguard Worker
333*d57664e9SAndroid Build Coastguard Worker inline ::std::ostream& operator<<(::std::ostream& out, const ResourceId& res_id) {
334*d57664e9SAndroid Build Coastguard Worker return out << res_id.to_string();
335*d57664e9SAndroid Build Coastguard Worker }
336*d57664e9SAndroid Build Coastguard Worker
337*d57664e9SAndroid Build Coastguard Worker // For generic code to call 'using std::to_string; to_string(T);'.
to_string(const ResourceId & id)338*d57664e9SAndroid Build Coastguard Worker inline std::string to_string(const ResourceId& id) {
339*d57664e9SAndroid Build Coastguard Worker return id.to_string();
340*d57664e9SAndroid Build Coastguard Worker }
341*d57664e9SAndroid Build Coastguard Worker
342*d57664e9SAndroid Build Coastguard Worker // Helper to compare resource IDs, moving dynamic IDs after framework IDs.
cmp_ids_dynamic_after_framework(const ResourceId & a,const ResourceId & b)343*d57664e9SAndroid Build Coastguard Worker inline bool cmp_ids_dynamic_after_framework(const ResourceId& a, const ResourceId& b) {
344*d57664e9SAndroid Build Coastguard Worker // If one of a and b is from the framework package (package ID 0x01), and the
345*d57664e9SAndroid Build Coastguard Worker // other is a dynamic ID (package ID 0x00), then put the dynamic ID after the
346*d57664e9SAndroid Build Coastguard Worker // framework ID. This ensures that when AssetManager resolves the dynamic IDs,
347*d57664e9SAndroid Build Coastguard Worker // they will be in sorted order as expected by AssetManager.
348*d57664e9SAndroid Build Coastguard Worker if ((a.package_id() == kFrameworkPackageId && b.package_id() == 0x00) ||
349*d57664e9SAndroid Build Coastguard Worker (a.package_id() == 0x00 && b.package_id() == kFrameworkPackageId)) {
350*d57664e9SAndroid Build Coastguard Worker return b < a;
351*d57664e9SAndroid Build Coastguard Worker }
352*d57664e9SAndroid Build Coastguard Worker return a < b;
353*d57664e9SAndroid Build Coastguard Worker }
354*d57664e9SAndroid Build Coastguard Worker
355*d57664e9SAndroid Build Coastguard Worker //
356*d57664e9SAndroid Build Coastguard Worker // ResourceType implementation.
357*d57664e9SAndroid Build Coastguard Worker //
358*d57664e9SAndroid Build Coastguard Worker
359*d57664e9SAndroid Build Coastguard Worker inline ::std::ostream& operator<<(::std::ostream& out, const ResourceType& val) {
360*d57664e9SAndroid Build Coastguard Worker return out << to_string(val);
361*d57664e9SAndroid Build Coastguard Worker }
362*d57664e9SAndroid Build Coastguard Worker
363*d57664e9SAndroid Build Coastguard Worker //
364*d57664e9SAndroid Build Coastguard Worker // ResourceNamedType implementation.
365*d57664e9SAndroid Build Coastguard Worker //
ResourceNamedType(android::StringPiece n,ResourceType t)366*d57664e9SAndroid Build Coastguard Worker inline ResourceNamedType::ResourceNamedType(android::StringPiece n, ResourceType t)
367*d57664e9SAndroid Build Coastguard Worker : name(n), type(t) {
368*d57664e9SAndroid Build Coastguard Worker }
369*d57664e9SAndroid Build Coastguard Worker
compare(const ResourceNamedType & other)370*d57664e9SAndroid Build Coastguard Worker inline int ResourceNamedType::compare(const ResourceNamedType& other) const {
371*d57664e9SAndroid Build Coastguard Worker int cmp = static_cast<int>(type) - static_cast<int>(other.type);
372*d57664e9SAndroid Build Coastguard Worker if (cmp != 0) return cmp;
373*d57664e9SAndroid Build Coastguard Worker cmp = name.compare(other.name);
374*d57664e9SAndroid Build Coastguard Worker return cmp;
375*d57664e9SAndroid Build Coastguard Worker }
376*d57664e9SAndroid Build Coastguard Worker
to_string()377*d57664e9SAndroid Build Coastguard Worker inline const std::string& ResourceNamedType::to_string() const {
378*d57664e9SAndroid Build Coastguard Worker return name;
379*d57664e9SAndroid Build Coastguard Worker }
380*d57664e9SAndroid Build Coastguard Worker
381*d57664e9SAndroid Build Coastguard Worker inline bool operator<(const ResourceNamedType& lhs, const ResourceNamedType& rhs) {
382*d57664e9SAndroid Build Coastguard Worker return lhs.compare(rhs) < 0;
383*d57664e9SAndroid Build Coastguard Worker }
384*d57664e9SAndroid Build Coastguard Worker
385*d57664e9SAndroid Build Coastguard Worker inline bool operator==(const ResourceNamedType& lhs, const ResourceNamedType& rhs) {
386*d57664e9SAndroid Build Coastguard Worker return lhs.compare(rhs) == 0;
387*d57664e9SAndroid Build Coastguard Worker }
388*d57664e9SAndroid Build Coastguard Worker
389*d57664e9SAndroid Build Coastguard Worker inline bool operator!=(const ResourceNamedType& lhs, const ResourceNamedType& rhs) {
390*d57664e9SAndroid Build Coastguard Worker return lhs.compare(rhs) != 0;
391*d57664e9SAndroid Build Coastguard Worker }
392*d57664e9SAndroid Build Coastguard Worker
393*d57664e9SAndroid Build Coastguard Worker inline ::std::ostream& operator<<(::std::ostream& out, const ResourceNamedType& val) {
394*d57664e9SAndroid Build Coastguard Worker return out << val.to_string();
395*d57664e9SAndroid Build Coastguard Worker }
396*d57664e9SAndroid Build Coastguard Worker
397*d57664e9SAndroid Build Coastguard Worker //
398*d57664e9SAndroid Build Coastguard Worker // ResourceNamedTypeRef implementation.
399*d57664e9SAndroid Build Coastguard Worker //
ResourceNamedTypeRef(android::StringPiece n,ResourceType t)400*d57664e9SAndroid Build Coastguard Worker inline ResourceNamedTypeRef::ResourceNamedTypeRef(android::StringPiece n, ResourceType t)
401*d57664e9SAndroid Build Coastguard Worker : name(n), type(t) {
402*d57664e9SAndroid Build Coastguard Worker }
403*d57664e9SAndroid Build Coastguard Worker
ResourceNamedTypeRef(const ResourceNamedType & rhs)404*d57664e9SAndroid Build Coastguard Worker inline ResourceNamedTypeRef::ResourceNamedTypeRef(const ResourceNamedType& rhs)
405*d57664e9SAndroid Build Coastguard Worker : name(rhs.name), type(rhs.type) {
406*d57664e9SAndroid Build Coastguard Worker }
407*d57664e9SAndroid Build Coastguard Worker
408*d57664e9SAndroid Build Coastguard Worker inline ResourceNamedTypeRef& ResourceNamedTypeRef::operator=(const ResourceNamedType& rhs) {
409*d57664e9SAndroid Build Coastguard Worker name = rhs.name;
410*d57664e9SAndroid Build Coastguard Worker type = rhs.type;
411*d57664e9SAndroid Build Coastguard Worker return *this;
412*d57664e9SAndroid Build Coastguard Worker }
413*d57664e9SAndroid Build Coastguard Worker
ToResourceNamedType()414*d57664e9SAndroid Build Coastguard Worker inline ResourceNamedType ResourceNamedTypeRef::ToResourceNamedType() const {
415*d57664e9SAndroid Build Coastguard Worker return ResourceNamedType(name, type);
416*d57664e9SAndroid Build Coastguard Worker }
417*d57664e9SAndroid Build Coastguard Worker
to_string()418*d57664e9SAndroid Build Coastguard Worker inline std::string_view ResourceNamedTypeRef::to_string() const {
419*d57664e9SAndroid Build Coastguard Worker return name;
420*d57664e9SAndroid Build Coastguard Worker }
421*d57664e9SAndroid Build Coastguard Worker
422*d57664e9SAndroid Build Coastguard Worker inline bool operator<(const ResourceNamedTypeRef& lhs, const ResourceNamedTypeRef& rhs) {
423*d57664e9SAndroid Build Coastguard Worker return std::tie(lhs.type, lhs.name) < std::tie(rhs.type, rhs.name);
424*d57664e9SAndroid Build Coastguard Worker }
425*d57664e9SAndroid Build Coastguard Worker
426*d57664e9SAndroid Build Coastguard Worker inline bool operator==(const ResourceNamedTypeRef& lhs, const ResourceNamedTypeRef& rhs) {
427*d57664e9SAndroid Build Coastguard Worker return std::tie(lhs.type, lhs.name) == std::tie(rhs.type, rhs.name);
428*d57664e9SAndroid Build Coastguard Worker }
429*d57664e9SAndroid Build Coastguard Worker
430*d57664e9SAndroid Build Coastguard Worker inline bool operator!=(const ResourceNamedTypeRef& lhs, const ResourceNamedTypeRef& rhs) {
431*d57664e9SAndroid Build Coastguard Worker return std::tie(lhs.type, lhs.name) != std::tie(rhs.type, rhs.name);
432*d57664e9SAndroid Build Coastguard Worker }
433*d57664e9SAndroid Build Coastguard Worker
434*d57664e9SAndroid Build Coastguard Worker inline ::std::ostream& operator<<(::std::ostream& out, const ResourceNamedTypeRef& val) {
435*d57664e9SAndroid Build Coastguard Worker return out << val.name;
436*d57664e9SAndroid Build Coastguard Worker }
437*d57664e9SAndroid Build Coastguard Worker
438*d57664e9SAndroid Build Coastguard Worker //
439*d57664e9SAndroid Build Coastguard Worker // ResourceName implementation.
440*d57664e9SAndroid Build Coastguard Worker //
441*d57664e9SAndroid Build Coastguard Worker
ResourceName(android::StringPiece p,const ResourceNamedTypeRef & t,android::StringPiece e)442*d57664e9SAndroid Build Coastguard Worker inline ResourceName::ResourceName(android::StringPiece p, const ResourceNamedTypeRef& t,
443*d57664e9SAndroid Build Coastguard Worker android::StringPiece e)
444*d57664e9SAndroid Build Coastguard Worker : package(p), type(t.ToResourceNamedType()), entry(e) {
445*d57664e9SAndroid Build Coastguard Worker }
446*d57664e9SAndroid Build Coastguard Worker
ResourceName(android::StringPiece p,ResourceType t,android::StringPiece e)447*d57664e9SAndroid Build Coastguard Worker inline ResourceName::ResourceName(android::StringPiece p, ResourceType t, android::StringPiece e)
448*d57664e9SAndroid Build Coastguard Worker : ResourceName(p, ResourceNamedTypeWithDefaultName(t), e) {
449*d57664e9SAndroid Build Coastguard Worker }
450*d57664e9SAndroid Build Coastguard Worker
compare(const ResourceName & other)451*d57664e9SAndroid Build Coastguard Worker inline int ResourceName::compare(const ResourceName& other) const {
452*d57664e9SAndroid Build Coastguard Worker int cmp = package.compare(other.package);
453*d57664e9SAndroid Build Coastguard Worker if (cmp != 0) return cmp;
454*d57664e9SAndroid Build Coastguard Worker cmp = type.compare(other.type);
455*d57664e9SAndroid Build Coastguard Worker if (cmp != 0) return cmp;
456*d57664e9SAndroid Build Coastguard Worker cmp = entry.compare(other.entry);
457*d57664e9SAndroid Build Coastguard Worker return cmp;
458*d57664e9SAndroid Build Coastguard Worker }
459*d57664e9SAndroid Build Coastguard Worker
is_valid()460*d57664e9SAndroid Build Coastguard Worker inline bool ResourceName::is_valid() const {
461*d57664e9SAndroid Build Coastguard Worker return !package.empty() && !entry.empty();
462*d57664e9SAndroid Build Coastguard Worker }
463*d57664e9SAndroid Build Coastguard Worker
464*d57664e9SAndroid Build Coastguard Worker inline bool operator<(const ResourceName& lhs, const ResourceName& rhs) {
465*d57664e9SAndroid Build Coastguard Worker return std::tie(lhs.package, lhs.type, lhs.entry) <
466*d57664e9SAndroid Build Coastguard Worker std::tie(rhs.package, rhs.type, rhs.entry);
467*d57664e9SAndroid Build Coastguard Worker }
468*d57664e9SAndroid Build Coastguard Worker
469*d57664e9SAndroid Build Coastguard Worker inline bool operator==(const ResourceName& lhs, const ResourceName& rhs) {
470*d57664e9SAndroid Build Coastguard Worker return std::tie(lhs.package, lhs.type, lhs.entry) ==
471*d57664e9SAndroid Build Coastguard Worker std::tie(rhs.package, rhs.type, rhs.entry);
472*d57664e9SAndroid Build Coastguard Worker }
473*d57664e9SAndroid Build Coastguard Worker
474*d57664e9SAndroid Build Coastguard Worker inline bool operator!=(const ResourceName& lhs, const ResourceName& rhs) {
475*d57664e9SAndroid Build Coastguard Worker return std::tie(lhs.package, lhs.type, lhs.entry) !=
476*d57664e9SAndroid Build Coastguard Worker std::tie(rhs.package, rhs.type, rhs.entry);
477*d57664e9SAndroid Build Coastguard Worker }
478*d57664e9SAndroid Build Coastguard Worker
479*d57664e9SAndroid Build Coastguard Worker inline ::std::ostream& operator<<(::std::ostream& out, const ResourceName& name) {
480*d57664e9SAndroid Build Coastguard Worker return out << name.to_string();
481*d57664e9SAndroid Build Coastguard Worker }
482*d57664e9SAndroid Build Coastguard Worker
483*d57664e9SAndroid Build Coastguard Worker //
484*d57664e9SAndroid Build Coastguard Worker // ResourceNameRef implementation.
485*d57664e9SAndroid Build Coastguard Worker //
486*d57664e9SAndroid Build Coastguard Worker
ResourceNameRef(const ResourceName & rhs)487*d57664e9SAndroid Build Coastguard Worker inline ResourceNameRef::ResourceNameRef(const ResourceName& rhs)
488*d57664e9SAndroid Build Coastguard Worker : package(rhs.package), type(rhs.type), entry(rhs.entry) {}
489*d57664e9SAndroid Build Coastguard Worker
ResourceNameRef(android::StringPiece p,const ResourceNamedTypeRef & t,android::StringPiece e)490*d57664e9SAndroid Build Coastguard Worker inline ResourceNameRef::ResourceNameRef(android::StringPiece p, const ResourceNamedTypeRef& t,
491*d57664e9SAndroid Build Coastguard Worker android::StringPiece e)
492*d57664e9SAndroid Build Coastguard Worker : package(p), type(t), entry(e) {
493*d57664e9SAndroid Build Coastguard Worker }
494*d57664e9SAndroid Build Coastguard Worker
ResourceNameRef(android::StringPiece p,ResourceType t,android::StringPiece e)495*d57664e9SAndroid Build Coastguard Worker inline ResourceNameRef::ResourceNameRef(android::StringPiece p, ResourceType t,
496*d57664e9SAndroid Build Coastguard Worker android::StringPiece e)
497*d57664e9SAndroid Build Coastguard Worker : ResourceNameRef(p, ResourceNamedTypeWithDefaultName(t), e) {
498*d57664e9SAndroid Build Coastguard Worker }
499*d57664e9SAndroid Build Coastguard Worker
500*d57664e9SAndroid Build Coastguard Worker inline ResourceNameRef& ResourceNameRef::operator=(const ResourceName& rhs) {
501*d57664e9SAndroid Build Coastguard Worker package = rhs.package;
502*d57664e9SAndroid Build Coastguard Worker type = rhs.type;
503*d57664e9SAndroid Build Coastguard Worker entry = rhs.entry;
504*d57664e9SAndroid Build Coastguard Worker return *this;
505*d57664e9SAndroid Build Coastguard Worker }
506*d57664e9SAndroid Build Coastguard Worker
ToResourceName()507*d57664e9SAndroid Build Coastguard Worker inline ResourceName ResourceNameRef::ToResourceName() const {
508*d57664e9SAndroid Build Coastguard Worker return ResourceName(package, type, entry);
509*d57664e9SAndroid Build Coastguard Worker }
510*d57664e9SAndroid Build Coastguard Worker
is_valid()511*d57664e9SAndroid Build Coastguard Worker inline bool ResourceNameRef::is_valid() const {
512*d57664e9SAndroid Build Coastguard Worker return !package.empty() && !entry.empty();
513*d57664e9SAndroid Build Coastguard Worker }
514*d57664e9SAndroid Build Coastguard Worker
515*d57664e9SAndroid Build Coastguard Worker inline bool operator<(const ResourceNameRef& lhs, const ResourceNameRef& rhs) {
516*d57664e9SAndroid Build Coastguard Worker return std::tie(lhs.package, lhs.type, lhs.entry) <
517*d57664e9SAndroid Build Coastguard Worker std::tie(rhs.package, rhs.type, rhs.entry);
518*d57664e9SAndroid Build Coastguard Worker }
519*d57664e9SAndroid Build Coastguard Worker
520*d57664e9SAndroid Build Coastguard Worker inline bool operator==(const ResourceNameRef& lhs, const ResourceNameRef& rhs) {
521*d57664e9SAndroid Build Coastguard Worker return std::tie(lhs.package, lhs.type, lhs.entry) ==
522*d57664e9SAndroid Build Coastguard Worker std::tie(rhs.package, rhs.type, rhs.entry);
523*d57664e9SAndroid Build Coastguard Worker }
524*d57664e9SAndroid Build Coastguard Worker
525*d57664e9SAndroid Build Coastguard Worker inline bool operator!=(const ResourceNameRef& lhs, const ResourceNameRef& rhs) {
526*d57664e9SAndroid Build Coastguard Worker return std::tie(lhs.package, lhs.type, lhs.entry) !=
527*d57664e9SAndroid Build Coastguard Worker std::tie(rhs.package, rhs.type, rhs.entry);
528*d57664e9SAndroid Build Coastguard Worker }
529*d57664e9SAndroid Build Coastguard Worker
530*d57664e9SAndroid Build Coastguard Worker inline ::std::ostream& operator<<(::std::ostream& out, const ResourceNameRef& name) {
531*d57664e9SAndroid Build Coastguard Worker return out << name.to_string();
532*d57664e9SAndroid Build Coastguard Worker }
533*d57664e9SAndroid Build Coastguard Worker
534*d57664e9SAndroid Build Coastguard Worker inline bool operator<(const ResourceName& lhs, const ResourceNameRef& b) {
535*d57664e9SAndroid Build Coastguard Worker return ResourceNameRef(lhs) < b;
536*d57664e9SAndroid Build Coastguard Worker }
537*d57664e9SAndroid Build Coastguard Worker
538*d57664e9SAndroid Build Coastguard Worker inline bool operator!=(const ResourceName& lhs, const ResourceNameRef& rhs) {
539*d57664e9SAndroid Build Coastguard Worker return ResourceNameRef(lhs) != rhs;
540*d57664e9SAndroid Build Coastguard Worker }
541*d57664e9SAndroid Build Coastguard Worker
542*d57664e9SAndroid Build Coastguard Worker inline bool operator==(const SourcedResourceName& lhs, const SourcedResourceName& rhs) {
543*d57664e9SAndroid Build Coastguard Worker return lhs.name == rhs.name && lhs.line == rhs.line;
544*d57664e9SAndroid Build Coastguard Worker }
545*d57664e9SAndroid Build Coastguard Worker
546*d57664e9SAndroid Build Coastguard Worker } // namespace aapt
547*d57664e9SAndroid Build Coastguard Worker
548*d57664e9SAndroid Build Coastguard Worker namespace std {
549*d57664e9SAndroid Build Coastguard Worker
550*d57664e9SAndroid Build Coastguard Worker template <>
551*d57664e9SAndroid Build Coastguard Worker struct hash<aapt::ResourceName> {
552*d57664e9SAndroid Build Coastguard Worker size_t operator()(const aapt::ResourceName& name) const {
553*d57664e9SAndroid Build Coastguard Worker android::hash_t h = 0;
554*d57664e9SAndroid Build Coastguard Worker h = android::JenkinsHashMix(h, static_cast<uint32_t>(hash<string>()(name.package)));
555*d57664e9SAndroid Build Coastguard Worker h = android::JenkinsHashMix(h, static_cast<uint32_t>(hash<string>()(name.type.name)));
556*d57664e9SAndroid Build Coastguard Worker h = android::JenkinsHashMix(h, static_cast<uint32_t>(hash<string>()(name.entry)));
557*d57664e9SAndroid Build Coastguard Worker return static_cast<size_t>(h);
558*d57664e9SAndroid Build Coastguard Worker }
559*d57664e9SAndroid Build Coastguard Worker };
560*d57664e9SAndroid Build Coastguard Worker
561*d57664e9SAndroid Build Coastguard Worker template <>
562*d57664e9SAndroid Build Coastguard Worker struct hash<aapt::ResourceId> {
563*d57664e9SAndroid Build Coastguard Worker size_t operator()(const aapt::ResourceId& id) const {
564*d57664e9SAndroid Build Coastguard Worker return id.id;
565*d57664e9SAndroid Build Coastguard Worker }
566*d57664e9SAndroid Build Coastguard Worker };
567*d57664e9SAndroid Build Coastguard Worker
568*d57664e9SAndroid Build Coastguard Worker } // namespace std
569*d57664e9SAndroid Build Coastguard Worker
570*d57664e9SAndroid Build Coastguard Worker #endif // AAPT_RESOURCE_H
571