blob: 22d75a2fb315d20b02ccf0c95eb2d3116f27b51a [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"
22
23#include "util/StringPiece.h"
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080024
25#include <iomanip>
Adam Lesinskica2fc352015-04-03 12:08:26 -070026#include <limits>
Adam Lesinskid0f116b2016-07-08 15:00:32 -070027#include <sstream>
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080028#include <string>
29#include <tuple>
Adam Lesinski1ab598f2015-08-14 14:26:04 -070030#include <vector>
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080031
32namespace aapt {
33
34/**
35 * The various types of resource types available. Corresponds
36 * to the 'type' in package:type/entry.
37 */
38enum class ResourceType {
39 kAnim,
40 kAnimator,
41 kArray,
42 kAttr,
43 kAttrPrivate,
44 kBool,
45 kColor,
46 kDimen,
47 kDrawable,
48 kFraction,
49 kId,
50 kInteger,
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080051 kInterpolator,
52 kLayout,
53 kMenu,
54 kMipmap,
55 kPlurals,
56 kRaw,
57 kString,
58 kStyle,
59 kStyleable,
60 kTransition,
61 kXml,
62};
63
Adam Lesinskid0f116b2016-07-08 15:00:32 -070064StringPiece toString(ResourceType type);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080065
66/**
67 * Returns a pointer to a valid ResourceType, or nullptr if
68 * the string was invalid.
69 */
Adam Lesinskid0f116b2016-07-08 15:00:32 -070070const ResourceType* parseResourceType(const StringPiece& str);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080071
72/**
73 * A resource's name. This can uniquely identify
74 * a resource in the ResourceTable.
75 */
76struct ResourceName {
Adam Lesinskid0f116b2016-07-08 15:00:32 -070077 std::string package;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080078 ResourceType type;
Adam Lesinskid0f116b2016-07-08 15:00:32 -070079 std::string entry;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080080
Adam Lesinski96917c22016-03-09 13:11:25 -080081 ResourceName() : type(ResourceType::kRaw) {}
Adam Lesinskid0f116b2016-07-08 15:00:32 -070082 ResourceName(const StringPiece& p, ResourceType t, const StringPiece& e);
Adam Lesinski9ba47d82015-10-13 11:37:10 -070083
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080084 bool isValid() const;
Adam Lesinskid0f116b2016-07-08 15:00:32 -070085 std::string toString() const;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080086};
87
88/**
89 * Same as ResourceName, but uses StringPieces instead.
90 * Use this if you need to avoid copying and know that
91 * the lifetime of this object is shorter than that
92 * of the original string.
93 */
94struct ResourceNameRef {
Adam Lesinskid0f116b2016-07-08 15:00:32 -070095 StringPiece package;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080096 ResourceType type;
Adam Lesinskid0f116b2016-07-08 15:00:32 -070097 StringPiece entry;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080098
99 ResourceNameRef() = default;
100 ResourceNameRef(const ResourceNameRef&) = default;
101 ResourceNameRef(ResourceNameRef&&) = default;
102 ResourceNameRef(const ResourceName& rhs);
Adam Lesinskid0f116b2016-07-08 15:00:32 -0700103 ResourceNameRef(const StringPiece& p, ResourceType t, const StringPiece& e);
Adam Lesinski838a6872015-05-01 13:14:05 -0700104 ResourceNameRef& operator=(const ResourceNameRef& rhs) = default;
105 ResourceNameRef& operator=(ResourceNameRef&& rhs) = default;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800106 ResourceNameRef& operator=(const ResourceName& rhs);
107
108 ResourceName toResourceName() const;
109 bool isValid() const;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800110};
111
112/**
113 * A binary identifier representing a resource. Internally it
114 * is a 32bit integer split as follows:
115 *
116 * 0xPPTTEEEE
117 *
118 * PP: 8 bit package identifier. 0x01 is reserved for system
119 * and 0x7f is reserved for the running app.
120 * TT: 8 bit type identifier. 0x00 is invalid.
121 * EEEE: 16 bit entry identifier.
122 */
123struct ResourceId {
124 uint32_t id;
125
126 ResourceId();
127 ResourceId(const ResourceId& rhs);
128 ResourceId(uint32_t resId);
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700129 ResourceId(uint8_t p, uint8_t t, uint16_t e);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800130
131 bool isValid() const;
132 uint8_t packageId() const;
133 uint8_t typeId() const;
134 uint16_t entryId() const;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800135};
136
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700137struct SourcedResourceName {
138 ResourceName name;
139 size_t line;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700140};
141
142struct ResourceFile {
143 // Name
144 ResourceName name;
145
146 // Configuration
147 ConfigDescription config;
148
149 // Source
150 Source source;
151
152 // Exported symbols
153 std::vector<SourcedResourceName> exportedSymbols;
154};
155
Adam Lesinskia6fe3452015-12-09 15:20:52 -0800156/**
157 * Useful struct used as a key to represent a unique resource in associative containers.
158 */
159struct ResourceKey {
160 ResourceName name;
161 ConfigDescription config;
162};
163
164bool operator<(const ResourceKey& a, const ResourceKey& b);
165
166/**
167 * Useful struct used as a key to represent a unique resource in associative containers.
168 * Holds a reference to the name, so that name better live longer than this key!
169 */
170struct ResourceKeyRef {
171 ResourceNameRef name;
172 ConfigDescription config;
173
174 ResourceKeyRef() = default;
175 ResourceKeyRef(const ResourceNameRef& n, const ConfigDescription& c) : name(n), config(c) {
176 }
177
178 /**
179 * Prevent taking a reference to a temporary. This is bad.
180 */
181 ResourceKeyRef(ResourceName&& n, const ConfigDescription& c) = delete;
182};
183
184bool operator<(const ResourceKeyRef& a, const ResourceKeyRef& b);
185
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800186//
187// ResourceId implementation.
188//
189
190inline ResourceId::ResourceId() : id(0) {
191}
192
193inline ResourceId::ResourceId(const ResourceId& rhs) : id(rhs.id) {
194}
195
196inline ResourceId::ResourceId(uint32_t resId) : id(resId) {
197}
198
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700199inline ResourceId::ResourceId(uint8_t p, uint8_t t, uint16_t e) : id((p << 24) | (t << 16) | e) {
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800200}
201
202inline bool ResourceId::isValid() const {
203 return (id & 0xff000000u) != 0 && (id & 0x00ff0000u) != 0;
204}
205
206inline uint8_t ResourceId::packageId() const {
207 return static_cast<uint8_t>(id >> 24);
208}
209
210inline uint8_t ResourceId::typeId() const {
211 return static_cast<uint8_t>(id >> 16);
212}
213
214inline uint16_t ResourceId::entryId() const {
215 return static_cast<uint16_t>(id);
216}
217
Adam Lesinski74605cd2016-03-03 15:39:50 -0800218inline bool operator<(const ResourceId& lhs, const ResourceId& rhs) {
219 return lhs.id < rhs.id;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800220}
221
Adam Lesinski74605cd2016-03-03 15:39:50 -0800222inline bool operator>(const ResourceId& lhs, const ResourceId& rhs) {
223 return lhs.id > rhs.id;
Adam Lesinski24aad162015-04-24 19:19:30 -0700224}
225
Adam Lesinski74605cd2016-03-03 15:39:50 -0800226inline bool operator==(const ResourceId& lhs, const ResourceId& rhs) {
227 return lhs.id == rhs.id;
228}
229
230inline bool operator!=(const ResourceId& lhs, const ResourceId& rhs) {
231 return lhs.id != rhs.id;
232}
233
234inline ::std::ostream& operator<<(::std::ostream& out, const ResourceId& resId) {
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800235 std::ios_base::fmtflags oldFlags = out.flags();
236 char oldFill = out.fill();
237 out << "0x" << std::internal << std::setfill('0') << std::setw(8)
238 << std::hex << resId.id;
239 out.flags(oldFlags);
240 out.fill(oldFill);
241 return out;
242}
243
244//
245// ResourceType implementation.
246//
247
Adam Lesinski769de982015-04-10 19:43:55 -0700248inline ::std::ostream& operator<<(::std::ostream& out, const ResourceType& val) {
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800249 return out << toString(val);
250}
251
252//
253// ResourceName implementation.
254//
255
Adam Lesinskid0f116b2016-07-08 15:00:32 -0700256inline ResourceName::ResourceName(const StringPiece& p, ResourceType t, const StringPiece& e) :
Adam Lesinski9ba47d82015-10-13 11:37:10 -0700257 package(p.toString()), type(t), entry(e.toString()) {
258}
259
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800260inline bool ResourceName::isValid() const {
261 return !package.empty() && !entry.empty();
262}
263
Adam Lesinski74605cd2016-03-03 15:39:50 -0800264inline bool operator<(const ResourceName& lhs, const ResourceName& rhs) {
265 return std::tie(lhs.package, lhs.type, lhs.entry)
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800266 < std::tie(rhs.package, rhs.type, rhs.entry);
267}
268
Adam Lesinski74605cd2016-03-03 15:39:50 -0800269inline bool operator==(const ResourceName& lhs, const ResourceName& rhs) {
270 return std::tie(lhs.package, lhs.type, lhs.entry)
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800271 == std::tie(rhs.package, rhs.type, rhs.entry);
272}
273
Adam Lesinski74605cd2016-03-03 15:39:50 -0800274inline bool operator!=(const ResourceName& lhs, const ResourceName& rhs) {
275 return std::tie(lhs.package, lhs.type, lhs.entry)
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800276 != std::tie(rhs.package, rhs.type, rhs.entry);
277}
278
Adam Lesinski769de982015-04-10 19:43:55 -0700279inline ::std::ostream& operator<<(::std::ostream& out, const ResourceName& name) {
280 if (!name.package.empty()) {
281 out << name.package << ":";
282 }
283 return out << name.type << "/" << name.entry;
284}
285
Adam Lesinskid0f116b2016-07-08 15:00:32 -0700286inline std::string ResourceName::toString() const {
287 std::stringstream stream;
288 stream << *this;
289 return stream.str();
290}
Adam Lesinski769de982015-04-10 19:43:55 -0700291
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800292//
293// ResourceNameRef implementation.
294//
295
296inline ResourceNameRef::ResourceNameRef(const ResourceName& rhs) :
297 package(rhs.package), type(rhs.type), entry(rhs.entry) {
298}
299
Adam Lesinskid0f116b2016-07-08 15:00:32 -0700300inline ResourceNameRef::ResourceNameRef(const StringPiece& p, ResourceType t,
301 const StringPiece& e) :
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800302 package(p), type(t), entry(e) {
303}
304
305inline ResourceNameRef& ResourceNameRef::operator=(const ResourceName& rhs) {
306 package = rhs.package;
307 type = rhs.type;
308 entry = rhs.entry;
309 return *this;
310}
311
312inline ResourceName ResourceNameRef::toResourceName() const {
Adam Lesinskid0f116b2016-07-08 15:00:32 -0700313 return ResourceName(package, type, entry);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800314}
315
316inline bool ResourceNameRef::isValid() const {
317 return !package.empty() && !entry.empty();
318}
319
Adam Lesinski74605cd2016-03-03 15:39:50 -0800320inline bool operator<(const ResourceNameRef& lhs, const ResourceNameRef& rhs) {
321 return std::tie(lhs.package, lhs.type, lhs.entry)
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800322 < std::tie(rhs.package, rhs.type, rhs.entry);
323}
324
Adam Lesinski74605cd2016-03-03 15:39:50 -0800325inline bool operator==(const ResourceNameRef& lhs, const ResourceNameRef& rhs) {
326 return std::tie(lhs.package, lhs.type, lhs.entry)
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800327 == std::tie(rhs.package, rhs.type, rhs.entry);
328}
329
Adam Lesinski74605cd2016-03-03 15:39:50 -0800330inline bool operator!=(const ResourceNameRef& lhs, const ResourceNameRef& rhs) {
331 return std::tie(lhs.package, lhs.type, lhs.entry)
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800332 != std::tie(rhs.package, rhs.type, rhs.entry);
333}
334
Adam Lesinski769de982015-04-10 19:43:55 -0700335inline ::std::ostream& operator<<(::std::ostream& out, const ResourceNameRef& name) {
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800336 if (!name.package.empty()) {
337 out << name.package << ":";
338 }
339 return out << name.type << "/" << name.entry;
340}
341
Adam Lesinski74605cd2016-03-03 15:39:50 -0800342inline bool operator<(const ResourceName& lhs, const ResourceNameRef& b) {
343 return ResourceNameRef(lhs) < b;
344}
345
346inline bool operator!=(const ResourceName& lhs, const ResourceNameRef& rhs) {
347 return ResourceNameRef(lhs) != rhs;
348}
349
350inline bool operator==(const SourcedResourceName& lhs, const SourcedResourceName& rhs) {
351 return lhs.name == rhs.name && lhs.line == rhs.line;
352}
353
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800354} // namespace aapt
355
356#endif // AAPT_RESOURCE_H