blob: 0ba0345205634a91de1e0c6ffdf1271a50f59aaa [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 Lesinski6f6ceb72014-11-14 14:48:12 -080085 bool isValid() const;
Adam Lesinskid0f116b2016-07-08 15:00:32 -070086 std::string toString() const;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080087};
88
89/**
90 * Same as ResourceName, but uses StringPieces instead.
91 * Use this if you need to avoid copying and know that
92 * the lifetime of this object is shorter than that
93 * of the original string.
94 */
95struct ResourceNameRef {
Adam Lesinskid0f116b2016-07-08 15:00:32 -070096 StringPiece package;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080097 ResourceType type;
Adam Lesinskid0f116b2016-07-08 15:00:32 -070098 StringPiece entry;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080099
100 ResourceNameRef() = default;
101 ResourceNameRef(const ResourceNameRef&) = default;
102 ResourceNameRef(ResourceNameRef&&) = default;
103 ResourceNameRef(const ResourceName& rhs);
Adam Lesinskid0f116b2016-07-08 15:00:32 -0700104 ResourceNameRef(const StringPiece& p, ResourceType t, const StringPiece& e);
Adam Lesinski838a6872015-05-01 13:14:05 -0700105 ResourceNameRef& operator=(const ResourceNameRef& rhs) = default;
106 ResourceNameRef& operator=(ResourceNameRef&& rhs) = default;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800107 ResourceNameRef& operator=(const ResourceName& rhs);
108
109 ResourceName toResourceName() const;
110 bool isValid() const;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800111};
112
113/**
114 * A binary identifier representing a resource. Internally it
115 * is a 32bit integer split as follows:
116 *
117 * 0xPPTTEEEE
118 *
119 * PP: 8 bit package identifier. 0x01 is reserved for system
120 * and 0x7f is reserved for the running app.
121 * TT: 8 bit type identifier. 0x00 is invalid.
122 * EEEE: 16 bit entry identifier.
123 */
124struct ResourceId {
125 uint32_t id;
126
127 ResourceId();
128 ResourceId(const ResourceId& rhs);
129 ResourceId(uint32_t resId);
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700130 ResourceId(uint8_t p, uint8_t t, uint16_t e);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800131
132 bool isValid() const;
133 uint8_t packageId() const;
134 uint8_t typeId() const;
135 uint16_t entryId() const;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800136};
137
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700138struct SourcedResourceName {
139 ResourceName name;
140 size_t line;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700141};
142
143struct ResourceFile {
144 // Name
145 ResourceName name;
146
147 // Configuration
148 ConfigDescription config;
149
150 // Source
151 Source source;
152
153 // Exported symbols
154 std::vector<SourcedResourceName> exportedSymbols;
155};
156
Adam Lesinskia6fe3452015-12-09 15:20:52 -0800157/**
158 * Useful struct used as a key to represent a unique resource in associative containers.
159 */
160struct ResourceKey {
161 ResourceName name;
162 ConfigDescription config;
163};
164
165bool operator<(const ResourceKey& a, const ResourceKey& b);
166
167/**
168 * Useful struct used as a key to represent a unique resource in associative containers.
169 * Holds a reference to the name, so that name better live longer than this key!
170 */
171struct ResourceKeyRef {
172 ResourceNameRef name;
173 ConfigDescription config;
174
175 ResourceKeyRef() = default;
176 ResourceKeyRef(const ResourceNameRef& n, const ConfigDescription& c) : name(n), config(c) {
177 }
178
179 /**
180 * Prevent taking a reference to a temporary. This is bad.
181 */
182 ResourceKeyRef(ResourceName&& n, const ConfigDescription& c) = delete;
183};
184
185bool operator<(const ResourceKeyRef& a, const ResourceKeyRef& b);
186
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800187//
188// ResourceId implementation.
189//
190
191inline ResourceId::ResourceId() : id(0) {
192}
193
194inline ResourceId::ResourceId(const ResourceId& rhs) : id(rhs.id) {
195}
196
197inline ResourceId::ResourceId(uint32_t resId) : id(resId) {
198}
199
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700200inline ResourceId::ResourceId(uint8_t p, uint8_t t, uint16_t e) : id((p << 24) | (t << 16) | e) {
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800201}
202
203inline bool ResourceId::isValid() const {
204 return (id & 0xff000000u) != 0 && (id & 0x00ff0000u) != 0;
205}
206
207inline uint8_t ResourceId::packageId() const {
208 return static_cast<uint8_t>(id >> 24);
209}
210
211inline uint8_t ResourceId::typeId() const {
212 return static_cast<uint8_t>(id >> 16);
213}
214
215inline uint16_t ResourceId::entryId() const {
216 return static_cast<uint16_t>(id);
217}
218
Adam Lesinski74605cd2016-03-03 15:39:50 -0800219inline bool operator<(const ResourceId& lhs, const ResourceId& rhs) {
220 return lhs.id < rhs.id;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800221}
222
Adam Lesinski74605cd2016-03-03 15:39:50 -0800223inline bool operator>(const ResourceId& lhs, const ResourceId& rhs) {
224 return lhs.id > rhs.id;
Adam Lesinski24aad162015-04-24 19:19:30 -0700225}
226
Adam Lesinski74605cd2016-03-03 15:39:50 -0800227inline bool operator==(const ResourceId& lhs, const ResourceId& rhs) {
228 return lhs.id == rhs.id;
229}
230
231inline bool operator!=(const ResourceId& lhs, const ResourceId& rhs) {
232 return lhs.id != rhs.id;
233}
234
235inline ::std::ostream& operator<<(::std::ostream& out, const ResourceId& resId) {
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800236 std::ios_base::fmtflags oldFlags = out.flags();
237 char oldFill = out.fill();
238 out << "0x" << std::internal << std::setfill('0') << std::setw(8)
239 << std::hex << resId.id;
240 out.flags(oldFlags);
241 out.fill(oldFill);
242 return out;
243}
244
245//
246// ResourceType implementation.
247//
248
Adam Lesinski769de982015-04-10 19:43:55 -0700249inline ::std::ostream& operator<<(::std::ostream& out, const ResourceType& val) {
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800250 return out << toString(val);
251}
252
253//
254// ResourceName implementation.
255//
256
Adam Lesinskid0f116b2016-07-08 15:00:32 -0700257inline ResourceName::ResourceName(const StringPiece& p, ResourceType t, const StringPiece& e) :
Adam Lesinski9ba47d82015-10-13 11:37:10 -0700258 package(p.toString()), type(t), entry(e.toString()) {
259}
260
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800261inline bool ResourceName::isValid() const {
262 return !package.empty() && !entry.empty();
263}
264
Adam Lesinski74605cd2016-03-03 15:39:50 -0800265inline bool operator<(const ResourceName& lhs, const ResourceName& rhs) {
266 return std::tie(lhs.package, lhs.type, lhs.entry)
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800267 < std::tie(rhs.package, rhs.type, rhs.entry);
268}
269
Adam Lesinski74605cd2016-03-03 15:39:50 -0800270inline bool operator==(const ResourceName& lhs, const ResourceName& rhs) {
271 return std::tie(lhs.package, lhs.type, lhs.entry)
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800272 == std::tie(rhs.package, rhs.type, rhs.entry);
273}
274
Adam Lesinski74605cd2016-03-03 15:39:50 -0800275inline bool operator!=(const ResourceName& lhs, const ResourceName& rhs) {
276 return std::tie(lhs.package, lhs.type, lhs.entry)
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800277 != std::tie(rhs.package, rhs.type, rhs.entry);
278}
279
Adam Lesinski769de982015-04-10 19:43:55 -0700280inline ::std::ostream& operator<<(::std::ostream& out, const ResourceName& name) {
281 if (!name.package.empty()) {
282 out << name.package << ":";
283 }
284 return out << name.type << "/" << name.entry;
285}
286
Adam Lesinskid0f116b2016-07-08 15:00:32 -0700287inline std::string ResourceName::toString() const {
288 std::stringstream stream;
289 stream << *this;
290 return stream.str();
291}
Adam Lesinski769de982015-04-10 19:43:55 -0700292
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800293//
294// ResourceNameRef implementation.
295//
296
297inline ResourceNameRef::ResourceNameRef(const ResourceName& rhs) :
298 package(rhs.package), type(rhs.type), entry(rhs.entry) {
299}
300
Adam Lesinskid0f116b2016-07-08 15:00:32 -0700301inline ResourceNameRef::ResourceNameRef(const StringPiece& p, ResourceType t,
302 const StringPiece& e) :
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800303 package(p), type(t), entry(e) {
304}
305
306inline ResourceNameRef& ResourceNameRef::operator=(const ResourceName& rhs) {
307 package = rhs.package;
308 type = rhs.type;
309 entry = rhs.entry;
310 return *this;
311}
312
313inline ResourceName ResourceNameRef::toResourceName() const {
Adam Lesinskid0f116b2016-07-08 15:00:32 -0700314 return ResourceName(package, type, entry);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800315}
316
317inline bool ResourceNameRef::isValid() const {
318 return !package.empty() && !entry.empty();
319}
320
Adam Lesinski74605cd2016-03-03 15:39:50 -0800321inline bool operator<(const ResourceNameRef& lhs, const ResourceNameRef& rhs) {
322 return std::tie(lhs.package, lhs.type, lhs.entry)
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800323 < std::tie(rhs.package, rhs.type, rhs.entry);
324}
325
Adam Lesinski74605cd2016-03-03 15:39:50 -0800326inline bool operator==(const ResourceNameRef& lhs, const ResourceNameRef& rhs) {
327 return std::tie(lhs.package, lhs.type, lhs.entry)
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800328 == std::tie(rhs.package, rhs.type, rhs.entry);
329}
330
Adam Lesinski74605cd2016-03-03 15:39:50 -0800331inline bool operator!=(const ResourceNameRef& lhs, const ResourceNameRef& rhs) {
332 return std::tie(lhs.package, lhs.type, lhs.entry)
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800333 != std::tie(rhs.package, rhs.type, rhs.entry);
334}
335
Adam Lesinski769de982015-04-10 19:43:55 -0700336inline ::std::ostream& operator<<(::std::ostream& out, const ResourceNameRef& name) {
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800337 if (!name.package.empty()) {
338 out << name.package << ":";
339 }
340 return out << name.type << "/" << name.entry;
341}
342
Adam Lesinski74605cd2016-03-03 15:39:50 -0800343inline bool operator<(const ResourceName& lhs, const ResourceNameRef& b) {
344 return ResourceNameRef(lhs) < b;
345}
346
347inline bool operator!=(const ResourceName& lhs, const ResourceNameRef& rhs) {
348 return ResourceNameRef(lhs) != rhs;
349}
350
351inline bool operator==(const SourcedResourceName& lhs, const SourcedResourceName& rhs) {
352 return lhs.name == rhs.name && lhs.line == rhs.line;
353}
354
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800355} // namespace aapt
356
Adam Lesinskibf0bd0f2016-06-01 15:31:50 -0700357namespace std {
358
359template <> struct hash<aapt::ResourceName> {
360 size_t operator()(const aapt::ResourceName& name) const {
361 android::hash_t h = 0;
362 h = android::JenkinsHashMix(h, hash<string>()(name.package));
363 h = android::JenkinsHashMix(h, static_cast<uint32_t>(name.type));
364 h = android::JenkinsHashMix(h, hash<string>()(name.entry));
365 return static_cast<size_t>(h);
366 }
367};
368
369} // namespace std
370
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800371#endif // AAPT_RESOURCE_H