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