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