blob: ec8fd175e16104c706fc0d64e0dc8124e1fdfe6a [file] [log] [blame]
Adam Lesinski282e1812014-01-23 18:17:42 -08001//
2// Copyright 2006 The Android Open Source Project
3//
4// Build resource files from raw assets.
5//
6
7#ifndef RESOURCE_TABLE_H
8#define RESOURCE_TABLE_H
9
10#include "StringPool.h"
11#include "SourcePos.h"
12
13#include <set>
14#include <map>
15
16using namespace std;
17
18class XMLNode;
19class ResourceTable;
20
21enum {
22 XML_COMPILE_STRIP_COMMENTS = 1<<0,
23 XML_COMPILE_ASSIGN_ATTRIBUTE_IDS = 1<<1,
24 XML_COMPILE_COMPACT_WHITESPACE = 1<<2,
25 XML_COMPILE_STRIP_WHITESPACE = 1<<3,
26 XML_COMPILE_STRIP_RAW_VALUES = 1<<4,
27 XML_COMPILE_UTF8 = 1<<5,
28
29 XML_COMPILE_STANDARD_RESOURCE =
30 XML_COMPILE_STRIP_COMMENTS | XML_COMPILE_ASSIGN_ATTRIBUTE_IDS
31 | XML_COMPILE_STRIP_WHITESPACE | XML_COMPILE_STRIP_RAW_VALUES
32};
33
34status_t compileXmlFile(const sp<AaptAssets>& assets,
35 const sp<AaptFile>& target,
36 ResourceTable* table,
37 int options = XML_COMPILE_STANDARD_RESOURCE);
38
39status_t compileXmlFile(const sp<AaptAssets>& assets,
40 const sp<AaptFile>& target,
41 const sp<AaptFile>& outTarget,
42 ResourceTable* table,
43 int options = XML_COMPILE_STANDARD_RESOURCE);
44
45status_t compileXmlFile(const sp<AaptAssets>& assets,
46 const sp<XMLNode>& xmlTree,
47 const sp<AaptFile>& target,
48 ResourceTable* table,
49 int options = XML_COMPILE_STANDARD_RESOURCE);
50
51status_t compileResourceFile(Bundle* bundle,
52 const sp<AaptAssets>& assets,
53 const sp<AaptFile>& in,
54 const ResTable_config& defParams,
55 const bool overwrite,
56 ResourceTable* outTable);
57
58struct AccessorCookie
59{
60 SourcePos sourcePos;
61 String8 attr;
62 String8 value;
63
64 AccessorCookie(const SourcePos&p, const String8& a, const String8& v)
65 :sourcePos(p),
66 attr(a),
67 value(v)
68 {
69 }
70};
71
72class ResourceTable : public ResTable::Accessor
73{
74public:
75 class Package;
76 class Type;
77 class Entry;
78
79 struct ConfigDescription : public ResTable_config {
80 ConfigDescription() {
81 memset(this, 0, sizeof(*this));
82 size = sizeof(ResTable_config);
83 }
84 ConfigDescription(const ResTable_config&o) {
85 *static_cast<ResTable_config*>(this) = o;
86 size = sizeof(ResTable_config);
87 }
88 ConfigDescription(const ConfigDescription&o) {
89 *static_cast<ResTable_config*>(this) = o;
90 }
91
92 ConfigDescription& operator=(const ResTable_config& o) {
93 *static_cast<ResTable_config*>(this) = o;
94 size = sizeof(ResTable_config);
95 return *this;
96 }
97 ConfigDescription& operator=(const ConfigDescription& o) {
98 *static_cast<ResTable_config*>(this) = o;
99 return *this;
100 }
101
102 inline bool operator<(const ConfigDescription& o) const { return compare(o) < 0; }
103 inline bool operator<=(const ConfigDescription& o) const { return compare(o) <= 0; }
104 inline bool operator==(const ConfigDescription& o) const { return compare(o) == 0; }
105 inline bool operator!=(const ConfigDescription& o) const { return compare(o) != 0; }
106 inline bool operator>=(const ConfigDescription& o) const { return compare(o) >= 0; }
107 inline bool operator>(const ConfigDescription& o) const { return compare(o) > 0; }
108 };
109
110 ResourceTable(Bundle* bundle, const String16& assetsPackage);
111
112 status_t addIncludedResources(Bundle* bundle, const sp<AaptAssets>& assets);
113
114 status_t addPublic(const SourcePos& pos,
115 const String16& package,
116 const String16& type,
117 const String16& name,
118 const uint32_t ident);
119
120 status_t addEntry(const SourcePos& pos,
121 const String16& package,
122 const String16& type,
123 const String16& name,
124 const String16& value,
125 const Vector<StringPool::entry_style_span>* style = NULL,
126 const ResTable_config* params = NULL,
127 const bool doSetIndex = false,
128 const int32_t format = ResTable_map::TYPE_ANY,
129 const bool overwrite = false);
130
131 status_t startBag(const SourcePos& pos,
132 const String16& package,
133 const String16& type,
134 const String16& name,
135 const String16& bagParent,
136 const ResTable_config* params = NULL,
137 bool overlay = false,
138 bool replace = false,
139 bool isId = false);
140
141 status_t addBag(const SourcePos& pos,
142 const String16& package,
143 const String16& type,
144 const String16& name,
145 const String16& bagParent,
146 const String16& bagKey,
147 const String16& value,
148 const Vector<StringPool::entry_style_span>* style = NULL,
149 const ResTable_config* params = NULL,
150 bool replace = false,
151 bool isId = false,
152 const int32_t format = ResTable_map::TYPE_ANY);
153
154 bool hasBagOrEntry(const String16& package,
155 const String16& type,
156 const String16& name) const;
157
158 bool hasBagOrEntry(const String16& package,
159 const String16& type,
160 const String16& name,
161 const ResTable_config& config) const;
162
163 bool hasBagOrEntry(const String16& ref,
164 const String16* defType = NULL,
165 const String16* defPackage = NULL);
166
167 bool appendComment(const String16& package,
168 const String16& type,
169 const String16& name,
170 const String16& comment,
171 bool onlyIfEmpty = false);
172
173 bool appendTypeComment(const String16& package,
174 const String16& type,
175 const String16& name,
176 const String16& comment);
177
178 void canAddEntry(const SourcePos& pos,
179 const String16& package, const String16& type, const String16& name);
180
181 size_t size() const;
182 size_t numLocalResources() const;
183 bool hasResources() const;
184
185 sp<AaptFile> flatten(Bundle*);
186
187 static inline uint32_t makeResId(uint32_t packageId,
188 uint32_t typeId,
189 uint32_t nameId)
190 {
191 return nameId | (typeId<<16) | (packageId<<24);
192 }
193
194 static inline uint32_t getResId(const sp<Package>& p,
195 const sp<Type>& t,
196 uint32_t nameId);
197
198 uint32_t getResId(const String16& package,
199 const String16& type,
200 const String16& name,
201 bool onlyPublic = true) const;
202
203 uint32_t getResId(const String16& ref,
204 const String16* defType = NULL,
205 const String16* defPackage = NULL,
206 const char** outErrorMsg = NULL,
207 bool onlyPublic = true) const;
208
209 static bool isValidResourceName(const String16& s);
210
211 bool stringToValue(Res_value* outValue, StringPool* pool,
212 const String16& str,
213 bool preserveSpaces, bool coerceType,
214 uint32_t attrID,
215 const Vector<StringPool::entry_style_span>* style = NULL,
216 String16* outStr = NULL, void* accessorCookie = NULL,
217 uint32_t attrType = ResTable_map::TYPE_ANY,
218 const String8* configTypeName = NULL,
219 const ConfigDescription* config = NULL);
220
221 status_t assignResourceIds();
222 status_t addSymbols(const sp<AaptSymbols>& outSymbols = NULL);
Adam Lesinskia01a9372014-03-20 18:04:57 -0700223 void addLocalization(const String16& name, const String8& locale, const SourcePos& src);
Adam Lesinski282e1812014-01-23 18:17:42 -0800224 status_t validateLocalizations(void);
225
226 status_t flatten(Bundle*, const sp<AaptFile>& dest);
Adam Lesinskide898ff2014-01-29 18:20:45 -0800227 status_t flattenLibraryTable(const sp<AaptFile>& dest, const Vector<sp<Package> >& libs);
Adam Lesinski282e1812014-01-23 18:17:42 -0800228
229 void writePublicDefinitions(const String16& package, FILE* fp);
230
231 virtual uint32_t getCustomResource(const String16& package,
232 const String16& type,
233 const String16& name) const;
234 virtual uint32_t getCustomResourceWithCreation(const String16& package,
235 const String16& type,
236 const String16& name,
237 const bool createIfNeeded);
238 virtual uint32_t getRemappedPackage(uint32_t origPackage) const;
239 virtual bool getAttributeType(uint32_t attrID, uint32_t* outType);
240 virtual bool getAttributeMin(uint32_t attrID, uint32_t* outMin);
241 virtual bool getAttributeMax(uint32_t attrID, uint32_t* outMax);
242 virtual bool getAttributeKeys(uint32_t attrID, Vector<String16>* outKeys);
243 virtual bool getAttributeEnum(uint32_t attrID,
244 const char16_t* name, size_t nameLen,
245 Res_value* outValue);
246 virtual bool getAttributeFlags(uint32_t attrID,
247 const char16_t* name, size_t nameLen,
248 Res_value* outValue);
249 virtual uint32_t getAttributeL10N(uint32_t attrID);
250
251 virtual bool getLocalizationSetting();
252 virtual void reportError(void* accessorCookie, const char* fmt, ...);
253
254 void setCurrentXmlPos(const SourcePos& pos) { mCurrentXmlPos = pos; }
255
256 class Item {
257 public:
258 Item() : isId(false), format(ResTable_map::TYPE_ANY), bagKeyId(0), evaluating(false)
259 { memset(&parsedValue, 0, sizeof(parsedValue)); }
260 Item(const SourcePos& pos,
261 bool _isId,
262 const String16& _value,
263 const Vector<StringPool::entry_style_span>* _style = NULL,
264 int32_t format = ResTable_map::TYPE_ANY);
265 Item(const Item& o) : sourcePos(o.sourcePos),
266 isId(o.isId), value(o.value), style(o.style),
267 format(o.format), bagKeyId(o.bagKeyId), evaluating(false) {
268 memset(&parsedValue, 0, sizeof(parsedValue));
269 }
270 ~Item() { }
271
272 Item& operator=(const Item& o) {
273 sourcePos = o.sourcePos;
274 isId = o.isId;
275 value = o.value;
276 style = o.style;
277 format = o.format;
278 bagKeyId = o.bagKeyId;
279 parsedValue = o.parsedValue;
280 return *this;
281 }
282
283 SourcePos sourcePos;
284 mutable bool isId;
285 String16 value;
286 Vector<StringPool::entry_style_span> style;
287 int32_t format;
288 uint32_t bagKeyId;
289 mutable bool evaluating;
290 Res_value parsedValue;
291 };
292
293 class Entry : public RefBase {
294 public:
295 Entry(const String16& name, const SourcePos& pos)
296 : mName(name), mType(TYPE_UNKNOWN),
297 mItemFormat(ResTable_map::TYPE_ANY), mNameIndex(-1), mPos(pos)
298 { }
299 virtual ~Entry() { }
300
301 enum type {
302 TYPE_UNKNOWN = 0,
303 TYPE_ITEM,
304 TYPE_BAG
305 };
306
307 String16 getName() const { return mName; }
308 type getType() const { return mType; }
309
310 void setParent(const String16& parent) { mParent = parent; }
311 String16 getParent() const { return mParent; }
312
313 status_t makeItABag(const SourcePos& sourcePos);
314
315 status_t emptyBag(const SourcePos& sourcePos);
316
317 status_t setItem(const SourcePos& pos,
318 const String16& value,
319 const Vector<StringPool::entry_style_span>* style = NULL,
320 int32_t format = ResTable_map::TYPE_ANY,
321 const bool overwrite = false);
322
323 status_t addToBag(const SourcePos& pos,
324 const String16& key, const String16& value,
325 const Vector<StringPool::entry_style_span>* style = NULL,
326 bool replace=false, bool isId = false,
327 int32_t format = ResTable_map::TYPE_ANY);
328
329 // Index of the entry's name string in the key pool.
330 int32_t getNameIndex() const { return mNameIndex; }
331 void setNameIndex(int32_t index) { mNameIndex = index; }
332
333 const Item* getItem() const { return mType == TYPE_ITEM ? &mItem : NULL; }
334 const KeyedVector<String16, Item>& getBag() const { return mBag; }
335
336 status_t generateAttributes(ResourceTable* table,
337 const String16& package);
338
339 status_t assignResourceIds(ResourceTable* table,
340 const String16& package);
341
342 status_t prepareFlatten(StringPool* strings, ResourceTable* table,
343 const String8* configTypeName, const ConfigDescription* config);
344
345 status_t remapStringValue(StringPool* strings);
346
347 ssize_t flatten(Bundle*, const sp<AaptFile>& data, bool isPublic);
348
349 const SourcePos& getPos() const { return mPos; }
350
351 private:
352 String16 mName;
353 String16 mParent;
354 type mType;
355 Item mItem;
356 int32_t mItemFormat;
357 KeyedVector<String16, Item> mBag;
358 int32_t mNameIndex;
359 uint32_t mParentId;
360 SourcePos mPos;
361 };
362
363 class ConfigList : public RefBase {
364 public:
365 ConfigList(const String16& name, const SourcePos& pos)
366 : mName(name), mPos(pos), mPublic(false), mEntryIndex(-1) { }
367 virtual ~ConfigList() { }
368
369 String16 getName() const { return mName; }
370 const SourcePos& getPos() const { return mPos; }
371
372 void appendComment(const String16& comment, bool onlyIfEmpty = false);
373 const String16& getComment() const { return mComment; }
374
375 void appendTypeComment(const String16& comment);
376 const String16& getTypeComment() const { return mTypeComment; }
377
378 // Index of this entry in its Type.
379 int32_t getEntryIndex() const { return mEntryIndex; }
380 void setEntryIndex(int32_t index) { mEntryIndex = index; }
381
382 void setPublic(bool pub) { mPublic = pub; }
383 bool getPublic() const { return mPublic; }
384 void setPublicSourcePos(const SourcePos& pos) { mPublicSourcePos = pos; }
385 const SourcePos& getPublicSourcePos() { return mPublicSourcePos; }
386
387 void addEntry(const ResTable_config& config, const sp<Entry>& entry) {
388 mEntries.add(config, entry);
389 }
390
391 const DefaultKeyedVector<ConfigDescription, sp<Entry> >& getEntries() const { return mEntries; }
392 private:
393 const String16 mName;
394 const SourcePos mPos;
395 String16 mComment;
396 String16 mTypeComment;
397 bool mPublic;
398 SourcePos mPublicSourcePos;
399 int32_t mEntryIndex;
400 DefaultKeyedVector<ConfigDescription, sp<Entry> > mEntries;
401 };
402
403 class Public {
404 public:
405 Public() : sourcePos(), ident(0) { }
406 Public(const SourcePos& pos,
407 const String16& _comment,
408 uint32_t _ident)
409 : sourcePos(pos),
410 comment(_comment), ident(_ident) { }
411 Public(const Public& o) : sourcePos(o.sourcePos),
412 comment(o.comment), ident(o.ident) { }
413 ~Public() { }
414
415 Public& operator=(const Public& o) {
416 sourcePos = o.sourcePos;
417 comment = o.comment;
418 ident = o.ident;
419 return *this;
420 }
421
422 SourcePos sourcePos;
423 String16 comment;
424 uint32_t ident;
425 };
426
427 class Type : public RefBase {
428 public:
429 Type(const String16& name, const SourcePos& pos)
430 : mName(name), mFirstPublicSourcePos(NULL), mPublicIndex(-1), mIndex(-1), mPos(pos)
431 { }
432 virtual ~Type() { delete mFirstPublicSourcePos; }
433
434 status_t addPublic(const SourcePos& pos,
435 const String16& name,
436 const uint32_t ident);
437
438 void canAddEntry(const String16& name);
439
440 String16 getName() const { return mName; }
441 sp<Entry> getEntry(const String16& entry,
442 const SourcePos& pos,
443 const ResTable_config* config = NULL,
444 bool doSetIndex = false,
445 bool overlay = false,
446 bool autoAddOverlay = false);
447
448 const SourcePos& getFirstPublicSourcePos() const { return *mFirstPublicSourcePos; }
449
450 int32_t getPublicIndex() const { return mPublicIndex; }
451
452 int32_t getIndex() const { return mIndex; }
453 void setIndex(int32_t index) { mIndex = index; }
454
455 status_t applyPublicEntryOrder();
456
457 const SortedVector<ConfigDescription>& getUniqueConfigs() const { return mUniqueConfigs; }
458
459 const DefaultKeyedVector<String16, sp<ConfigList> >& getConfigs() const { return mConfigs; }
460 const Vector<sp<ConfigList> >& getOrderedConfigs() const { return mOrderedConfigs; }
461
462 const SortedVector<String16>& getCanAddEntries() const { return mCanAddEntries; }
463
464 const SourcePos& getPos() const { return mPos; }
465 private:
466 String16 mName;
467 SourcePos* mFirstPublicSourcePos;
468 DefaultKeyedVector<String16, Public> mPublic;
469 SortedVector<ConfigDescription> mUniqueConfigs;
470 DefaultKeyedVector<String16, sp<ConfigList> > mConfigs;
471 Vector<sp<ConfigList> > mOrderedConfigs;
472 SortedVector<String16> mCanAddEntries;
473 int32_t mPublicIndex;
474 int32_t mIndex;
475 SourcePos mPos;
476 };
477
478 class Package : public RefBase {
479 public:
480 Package(const String16& name, ssize_t includedId=-1);
481 virtual ~Package() { }
482
483 String16 getName() const { return mName; }
484 sp<Type> getType(const String16& type,
485 const SourcePos& pos,
486 bool doSetIndex = false);
487
488 ssize_t getAssignedId() const { return mIncludedId; }
489
490 const ResStringPool& getTypeStrings() const { return mTypeStrings; }
491 uint32_t indexOfTypeString(const String16& s) const { return mTypeStringsMapping.valueFor(s); }
492 const sp<AaptFile> getTypeStringsData() const { return mTypeStringsData; }
493 status_t setTypeStrings(const sp<AaptFile>& data);
494
495 const ResStringPool& getKeyStrings() const { return mKeyStrings; }
496 uint32_t indexOfKeyString(const String16& s) const { return mKeyStringsMapping.valueFor(s); }
497 const sp<AaptFile> getKeyStringsData() const { return mKeyStringsData; }
498 status_t setKeyStrings(const sp<AaptFile>& data);
499
500 status_t applyPublicTypeOrder();
501
502 const DefaultKeyedVector<String16, sp<Type> >& getTypes() const { return mTypes; }
503 const Vector<sp<Type> >& getOrderedTypes() const { return mOrderedTypes; }
504
505 private:
506 status_t setStrings(const sp<AaptFile>& data,
507 ResStringPool* strings,
508 DefaultKeyedVector<String16, uint32_t>* mappings);
509
510 const String16 mName;
511 const ssize_t mIncludedId;
512 DefaultKeyedVector<String16, sp<Type> > mTypes;
513 Vector<sp<Type> > mOrderedTypes;
514 sp<AaptFile> mTypeStringsData;
515 sp<AaptFile> mKeyStringsData;
516 ResStringPool mTypeStrings;
517 ResStringPool mKeyStrings;
518 DefaultKeyedVector<String16, uint32_t> mTypeStringsMapping;
519 DefaultKeyedVector<String16, uint32_t> mKeyStringsMapping;
520 };
521
522private:
523 void writePublicDefinitions(const String16& package, FILE* fp, bool pub);
524 sp<Package> getPackage(const String16& package);
525 sp<Type> getType(const String16& package,
526 const String16& type,
527 const SourcePos& pos,
528 bool doSetIndex = false);
529 sp<Entry> getEntry(const String16& package,
530 const String16& type,
531 const String16& name,
532 const SourcePos& pos,
533 bool overlay,
534 const ResTable_config* config = NULL,
535 bool doSetIndex = false);
536 sp<const Entry> getEntry(uint32_t resID,
537 const ResTable_config* config = NULL) const;
538 const Item* getItem(uint32_t resID, uint32_t attrID) const;
539 bool getItemValue(uint32_t resID, uint32_t attrID,
540 Res_value* outValue);
541
542
543 String16 mAssetsPackage;
544 sp<AaptAssets> mAssets;
545 DefaultKeyedVector<String16, sp<Package> > mPackages;
546 Vector<sp<Package> > mOrderedPackages;
547 uint32_t mNextPackageId;
548 bool mHaveAppPackage;
549 bool mIsAppPackage;
Adam Lesinskide898ff2014-01-29 18:20:45 -0800550 bool mIsSharedLibrary;
Adam Lesinski282e1812014-01-23 18:17:42 -0800551 size_t mNumLocal;
552 SourcePos mCurrentXmlPos;
553 Bundle* mBundle;
554
555 // key = string resource name, value = set of locales in which that name is defined
Adam Lesinskia01a9372014-03-20 18:04:57 -0700556 map<String16, map<String8, SourcePos> > mLocalizations;
Adam Lesinski282e1812014-01-23 18:17:42 -0800557};
558
559#endif