OSDN Git Service

0a74c1a0f77dfd930fbd55916cb8739681104079
[android-x86/frameworks-base.git] / tools / aapt2 / Resource.h
1 /*
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 <iomanip>
21 #include <limits>
22 #include <sstream>
23 #include <string>
24 #include <tuple>
25 #include <vector>
26
27 #include "androidfw/StringPiece.h"
28 #include "utils/JenkinsHash.h"
29
30 #include "ConfigDescription.h"
31 #include "Source.h"
32
33 namespace aapt {
34
35 /**
36  * The various types of resource types available. Corresponds
37  * to the 'type' in package:type/entry.
38  */
39 enum class ResourceType {
40   kAnim,
41   kAnimator,
42   kArray,
43   kAttr,
44   kAttrPrivate,
45   kBool,
46   kColor,
47
48   // Not really a type, but it shows up in some CTS tests and
49   // we need to continue respecting it.
50   kConfigVarying,
51
52   kDimen,
53   kDrawable,
54   kFont,
55   kFraction,
56   kId,
57   kInteger,
58   kInterpolator,
59   kLayout,
60   kMenu,
61   kMipmap,
62   kPlurals,
63   kRaw,
64   kString,
65   kStyle,
66   kStyleable,
67   kTransition,
68   kXml,
69 };
70
71 android::StringPiece ToString(ResourceType type);
72
73 /**
74  * Returns a pointer to a valid ResourceType, or nullptr if
75  * the string was invalid.
76  */
77 const ResourceType* ParseResourceType(const android::StringPiece& str);
78
79 /**
80  * A resource's name. This can uniquely identify
81  * a resource in the ResourceTable.
82  */
83 struct ResourceName {
84   std::string package;
85   ResourceType type = ResourceType::kRaw;
86   std::string entry;
87
88   ResourceName() = default;
89   ResourceName(const android::StringPiece& p, ResourceType t, const android::StringPiece& e);
90
91   int compare(const ResourceName& other) const;
92
93   bool is_valid() const;
94   std::string ToString() const;
95 };
96
97 /**
98  * Same as ResourceName, but uses StringPieces instead.
99  * Use this if you need to avoid copying and know that
100  * the lifetime of this object is shorter than that
101  * of the original string.
102  */
103 struct ResourceNameRef {
104   android::StringPiece package;
105   ResourceType type = ResourceType::kRaw;
106   android::StringPiece entry;
107
108   ResourceNameRef() = default;
109   ResourceNameRef(const ResourceNameRef&) = default;
110   ResourceNameRef(ResourceNameRef&&) = default;
111   ResourceNameRef(const ResourceName& rhs);  // NOLINT(implicit)
112   ResourceNameRef(const android::StringPiece& p, ResourceType t, const android::StringPiece& e);
113   ResourceNameRef& operator=(const ResourceNameRef& rhs) = default;
114   ResourceNameRef& operator=(ResourceNameRef&& rhs) = default;
115   ResourceNameRef& operator=(const ResourceName& rhs);
116
117   ResourceName ToResourceName() const;
118   bool is_valid() const;
119 };
120
121 constexpr const uint8_t kAppPackageId = 0x7fu;
122 constexpr const uint8_t kFrameworkPackageId = 0x01u;
123
124 /**
125  * A binary identifier representing a resource. Internally it
126  * is a 32bit integer split as follows:
127  *
128  * 0xPPTTEEEE
129  *
130  * PP: 8 bit package identifier. 0x01 is reserved for system
131  *     and 0x7f is reserved for the running app.
132  * TT: 8 bit type identifier. 0x00 is invalid.
133  * EEEE: 16 bit entry identifier.
134  */
135 struct ResourceId {
136   uint32_t id;
137
138   ResourceId();
139   ResourceId(const ResourceId& rhs);
140   ResourceId(uint32_t res_id);  // NOLINT(implicit)
141   ResourceId(uint8_t p, uint8_t t, uint16_t e);
142
143   bool is_valid() const;
144
145   // Returns true if the ID is a valid ID or dynamic ID (package ID can be 0).
146   bool is_valid_dynamic() const;
147
148   uint8_t package_id() const;
149   uint8_t type_id() const;
150   uint16_t entry_id() const;
151 };
152
153 struct SourcedResourceName {
154   ResourceName name;
155   size_t line;
156 };
157
158 struct ResourceFile {
159   // Name
160   ResourceName name;
161
162   // Configuration
163   ConfigDescription config;
164
165   // Source
166   Source source;
167
168   // Exported symbols
169   std::vector<SourcedResourceName> exported_symbols;
170 };
171
172 /**
173  * Useful struct used as a key to represent a unique resource in associative
174  * containers.
175  */
176 struct ResourceKey {
177   ResourceName name;
178   ConfigDescription config;
179 };
180
181 bool operator<(const ResourceKey& a, const ResourceKey& b);
182
183 /**
184  * Useful struct used as a key to represent a unique resource in associative
185  * containers.
186  * Holds a reference to the name, so that name better live longer than this key!
187  */
188 struct ResourceKeyRef {
189   ResourceNameRef name;
190   ConfigDescription config;
191
192   ResourceKeyRef() = default;
193   ResourceKeyRef(const ResourceNameRef& n, const ConfigDescription& c)
194       : name(n), config(c) {}
195
196   /**
197    * Prevent taking a reference to a temporary. This is bad.
198    */
199   ResourceKeyRef(ResourceName&& n, const ConfigDescription& c) = delete;
200 };
201
202 bool operator<(const ResourceKeyRef& a, const ResourceKeyRef& b);
203
204 //
205 // ResourceId implementation.
206 //
207
208 inline ResourceId::ResourceId() : id(0) {}
209
210 inline ResourceId::ResourceId(const ResourceId& rhs) : id(rhs.id) {}
211
212 inline ResourceId::ResourceId(uint32_t res_id) : id(res_id) {}
213
214 inline ResourceId::ResourceId(uint8_t p, uint8_t t, uint16_t e)
215     : id((p << 24) | (t << 16) | e) {}
216
217 inline bool ResourceId::is_valid() const {
218   return (id & 0xff000000u) != 0 && (id & 0x00ff0000u) != 0;
219 }
220
221 inline bool ResourceId::is_valid_dynamic() const { return (id & 0x00ff0000u) != 0; }
222
223 inline uint8_t ResourceId::package_id() const {
224   return static_cast<uint8_t>(id >> 24);
225 }
226
227 inline uint8_t ResourceId::type_id() const {
228   return static_cast<uint8_t>(id >> 16);
229 }
230
231 inline uint16_t ResourceId::entry_id() const {
232   return static_cast<uint16_t>(id);
233 }
234
235 inline bool operator<(const ResourceId& lhs, const ResourceId& rhs) {
236   return lhs.id < rhs.id;
237 }
238
239 inline bool operator>(const ResourceId& lhs, const ResourceId& rhs) {
240   return lhs.id > rhs.id;
241 }
242
243 inline bool operator==(const ResourceId& lhs, const ResourceId& rhs) {
244   return lhs.id == rhs.id;
245 }
246
247 inline bool operator!=(const ResourceId& lhs, const ResourceId& rhs) {
248   return lhs.id != rhs.id;
249 }
250
251 inline ::std::ostream& operator<<(::std::ostream& out,
252                                   const ResourceId& res_id) {
253   std::ios_base::fmtflags old_flags = out.flags();
254   char old_fill = out.fill();
255   out << "0x" << std::internal << std::setfill('0') << std::setw(8) << std::hex
256       << res_id.id;
257   out.flags(old_flags);
258   out.fill(old_fill);
259   return out;
260 }
261
262 //
263 // ResourceType implementation.
264 //
265
266 inline ::std::ostream& operator<<(::std::ostream& out,
267                                   const ResourceType& val) {
268   return out << ToString(val);
269 }
270
271 //
272 // ResourceName implementation.
273 //
274
275 inline ResourceName::ResourceName(const android::StringPiece& p, ResourceType t,
276                                   const android::StringPiece& e)
277     : package(p.to_string()), type(t), entry(e.to_string()) {}
278
279 inline int ResourceName::compare(const ResourceName& other) const {
280   int cmp = package.compare(other.package);
281   if (cmp != 0) return cmp;
282   cmp = static_cast<int>(type) - static_cast<int>(other.type);
283   if (cmp != 0) return cmp;
284   cmp = entry.compare(other.entry);
285   return cmp;
286 }
287
288 inline bool ResourceName::is_valid() const {
289   return !package.empty() && !entry.empty();
290 }
291
292 inline bool operator<(const ResourceName& lhs, const ResourceName& rhs) {
293   return std::tie(lhs.package, lhs.type, lhs.entry) <
294          std::tie(rhs.package, rhs.type, rhs.entry);
295 }
296
297 inline bool operator==(const ResourceName& lhs, const ResourceName& rhs) {
298   return std::tie(lhs.package, lhs.type, lhs.entry) ==
299          std::tie(rhs.package, rhs.type, rhs.entry);
300 }
301
302 inline bool operator!=(const ResourceName& lhs, const ResourceName& rhs) {
303   return std::tie(lhs.package, lhs.type, lhs.entry) !=
304          std::tie(rhs.package, rhs.type, rhs.entry);
305 }
306
307 inline ::std::ostream& operator<<(::std::ostream& out,
308                                   const ResourceName& name) {
309   if (!name.package.empty()) {
310     out << name.package << ":";
311   }
312   return out << name.type << "/" << name.entry;
313 }
314
315 inline std::string ResourceName::ToString() const {
316   std::stringstream stream;
317   stream << *this;
318   return stream.str();
319 }
320
321 //
322 // ResourceNameRef implementation.
323 //
324
325 inline ResourceNameRef::ResourceNameRef(const ResourceName& rhs)
326     : package(rhs.package), type(rhs.type), entry(rhs.entry) {}
327
328 inline ResourceNameRef::ResourceNameRef(const android::StringPiece& p, ResourceType t,
329                                         const android::StringPiece& e)
330     : package(p), type(t), entry(e) {}
331
332 inline ResourceNameRef& ResourceNameRef::operator=(const ResourceName& rhs) {
333   package = rhs.package;
334   type = rhs.type;
335   entry = rhs.entry;
336   return *this;
337 }
338
339 inline ResourceName ResourceNameRef::ToResourceName() const {
340   return ResourceName(package, type, entry);
341 }
342
343 inline bool ResourceNameRef::is_valid() const {
344   return !package.empty() && !entry.empty();
345 }
346
347 inline bool operator<(const ResourceNameRef& lhs, const ResourceNameRef& rhs) {
348   return std::tie(lhs.package, lhs.type, lhs.entry) <
349          std::tie(rhs.package, rhs.type, rhs.entry);
350 }
351
352 inline bool operator==(const ResourceNameRef& lhs, const ResourceNameRef& rhs) {
353   return std::tie(lhs.package, lhs.type, lhs.entry) ==
354          std::tie(rhs.package, rhs.type, rhs.entry);
355 }
356
357 inline bool operator!=(const ResourceNameRef& lhs, const ResourceNameRef& rhs) {
358   return std::tie(lhs.package, lhs.type, lhs.entry) !=
359          std::tie(rhs.package, rhs.type, rhs.entry);
360 }
361
362 inline ::std::ostream& operator<<(::std::ostream& out,
363                                   const ResourceNameRef& name) {
364   if (!name.package.empty()) {
365     out << name.package << ":";
366   }
367   return out << name.type << "/" << name.entry;
368 }
369
370 inline bool operator<(const ResourceName& lhs, const ResourceNameRef& b) {
371   return ResourceNameRef(lhs) < b;
372 }
373
374 inline bool operator!=(const ResourceName& lhs, const ResourceNameRef& rhs) {
375   return ResourceNameRef(lhs) != rhs;
376 }
377
378 inline bool operator==(const SourcedResourceName& lhs,
379                        const SourcedResourceName& rhs) {
380   return lhs.name == rhs.name && lhs.line == rhs.line;
381 }
382
383 }  // namespace aapt
384
385 namespace std {
386
387 template <>
388 struct hash<aapt::ResourceName> {
389   size_t operator()(const aapt::ResourceName& name) const {
390     android::hash_t h = 0;
391     h = android::JenkinsHashMix(h, static_cast<uint32_t>(hash<string>()(name.package)));
392     h = android::JenkinsHashMix(h, static_cast<uint32_t>(name.type));
393     h = android::JenkinsHashMix(h, static_cast<uint32_t>(hash<string>()(name.entry)));
394     return static_cast<size_t>(h);
395   }
396 };
397
398 template <>
399 struct hash<aapt::ResourceId> {
400   size_t operator()(const aapt::ResourceId& id) const {
401     return id.id;
402   }
403 };
404
405 }  // namespace std
406
407 #endif  // AAPT_RESOURCE_H