blob: a3e066690fba4e747480f9aec8f61c1bc7a643b2 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -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
Dianne Hackborna96cbb42009-05-13 15:06:13 -070018class XMLNode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080019class 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,
Kenny Root19138462009-12-04 09:38:48 -080027 XML_COMPILE_UTF8 = 1<<5,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028
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
Dianne Hackborna96cbb42009-05-13 15:06:13 -070039status_t compileXmlFile(const sp<AaptAssets>& assets,
Dianne Hackborncf244ad2010-03-09 15:00:30 -080040 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,
Dianne Hackborna96cbb42009-05-13 15:06:13 -070046 const sp<XMLNode>& xmlTree,
47 const sp<AaptFile>& target,
48 ResourceTable* table,
49 int options = XML_COMPILE_STANDARD_RESOURCE);
50
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051status_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
Dianne Hackborn6c997a92012-01-31 11:27:43 -080079 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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110 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,
Robert Greenwalt1aa81702009-06-05 15:59:15 -0700137 bool overlay = false,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138 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
Eric Fischer914f7e62011-09-27 16:09:41 -0700158 bool hasBagOrEntry(const String16& package,
159 const String16& type,
160 const String16& name,
161 const ResTable_config& config) const;
162
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163 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
Dianne Hackborn58c27a02009-08-13 13:36:00 -0700178 void canAddEntry(const SourcePos& pos,
179 const String16& package, const String16& type, const String16& name);
180
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800181 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,
Dianne Hackborn426431a2011-06-09 11:29:08 -0700201 bool onlyPublic = true) const;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800202
203 uint32_t getResId(const String16& ref,
204 const String16* defType = NULL,
205 const String16* defPackage = NULL,
206 const char** outErrorMsg = NULL,
Dianne Hackborn426431a2011-06-09 11:29:08 -0700207 bool onlyPublic = true) const;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800208
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,
Dianne Hackborn6c997a92012-01-31 11:27:43 -0800217 uint32_t attrType = ResTable_map::TYPE_ANY,
218 const String8* configTypeName = NULL,
219 const ConfigDescription* config = NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800220
221 status_t assignResourceIds();
222 status_t addSymbols(const sp<AaptSymbols>& outSymbols = NULL);
223 void addLocalization(const String16& name, const String8& locale);
224 status_t validateLocalizations(void);
225
226 status_t flatten(Bundle*, const sp<AaptFile>& dest);
227
228 void writePublicDefinitions(const String16& package, FILE* fp);
229
230 virtual uint32_t getCustomResource(const String16& package,
231 const String16& type,
232 const String16& name) const;
233 virtual uint32_t getCustomResourceWithCreation(const String16& package,
234 const String16& type,
235 const String16& name,
236 const bool createIfNeeded);
237 virtual uint32_t getRemappedPackage(uint32_t origPackage) const;
238 virtual bool getAttributeType(uint32_t attrID, uint32_t* outType);
239 virtual bool getAttributeMin(uint32_t attrID, uint32_t* outMin);
240 virtual bool getAttributeMax(uint32_t attrID, uint32_t* outMax);
241 virtual bool getAttributeKeys(uint32_t attrID, Vector<String16>* outKeys);
242 virtual bool getAttributeEnum(uint32_t attrID,
243 const char16_t* name, size_t nameLen,
244 Res_value* outValue);
245 virtual bool getAttributeFlags(uint32_t attrID,
246 const char16_t* name, size_t nameLen,
247 Res_value* outValue);
248 virtual uint32_t getAttributeL10N(uint32_t attrID);
249
250 virtual bool getLocalizationSetting();
251 virtual void reportError(void* accessorCookie, const char* fmt, ...);
252
253 void setCurrentXmlPos(const SourcePos& pos) { mCurrentXmlPos = pos; }
254
255 class Item {
256 public:
257 Item() : isId(false), format(ResTable_map::TYPE_ANY), bagKeyId(0), evaluating(false)
258 { memset(&parsedValue, 0, sizeof(parsedValue)); }
259 Item(const SourcePos& pos,
260 bool _isId,
261 const String16& _value,
262 const Vector<StringPool::entry_style_span>* _style = NULL,
263 int32_t format = ResTable_map::TYPE_ANY);
264 Item(const Item& o) : sourcePos(o.sourcePos),
265 isId(o.isId), value(o.value), style(o.style),
266 format(o.format), bagKeyId(o.bagKeyId), evaluating(false) {
267 memset(&parsedValue, 0, sizeof(parsedValue));
268 }
269 ~Item() { }
270
271 Item& operator=(const Item& o) {
272 sourcePos = o.sourcePos;
273 isId = o.isId;
274 value = o.value;
275 style = o.style;
276 format = o.format;
277 bagKeyId = o.bagKeyId;
278 parsedValue = o.parsedValue;
279 return *this;
280 }
281
282 SourcePos sourcePos;
283 mutable bool isId;
284 String16 value;
285 Vector<StringPool::entry_style_span> style;
286 int32_t format;
287 uint32_t bagKeyId;
288 mutable bool evaluating;
289 Res_value parsedValue;
290 };
291
292 class Entry : public RefBase {
293 public:
294 Entry(const String16& name, const SourcePos& pos)
295 : mName(name), mType(TYPE_UNKNOWN),
296 mItemFormat(ResTable_map::TYPE_ANY), mNameIndex(-1), mPos(pos)
297 { }
298 virtual ~Entry() { }
299
300 enum type {
301 TYPE_UNKNOWN = 0,
302 TYPE_ITEM,
303 TYPE_BAG
304 };
305
306 String16 getName() const { return mName; }
307 type getType() const { return mType; }
308
309 void setParent(const String16& parent) { mParent = parent; }
310 String16 getParent() const { return mParent; }
311
312 status_t makeItABag(const SourcePos& sourcePos);
Robert Greenwalt4b4f4a92009-04-02 16:55:50 -0700313
314 status_t emptyBag(const SourcePos& sourcePos);
315
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800316 status_t setItem(const SourcePos& pos,
317 const String16& value,
318 const Vector<StringPool::entry_style_span>* style = NULL,
319 int32_t format = ResTable_map::TYPE_ANY,
320 const bool overwrite = false);
321
322 status_t addToBag(const SourcePos& pos,
323 const String16& key, const String16& value,
324 const Vector<StringPool::entry_style_span>* style = NULL,
325 bool replace=false, bool isId = false,
326 int32_t format = ResTable_map::TYPE_ANY);
327
328 // Index of the entry's name string in the key pool.
329 int32_t getNameIndex() const { return mNameIndex; }
330 void setNameIndex(int32_t index) { mNameIndex = index; }
331
332 const Item* getItem() const { return mType == TYPE_ITEM ? &mItem : NULL; }
333 const KeyedVector<String16, Item>& getBag() const { return mBag; }
334
335 status_t generateAttributes(ResourceTable* table,
336 const String16& package);
337
338 status_t assignResourceIds(ResourceTable* table,
339 const String16& package);
340
Dianne Hackborn6c997a92012-01-31 11:27:43 -0800341 status_t prepareFlatten(StringPool* strings, ResourceTable* table,
342 const String8* configTypeName, const ConfigDescription* config);
343
344 status_t remapStringValue(StringPool* strings);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800345
346 ssize_t flatten(Bundle*, const sp<AaptFile>& data, bool isPublic);
347
348 const SourcePos& getPos() const { return mPos; }
349
350 private:
351 String16 mName;
352 String16 mParent;
353 type mType;
354 Item mItem;
355 int32_t mItemFormat;
356 KeyedVector<String16, Item> mBag;
357 int32_t mNameIndex;
358 uint32_t mParentId;
359 SourcePos mPos;
360 };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800361
362 class ConfigList : public RefBase {
363 public:
364 ConfigList(const String16& name, const SourcePos& pos)
365 : mName(name), mPos(pos), mPublic(false), mEntryIndex(-1) { }
366 virtual ~ConfigList() { }
367
368 String16 getName() const { return mName; }
369 const SourcePos& getPos() const { return mPos; }
370
371 void appendComment(const String16& comment, bool onlyIfEmpty = false);
372 const String16& getComment() const { return mComment; }
373
374 void appendTypeComment(const String16& comment);
375 const String16& getTypeComment() const { return mTypeComment; }
376
377 // Index of this entry in its Type.
378 int32_t getEntryIndex() const { return mEntryIndex; }
379 void setEntryIndex(int32_t index) { mEntryIndex = index; }
380
381 void setPublic(bool pub) { mPublic = pub; }
382 bool getPublic() const { return mPublic; }
383 void setPublicSourcePos(const SourcePos& pos) { mPublicSourcePos = pos; }
384 const SourcePos& getPublicSourcePos() { return mPublicSourcePos; }
385
386 void addEntry(const ResTable_config& config, const sp<Entry>& entry) {
387 mEntries.add(config, entry);
388 }
389
390 const DefaultKeyedVector<ConfigDescription, sp<Entry> >& getEntries() const { return mEntries; }
391 private:
392 const String16 mName;
393 const SourcePos mPos;
394 String16 mComment;
395 String16 mTypeComment;
396 bool mPublic;
397 SourcePos mPublicSourcePos;
398 int32_t mEntryIndex;
399 DefaultKeyedVector<ConfigDescription, sp<Entry> > mEntries;
400 };
401
402 class Public {
403 public:
404 Public() : sourcePos(), ident(0) { }
405 Public(const SourcePos& pos,
406 const String16& _comment,
407 uint32_t _ident)
408 : sourcePos(pos),
409 comment(_comment), ident(_ident) { }
410 Public(const Public& o) : sourcePos(o.sourcePos),
411 comment(o.comment), ident(o.ident) { }
412 ~Public() { }
413
414 Public& operator=(const Public& o) {
415 sourcePos = o.sourcePos;
416 comment = o.comment;
417 ident = o.ident;
418 return *this;
419 }
420
421 SourcePos sourcePos;
422 String16 comment;
423 uint32_t ident;
424 };
425
426 class Type : public RefBase {
427 public:
428 Type(const String16& name, const SourcePos& pos)
429 : mName(name), mFirstPublicSourcePos(NULL), mPublicIndex(-1), mIndex(-1), mPos(pos)
430 { }
431 virtual ~Type() { delete mFirstPublicSourcePos; }
432
433 status_t addPublic(const SourcePos& pos,
434 const String16& name,
435 const uint32_t ident);
Dianne Hackborn58c27a02009-08-13 13:36:00 -0700436
437 void canAddEntry(const String16& name);
438
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800439 String16 getName() const { return mName; }
440 sp<Entry> getEntry(const String16& entry,
441 const SourcePos& pos,
442 const ResTable_config* config = NULL,
Robert Greenwaltf878e2d2009-06-09 09:14:20 -0700443 bool doSetIndex = false,
Xavier Ducrohet99080c72010-02-04 18:45:31 -0800444 bool overlay = false,
445 bool autoAddOverlay = false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800446
447 const SourcePos& getFirstPublicSourcePos() const { return *mFirstPublicSourcePos; }
448
449 int32_t getPublicIndex() const { return mPublicIndex; }
450
451 int32_t getIndex() const { return mIndex; }
452 void setIndex(int32_t index) { mIndex = index; }
453
454 status_t applyPublicEntryOrder();
455
456 const SortedVector<ConfigDescription>& getUniqueConfigs() const { return mUniqueConfigs; }
457
458 const DefaultKeyedVector<String16, sp<ConfigList> >& getConfigs() const { return mConfigs; }
459 const Vector<sp<ConfigList> >& getOrderedConfigs() const { return mOrderedConfigs; }
460
Dianne Hackborn58c27a02009-08-13 13:36:00 -0700461 const SortedVector<String16>& getCanAddEntries() const { return mCanAddEntries; }
462
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800463 const SourcePos& getPos() const { return mPos; }
464 private:
465 String16 mName;
466 SourcePos* mFirstPublicSourcePos;
467 DefaultKeyedVector<String16, Public> mPublic;
468 SortedVector<ConfigDescription> mUniqueConfigs;
469 DefaultKeyedVector<String16, sp<ConfigList> > mConfigs;
470 Vector<sp<ConfigList> > mOrderedConfigs;
Dianne Hackborn58c27a02009-08-13 13:36:00 -0700471 SortedVector<String16> mCanAddEntries;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800472 int32_t mPublicIndex;
473 int32_t mIndex;
474 SourcePos mPos;
475 };
476
477 class Package : public RefBase {
478 public:
479 Package(const String16& name, ssize_t includedId=-1);
480 virtual ~Package() { }
481
482 String16 getName() const { return mName; }
483 sp<Type> getType(const String16& type,
484 const SourcePos& pos,
485 bool doSetIndex = false);
486
487 ssize_t getAssignedId() const { return mIncludedId; }
488
489 const ResStringPool& getTypeStrings() const { return mTypeStrings; }
490 uint32_t indexOfTypeString(const String16& s) const { return mTypeStringsMapping.valueFor(s); }
491 const sp<AaptFile> getTypeStringsData() const { return mTypeStringsData; }
492 status_t setTypeStrings(const sp<AaptFile>& data);
493
494 const ResStringPool& getKeyStrings() const { return mKeyStrings; }
495 uint32_t indexOfKeyString(const String16& s) const { return mKeyStringsMapping.valueFor(s); }
496 const sp<AaptFile> getKeyStringsData() const { return mKeyStringsData; }
497 status_t setKeyStrings(const sp<AaptFile>& data);
498
499 status_t applyPublicTypeOrder();
500
501 const DefaultKeyedVector<String16, sp<Type> >& getTypes() const { return mTypes; }
502 const Vector<sp<Type> >& getOrderedTypes() const { return mOrderedTypes; }
503
504 private:
505 status_t setStrings(const sp<AaptFile>& data,
506 ResStringPool* strings,
507 DefaultKeyedVector<String16, uint32_t>* mappings);
508
509 const String16 mName;
510 const ssize_t mIncludedId;
511 DefaultKeyedVector<String16, sp<Type> > mTypes;
512 Vector<sp<Type> > mOrderedTypes;
513 sp<AaptFile> mTypeStringsData;
514 sp<AaptFile> mKeyStringsData;
515 ResStringPool mTypeStrings;
516 ResStringPool mKeyStrings;
517 DefaultKeyedVector<String16, uint32_t> mTypeStringsMapping;
518 DefaultKeyedVector<String16, uint32_t> mKeyStringsMapping;
519 };
520
521private:
522 void writePublicDefinitions(const String16& package, FILE* fp, bool pub);
523 sp<Package> getPackage(const String16& package);
524 sp<Type> getType(const String16& package,
525 const String16& type,
526 const SourcePos& pos,
527 bool doSetIndex = false);
528 sp<Entry> getEntry(const String16& package,
529 const String16& type,
530 const String16& name,
531 const SourcePos& pos,
Robert Greenwaltf878e2d2009-06-09 09:14:20 -0700532 bool overlay,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800533 const ResTable_config* config = NULL,
534 bool doSetIndex = false);
535 sp<const Entry> getEntry(uint32_t resID,
536 const ResTable_config* config = NULL) const;
537 const Item* getItem(uint32_t resID, uint32_t attrID) const;
538 bool getItemValue(uint32_t resID, uint32_t attrID,
539 Res_value* outValue);
540
541
542 String16 mAssetsPackage;
543 sp<AaptAssets> mAssets;
544 DefaultKeyedVector<String16, sp<Package> > mPackages;
545 Vector<sp<Package> > mOrderedPackages;
546 uint32_t mNextPackageId;
547 bool mHaveAppPackage;
548 bool mIsAppPackage;
549 size_t mNumLocal;
550 SourcePos mCurrentXmlPos;
551 Bundle* mBundle;
552
553 // key = string resource name, value = set of locales in which that name is defined
554 map<String16, set<String8> > mLocalizations;
555};
556
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800557#endif