blob: 2969b8ccbc40dc4bfada197213d7d7f2933094fc [file] [log] [blame]
Adam Lesinski6f6ceb72014-11-14 14:48:12 -08001/*
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_RESOURCE_H
18#define AAPT_RESOURCE_H
19
Adam Lesinski1ab598f2015-08-14 14:26:04 -070020#include "ConfigDescription.h"
21#include "Source.h"
Adam Lesinski1ab598f2015-08-14 14:26:04 -070022#include "util/StringPiece.h"
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080023
Adam Lesinskibf0bd0f2016-06-01 15:31:50 -070024#include <utils/JenkinsHash.h>
25
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080026#include <iomanip>
Adam Lesinskica2fc352015-04-03 12:08:26 -070027#include <limits>
Adam Lesinskid0f116b2016-07-08 15:00:32 -070028#include <sstream>
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080029#include <string>
30#include <tuple>
Adam Lesinski1ab598f2015-08-14 14:26:04 -070031#include <vector>
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080032
33namespace aapt {
34
35/**
36 * The various types of resource types available. Corresponds
37 * to the 'type' in package:type/entry.
38 */
39enum class ResourceType {
40 kAnim,
41 kAnimator,
42 kArray,
43 kAttr,
44 kAttrPrivate,
45 kBool,
46 kColor,
47 kDimen,
48 kDrawable,
49 kFraction,
50 kId,
51 kInteger,
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080052 kInterpolator,
53 kLayout,
54 kMenu,
55 kMipmap,
56 kPlurals,
57 kRaw,
58 kString,
59 kStyle,
60 kStyleable,
61 kTransition,
62 kXml,
63};
64
Adam Lesinskid0f116b2016-07-08 15:00:32 -070065StringPiece toString(ResourceType type);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080066
67/**
68 * Returns a pointer to a valid ResourceType, or nullptr if
69 * the string was invalid.
70 */
Adam Lesinskid0f116b2016-07-08 15:00:32 -070071const ResourceType* parseResourceType(const StringPiece& str);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080072
73/**
74 * A resource's name. This can uniquely identify
75 * a resource in the ResourceTable.
76 */
77struct ResourceName {
Adam Lesinskid0f116b2016-07-08 15:00:32 -070078 std::string package;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080079 ResourceType type;
Adam Lesinskid0f116b2016-07-08 15:00:32 -070080 std::string entry;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080081
Adam Lesinski96917c22016-03-09 13:11:25 -080082 ResourceName() : type(ResourceType::kRaw) {}
Adam Lesinskid0f116b2016-07-08 15:00:32 -070083 ResourceName(const StringPiece& p, ResourceType t, const StringPiece& e);
Adam Lesinski9ba47d82015-10-13 11:37:10 -070084
Adam Lesinski8197cc462016-08-19 12:16:49 -070085 int compare(const ResourceName& other) const;
86
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080087 bool isValid() const;
Adam Lesinskid0f116b2016-07-08 15:00:32 -070088 std::string toString() const;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080089};
90
91/**
92 * Same as ResourceName, but uses StringPieces instead.
93 * Use this if you need to avoid copying and know that
94 * the lifetime of this object is shorter than that
95 * of the original string.
96 */
97struct ResourceNameRef {
Adam Lesinskid0f116b2016-07-08 15:00:32 -070098 StringPiece package;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080099 ResourceType type;
Adam Lesinskid0f116b2016-07-08 15:00:32 -0700100 StringPiece entry;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800101
102 ResourceNameRef() = default;
103 ResourceNameRef(const ResourceNameRef&) = default;
104 ResourceNameRef(ResourceNameRef&&) = default;
Chih-Hung Hsieh9b8528f2016-08-10 14:15:30 -0700105 ResourceNameRef(const ResourceName& rhs); // NOLINT(implicit)
Adam Lesinskid0f116b2016-07-08 15:00:32 -0700106 ResourceNameRef(const StringPiece& p, ResourceType t, const StringPiece& e);
Adam Lesinski838a6872015-05-01 13:14:05 -0700107 ResourceNameRef& operator=(const ResourceNameRef& rhs) = default;
108 ResourceNameRef& operator=(ResourceNameRef&& rhs) = default;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800109 ResourceNameRef& operator=(const ResourceName& rhs);
110
111 ResourceName toResourceName() const;
112 bool isValid() const;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800113};
114
115/**
116 * A binary identifier representing a resource. Internally it
117 * is a 32bit integer split as follows:
118 *
119 * 0xPPTTEEEE
120 *
121 * PP: 8 bit package identifier. 0x01 is reserved for system
122 * and 0x7f is reserved for the running app.
123 * TT: 8 bit type identifier. 0x00 is invalid.
124 * EEEE: 16 bit entry identifier.
125 */
126struct ResourceId {
127 uint32_t id;
128
129 ResourceId();
130 ResourceId(const ResourceId& rhs);
Chih-Hung Hsieh9b8528f2016-08-10 14:15:30 -0700131 ResourceId(uint32_t resId); // NOLINT(implicit)
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700132 ResourceId(uint8_t p, uint8_t t, uint16_t e);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800133
134 bool isValid() const;
135 uint8_t packageId() const;
136 uint8_t typeId() const;
137 uint16_t entryId() const;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800138};
139
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700140struct SourcedResourceName {
141 ResourceName name;
142 size_t line;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700143};
144
145struct ResourceFile {
146 // Name
147 ResourceName name;
148
149 // Configuration
150 ConfigDescription config;
151
152 // Source
153 Source source;
154
155 // Exported symbols
156 std::vector<SourcedResourceName> exportedSymbols;
157};
158
Adam Lesinskia6fe3452015-12-09 15:20:52 -0800159/**
160 * Useful struct used as a key to represent a unique resource in associative containers.
161 */
162struct ResourceKey {
163 ResourceName name;
164 ConfigDescription config;
165};
166
167bool operator<(const ResourceKey& a, const ResourceKey& b);
168
169/**
170 * Useful struct used as a key to represent a unique resource in associative containers.
171 * Holds a reference to the name, so that name better live longer than this key!
172 */
173struct ResourceKeyRef {
174 ResourceNameRef name;
175 ConfigDescription config;
176
177 ResourceKeyRef() = default;
178 ResourceKeyRef(const ResourceNameRef& n, const ConfigDescription& c) : name(n), config(c) {
179 }
180
181 /**
182 * Prevent taking a reference to a temporary. This is bad.
183 */
184 ResourceKeyRef(ResourceName&& n, const ConfigDescription& c) = delete;
185};
186
187bool operator<(const ResourceKeyRef& a, const ResourceKeyRef& b);
188
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800189//
190// ResourceId implementation.
191//
192
193inline ResourceId::ResourceId() : id(0) {
194}
195
196inline ResourceId::ResourceId(const ResourceId& rhs) : id(rhs.id) {
197}
198
199inline ResourceId::ResourceId(uint32_t resId) : id(resId) {
200}
201
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700202inline ResourceId::ResourceId(uint8_t p, uint8_t t, uint16_t e) : id((p << 24) | (t << 16) | e) {
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800203}
204
205inline bool ResourceId::isValid() const {
206 return (id & 0xff000000u) != 0 && (id & 0x00ff0000u) != 0;
207}
208
209inline uint8_t ResourceId::packageId() const {
210 return static_cast<uint8_t>(id >> 24);
211}
212
213inline uint8_t ResourceId::typeId() const {
214 return static_cast<uint8_t>(id >> 16);
215}
216
217inline uint16_t ResourceId::entryId() const {
218 return static_cast<uint16_t>(id);
219}
220
Adam Lesinski74605cd2016-03-03 15:39:50 -0800221inline bool operator<(const ResourceId& lhs, const ResourceId& rhs) {
222 return lhs.id < rhs.id;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800223}
224
Adam Lesinski74605cd2016-03-03 15:39:50 -0800225inline bool operator>(const ResourceId& lhs, const ResourceId& rhs) {
226 return lhs.id > rhs.id;
Adam Lesinski24aad162015-04-24 19:19:30 -0700227}
228
Adam Lesinski74605cd2016-03-03 15:39:50 -0800229inline bool operator==(const ResourceId& lhs, const ResourceId& rhs) {
230 return lhs.id == rhs.id;
231}
232
233inline bool operator!=(const ResourceId& lhs, const ResourceId& rhs) {
234 return lhs.id != rhs.id;
235}
236
237inline ::std::ostream& operator<<(::std::ostream& out, const ResourceId& resId) {
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800238 std::ios_base::fmtflags oldFlags = out.flags();
239 char oldFill = out.fill();
240 out << "0x" << std::internal << std::setfill('0') << std::setw(8)
241 << std::hex << resId.id;
242 out.flags(oldFlags);
243 out.fill(oldFill);
244 return out;
245}
246
247//
248// ResourceType implementation.
249//
250
Adam Lesinski769de982015-04-10 19:43:55 -0700251inline ::std::ostream& operator<<(::std::ostream& out, const ResourceType& val) {
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800252 return out << toString(val);
253}
254
255//
256// ResourceName implementation.
257//
258
Adam Lesinskid0f116b2016-07-08 15:00:32 -0700259inline ResourceName::ResourceName(const StringPiece& p, ResourceType t, const StringPiece& e) :
Adam Lesinski9ba47d82015-10-13 11:37:10 -0700260 package(p.toString()), type(t), entry(e.toString()) {
261}
262
Adam Lesinski8197cc462016-08-19 12:16:49 -0700263inline int ResourceName::compare(const ResourceName& other) const {
264 int cmp = package.compare(other.package);
265 if (cmp != 0) return cmp;
266 cmp = static_cast<int>(type) - static_cast<int>(other.type);
267 if (cmp != 0) return cmp;
268 cmp = entry.compare(other.entry);
269 return cmp;
270}
271
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800272inline bool ResourceName::isValid() const {
273 return !package.empty() && !entry.empty();
274}
275
Adam Lesinski74605cd2016-03-03 15:39:50 -0800276inline bool operator<(const ResourceName& lhs, const ResourceName& rhs) {
277 return std::tie(lhs.package, lhs.type, lhs.entry)
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800278 < std::tie(rhs.package, rhs.type, rhs.entry);
279}
280
Adam Lesinski74605cd2016-03-03 15:39:50 -0800281inline bool operator==(const ResourceName& lhs, const ResourceName& rhs) {
282 return std::tie(lhs.package, lhs.type, lhs.entry)
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800283 == std::tie(rhs.package, rhs.type, rhs.entry);
284}
285
Adam Lesinski74605cd2016-03-03 15:39:50 -0800286inline bool operator!=(const ResourceName& lhs, const ResourceName& rhs) {
287 return std::tie(lhs.package, lhs.type, lhs.entry)
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800288 != std::tie(rhs.package, rhs.type, rhs.entry);
289}
290
Adam Lesinski769de982015-04-10 19:43:55 -0700291inline ::std::ostream& operator<<(::std::ostream& out, const ResourceName& name) {
292 if (!name.package.empty()) {
293 out << name.package << ":";
294 }
295 return out << name.type << "/" << name.entry;
296}
297
Adam Lesinskid0f116b2016-07-08 15:00:32 -0700298inline std::string ResourceName::toString() const {
299 std::stringstream stream;
300 stream << *this;
301 return stream.str();
302}
Adam Lesinski769de982015-04-10 19:43:55 -0700303
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800304//
305// ResourceNameRef implementation.
306//
307
308inline ResourceNameRef::ResourceNameRef(const ResourceName& rhs) :
309 package(rhs.package), type(rhs.type), entry(rhs.entry) {
310}
311
Adam Lesinskid0f116b2016-07-08 15:00:32 -0700312inline ResourceNameRef::ResourceNameRef(const StringPiece& p, ResourceType t,
313 const StringPiece& e) :
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800314 package(p), type(t), entry(e) {
315}
316
317inline ResourceNameRef& ResourceNameRef::operator=(const ResourceName& rhs) {
318 package = rhs.package;
319 type = rhs.type;
320 entry = rhs.entry;
321 return *this;
322}
323
324inline ResourceName ResourceNameRef::toResourceName() const {
Adam Lesinskid0f116b2016-07-08 15:00:32 -0700325 return ResourceName(package, type, entry);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800326}
327
328inline bool ResourceNameRef::isValid() const {
329 return !package.empty() && !entry.empty();
330}
331
Adam Lesinski74605cd2016-03-03 15:39:50 -0800332inline bool operator<(const ResourceNameRef& lhs, const ResourceNameRef& rhs) {
333 return std::tie(lhs.package, lhs.type, lhs.entry)
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800334 < std::tie(rhs.package, rhs.type, rhs.entry);
335}
336
Adam Lesinski74605cd2016-03-03 15:39:50 -0800337inline bool operator==(const ResourceNameRef& lhs, const ResourceNameRef& rhs) {
338 return std::tie(lhs.package, lhs.type, lhs.entry)
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800339 == std::tie(rhs.package, rhs.type, rhs.entry);
340}
341
Adam Lesinski74605cd2016-03-03 15:39:50 -0800342inline bool operator!=(const ResourceNameRef& lhs, const ResourceNameRef& rhs) {
343 return std::tie(lhs.package, lhs.type, lhs.entry)
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800344 != std::tie(rhs.package, rhs.type, rhs.entry);
345}
346
Adam Lesinski769de982015-04-10 19:43:55 -0700347inline ::std::ostream& operator<<(::std::ostream& out, const ResourceNameRef& name) {
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800348 if (!name.package.empty()) {
349 out << name.package << ":";
350 }
351 return out << name.type << "/" << name.entry;
352}
353
Adam Lesinski74605cd2016-03-03 15:39:50 -0800354inline bool operator<(const ResourceName& lhs, const ResourceNameRef& b) {
355 return ResourceNameRef(lhs) < b;
356}
357
358inline bool operator!=(const ResourceName& lhs, const ResourceNameRef& rhs) {
359 return ResourceNameRef(lhs) != rhs;
360}
361
362inline bool operator==(const SourcedResourceName& lhs, const SourcedResourceName& rhs) {
363 return lhs.name == rhs.name && lhs.line == rhs.line;
364}
365
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800366} // namespace aapt
367
Adam Lesinskibf0bd0f2016-06-01 15:31:50 -0700368namespace std {
369
370template <> struct hash<aapt::ResourceName> {
371 size_t operator()(const aapt::ResourceName& name) const {
372 android::hash_t h = 0;
373 h = android::JenkinsHashMix(h, hash<string>()(name.package));
374 h = android::JenkinsHashMix(h, static_cast<uint32_t>(name.type));
375 h = android::JenkinsHashMix(h, hash<string>()(name.entry));
376 return static_cast<size_t>(h);
377 }
378};
379
380} // namespace std
381
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800382#endif // AAPT_RESOURCE_H