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