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