blob: 3fd678e741ed4770e5d77f51b81daa057473bb90 [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
20#include "StringPiece.h"
21
22#include <iomanip>
23#include <string>
24#include <tuple>
25
26namespace aapt {
27
28/**
29 * The various types of resource types available. Corresponds
30 * to the 'type' in package:type/entry.
31 */
32enum class ResourceType {
33 kAnim,
34 kAnimator,
35 kArray,
36 kAttr,
37 kAttrPrivate,
38 kBool,
39 kColor,
40 kDimen,
41 kDrawable,
42 kFraction,
43 kId,
44 kInteger,
45 kIntegerArray,
46 kInterpolator,
47 kLayout,
48 kMenu,
49 kMipmap,
50 kPlurals,
51 kRaw,
52 kString,
53 kStyle,
54 kStyleable,
55 kTransition,
56 kXml,
57};
58
59StringPiece16 toString(ResourceType type);
60
61/**
62 * Returns a pointer to a valid ResourceType, or nullptr if
63 * the string was invalid.
64 */
65const ResourceType* parseResourceType(const StringPiece16& str);
66
67/**
68 * A resource's name. This can uniquely identify
69 * a resource in the ResourceTable.
70 */
71struct ResourceName {
72 std::u16string package;
73 ResourceType type;
74 std::u16string entry;
75
76 bool isValid() const;
77 bool operator<(const ResourceName& rhs) const;
78 bool operator==(const ResourceName& rhs) const;
79 bool operator!=(const ResourceName& rhs) const;
80};
81
82/**
83 * Same as ResourceName, but uses StringPieces instead.
84 * Use this if you need to avoid copying and know that
85 * the lifetime of this object is shorter than that
86 * of the original string.
87 */
88struct ResourceNameRef {
89 StringPiece16 package;
90 ResourceType type;
91 StringPiece16 entry;
92
93 ResourceNameRef() = default;
94 ResourceNameRef(const ResourceNameRef&) = default;
95 ResourceNameRef(ResourceNameRef&&) = default;
96 ResourceNameRef(const ResourceName& rhs);
97 ResourceNameRef(const StringPiece16& p, ResourceType t, const StringPiece16& e);
98 ResourceNameRef& operator=(const ResourceName& rhs);
99
100 ResourceName toResourceName() const;
101 bool isValid() const;
102
103 bool operator<(const ResourceNameRef& rhs) const;
104 bool operator==(const ResourceNameRef& rhs) const;
105 bool operator!=(const ResourceNameRef& rhs) const;
106};
107
108/**
109 * A binary identifier representing a resource. Internally it
110 * is a 32bit integer split as follows:
111 *
112 * 0xPPTTEEEE
113 *
114 * PP: 8 bit package identifier. 0x01 is reserved for system
115 * and 0x7f is reserved for the running app.
116 * TT: 8 bit type identifier. 0x00 is invalid.
117 * EEEE: 16 bit entry identifier.
118 */
119struct ResourceId {
120 uint32_t id;
121
122 ResourceId();
123 ResourceId(const ResourceId& rhs);
124 ResourceId(uint32_t resId);
125 ResourceId(size_t p, size_t t, size_t e);
126
127 bool isValid() const;
128 uint8_t packageId() const;
129 uint8_t typeId() const;
130 uint16_t entryId() const;
131 bool operator<(const ResourceId& rhs) const;
132};
133
134//
135// ResourceId implementation.
136//
137
138inline ResourceId::ResourceId() : id(0) {
139}
140
141inline ResourceId::ResourceId(const ResourceId& rhs) : id(rhs.id) {
142}
143
144inline ResourceId::ResourceId(uint32_t resId) : id(resId) {
145}
146
147inline ResourceId::ResourceId(size_t p, size_t t, size_t e) : id(0) {
148 if (p > std::numeric_limits<uint8_t>::max() ||
149 t > std::numeric_limits<uint8_t>::max() ||
150 e > std::numeric_limits<uint16_t>::max()) {
151 // This will leave the ResourceId in an invalid state.
152 return;
153 }
154
155 id = (static_cast<uint8_t>(p) << 24) |
156 (static_cast<uint8_t>(t) << 16) |
157 static_cast<uint16_t>(e);
158}
159
160inline bool ResourceId::isValid() const {
161 return (id & 0xff000000u) != 0 && (id & 0x00ff0000u) != 0;
162}
163
164inline uint8_t ResourceId::packageId() const {
165 return static_cast<uint8_t>(id >> 24);
166}
167
168inline uint8_t ResourceId::typeId() const {
169 return static_cast<uint8_t>(id >> 16);
170}
171
172inline uint16_t ResourceId::entryId() const {
173 return static_cast<uint16_t>(id);
174}
175
176inline bool ResourceId::operator<(const ResourceId& rhs) const {
177 return id < rhs.id;
178}
179
180inline ::std::ostream& operator<<(::std::ostream& out,
181 const ResourceId& resId) {
182 std::ios_base::fmtflags oldFlags = out.flags();
183 char oldFill = out.fill();
184 out << "0x" << std::internal << std::setfill('0') << std::setw(8)
185 << std::hex << resId.id;
186 out.flags(oldFlags);
187 out.fill(oldFill);
188 return out;
189}
190
191//
192// ResourceType implementation.
193//
194
195inline ::std::ostream& operator<<(::std::ostream& out,
196 const ResourceType& val) {
197 return out << toString(val);
198}
199
200//
201// ResourceName implementation.
202//
203
204inline bool ResourceName::isValid() const {
205 return !package.empty() && !entry.empty();
206}
207
208inline bool ResourceName::operator<(const ResourceName& rhs) const {
209 return std::tie(package, type, entry)
210 < std::tie(rhs.package, rhs.type, rhs.entry);
211}
212
213inline bool ResourceName::operator==(const ResourceName& rhs) const {
214 return std::tie(package, type, entry)
215 == std::tie(rhs.package, rhs.type, rhs.entry);
216}
217
218inline bool ResourceName::operator!=(const ResourceName& rhs) const {
219 return std::tie(package, type, entry)
220 != std::tie(rhs.package, rhs.type, rhs.entry);
221}
222
223//
224// ResourceNameRef implementation.
225//
226
227inline ResourceNameRef::ResourceNameRef(const ResourceName& rhs) :
228 package(rhs.package), type(rhs.type), entry(rhs.entry) {
229}
230
231inline ResourceNameRef::ResourceNameRef(const StringPiece16& p, ResourceType t,
232 const StringPiece16& e) :
233 package(p), type(t), entry(e) {
234}
235
236inline ResourceNameRef& ResourceNameRef::operator=(const ResourceName& rhs) {
237 package = rhs.package;
238 type = rhs.type;
239 entry = rhs.entry;
240 return *this;
241}
242
243inline ResourceName ResourceNameRef::toResourceName() const {
244 return { package.toString(), type, entry.toString() };
245}
246
247inline bool ResourceNameRef::isValid() const {
248 return !package.empty() && !entry.empty();
249}
250
251inline bool ResourceNameRef::operator<(const ResourceNameRef& rhs) const {
252 return std::tie(package, type, entry)
253 < std::tie(rhs.package, rhs.type, rhs.entry);
254}
255
256inline bool ResourceNameRef::operator==(const ResourceNameRef& rhs) const {
257 return std::tie(package, type, entry)
258 == std::tie(rhs.package, rhs.type, rhs.entry);
259}
260
261inline bool ResourceNameRef::operator!=(const ResourceNameRef& rhs) const {
262 return std::tie(package, type, entry)
263 != std::tie(rhs.package, rhs.type, rhs.entry);
264}
265
266inline ::std::ostream& operator<<(::std::ostream& out,
267 const ResourceNameRef& name) {
268 if (!name.package.empty()) {
269 out << name.package << ":";
270 }
271 return out << name.type << "/" << name.entry;
272}
273
274} // namespace aapt
275
276#endif // AAPT_RESOURCE_H