]> git.saurik.com Git - android/aapt.git/blob - ResourceTable.h
Dedupe resource config pointers
[android/aapt.git] / ResourceTable.h
1 //
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
16 using namespace std;
17
18 class XMLNode;
19 class ResourceTable;
20
21 enum {
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 XML_COMPILE_UTF8 = 1<<5,
28
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
34 status_t compileXmlFile(const sp<AaptAssets>& assets,
35 const sp<AaptFile>& target,
36 ResourceTable* table,
37 int options = XML_COMPILE_STANDARD_RESOURCE);
38
39 status_t compileXmlFile(const sp<AaptAssets>& assets,
40 const sp<AaptFile>& target,
41 const sp<AaptFile>& outTarget,
42 ResourceTable* table,
43 int options = XML_COMPILE_STANDARD_RESOURCE);
44
45 status_t compileXmlFile(const sp<AaptAssets>& assets,
46 const sp<XMLNode>& xmlTree,
47 const sp<AaptFile>& target,
48 ResourceTable* table,
49 int options = XML_COMPILE_STANDARD_RESOURCE);
50
51 status_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
58 struct 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
72 class ResourceTable : public ResTable::Accessor
73 {
74 public:
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,
106 bool overlay = false,
107 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
127 bool hasBagOrEntry(const String16& ref,
128 const String16* defType = NULL,
129 const String16* defPackage = NULL);
130
131 bool appendComment(const String16& package,
132 const String16& type,
133 const String16& name,
134 const String16& comment,
135 bool onlyIfEmpty = false);
136
137 bool appendTypeComment(const String16& package,
138 const String16& type,
139 const String16& name,
140 const String16& comment);
141
142 void canAddEntry(const SourcePos& pos,
143 const String16& package, const String16& type, const String16& name);
144
145 size_t size() const;
146 size_t numLocalResources() const;
147 bool hasResources() const;
148
149 sp<AaptFile> flatten(Bundle*);
150
151 static inline uint32_t makeResId(uint32_t packageId,
152 uint32_t typeId,
153 uint32_t nameId)
154 {
155 return nameId | (typeId<<16) | (packageId<<24);
156 }
157
158 static inline uint32_t getResId(const sp<Package>& p,
159 const sp<Type>& t,
160 uint32_t nameId);
161
162 uint32_t getResId(const String16& package,
163 const String16& type,
164 const String16& name,
165 bool onlyPublic = false) const;
166
167 uint32_t getResId(const String16& ref,
168 const String16* defType = NULL,
169 const String16* defPackage = NULL,
170 const char** outErrorMsg = NULL,
171 bool onlyPublic = false) const;
172
173 static bool isValidResourceName(const String16& s);
174
175 bool stringToValue(Res_value* outValue, StringPool* pool,
176 const String16& str,
177 bool preserveSpaces, bool coerceType,
178 uint32_t attrID,
179 const Vector<StringPool::entry_style_span>* style = NULL,
180 String16* outStr = NULL, void* accessorCookie = NULL,
181 uint32_t attrType = ResTable_map::TYPE_ANY);
182
183 status_t assignResourceIds();
184 status_t addSymbols(const sp<AaptSymbols>& outSymbols = NULL);
185 void addLocalization(const String16& name, const String8& locale);
186 status_t validateLocalizations(void);
187
188 status_t flatten(Bundle*, const sp<AaptFile>& dest);
189
190 void writePublicDefinitions(const String16& package, FILE* fp);
191
192 virtual uint32_t getCustomResource(const String16& package,
193 const String16& type,
194 const String16& name) const;
195 virtual uint32_t getCustomResourceWithCreation(const String16& package,
196 const String16& type,
197 const String16& name,
198 const bool createIfNeeded);
199 virtual uint32_t getRemappedPackage(uint32_t origPackage) const;
200 virtual bool getAttributeType(uint32_t attrID, uint32_t* outType);
201 virtual bool getAttributeMin(uint32_t attrID, uint32_t* outMin);
202 virtual bool getAttributeMax(uint32_t attrID, uint32_t* outMax);
203 virtual bool getAttributeKeys(uint32_t attrID, Vector<String16>* outKeys);
204 virtual bool getAttributeEnum(uint32_t attrID,
205 const char16_t* name, size_t nameLen,
206 Res_value* outValue);
207 virtual bool getAttributeFlags(uint32_t attrID,
208 const char16_t* name, size_t nameLen,
209 Res_value* outValue);
210 virtual uint32_t getAttributeL10N(uint32_t attrID);
211
212 virtual bool getLocalizationSetting();
213 virtual void reportError(void* accessorCookie, const char* fmt, ...);
214
215 void setCurrentXmlPos(const SourcePos& pos) { mCurrentXmlPos = pos; }
216
217 class Item {
218 public:
219 Item() : isId(false), format(ResTable_map::TYPE_ANY), bagKeyId(0), evaluating(false)
220 { memset(&parsedValue, 0, sizeof(parsedValue)); }
221 Item(const SourcePos& pos,
222 bool _isId,
223 const String16& _value,
224 const Vector<StringPool::entry_style_span>* _style = NULL,
225 int32_t format = ResTable_map::TYPE_ANY);
226 Item(const Item& o) : sourcePos(o.sourcePos),
227 isId(o.isId), value(o.value), style(o.style),
228 format(o.format), bagKeyId(o.bagKeyId), evaluating(false) {
229 memset(&parsedValue, 0, sizeof(parsedValue));
230 }
231 ~Item() { }
232
233 Item& operator=(const Item& o) {
234 sourcePos = o.sourcePos;
235 isId = o.isId;
236 value = o.value;
237 style = o.style;
238 format = o.format;
239 bagKeyId = o.bagKeyId;
240 parsedValue = o.parsedValue;
241 return *this;
242 }
243
244 SourcePos sourcePos;
245 mutable bool isId;
246 String16 value;
247 Vector<StringPool::entry_style_span> style;
248 int32_t format;
249 uint32_t bagKeyId;
250 mutable bool evaluating;
251 Res_value parsedValue;
252 };
253
254 class Entry : public RefBase {
255 public:
256 Entry(const String16& name, const SourcePos& pos)
257 : mName(name), mType(TYPE_UNKNOWN),
258 mItemFormat(ResTable_map::TYPE_ANY), mNameIndex(-1), mPos(pos)
259 { }
260 virtual ~Entry() { }
261
262 enum type {
263 TYPE_UNKNOWN = 0,
264 TYPE_ITEM,
265 TYPE_BAG
266 };
267
268 String16 getName() const { return mName; }
269 type getType() const { return mType; }
270
271 void setParent(const String16& parent) { mParent = parent; }
272 String16 getParent() const { return mParent; }
273
274 status_t makeItABag(const SourcePos& sourcePos);
275
276 status_t emptyBag(const SourcePos& sourcePos);
277
278 status_t setItem(const SourcePos& pos,
279 const String16& value,
280 const Vector<StringPool::entry_style_span>* style = NULL,
281 int32_t format = ResTable_map::TYPE_ANY,
282 const bool overwrite = false);
283
284 status_t addToBag(const SourcePos& pos,
285 const String16& key, const String16& value,
286 const Vector<StringPool::entry_style_span>* style = NULL,
287 bool replace=false, bool isId = false,
288 int32_t format = ResTable_map::TYPE_ANY);
289
290 // Index of the entry's name string in the key pool.
291 int32_t getNameIndex() const { return mNameIndex; }
292 void setNameIndex(int32_t index) { mNameIndex = index; }
293
294 const Item* getItem() const { return mType == TYPE_ITEM ? &mItem : NULL; }
295 const KeyedVector<String16, Item>& getBag() const { return mBag; }
296
297 status_t generateAttributes(ResourceTable* table,
298 const String16& package);
299
300 status_t assignResourceIds(ResourceTable* table,
301 const String16& package);
302
303 status_t prepareFlatten(StringPool* strings, ResourceTable* table);
304
305 ssize_t flatten(Bundle*, const sp<AaptFile>& data, bool isPublic);
306
307 const SourcePos& getPos() const { return mPos; }
308
309 private:
310 String16 mName;
311 String16 mParent;
312 type mType;
313 Item mItem;
314 int32_t mItemFormat;
315 KeyedVector<String16, Item> mBag;
316 int32_t mNameIndex;
317 uint32_t mParentId;
318 SourcePos mPos;
319 };
320
321 struct ConfigDescription : public ResTable_config {
322 ConfigDescription() {
323 memset(this, 0, sizeof(*this));
324 size = sizeof(ResTable_config);
325 }
326 ConfigDescription(const ResTable_config&o) {
327 *static_cast<ResTable_config*>(this) = o;
328 size = sizeof(ResTable_config);
329 }
330 ConfigDescription(const ConfigDescription&o) {
331 *static_cast<ResTable_config*>(this) = o;
332 }
333
334 ConfigDescription& operator=(const ResTable_config& o) {
335 *static_cast<ResTable_config*>(this) = o;
336 size = sizeof(ResTable_config);
337 return *this;
338 }
339 ConfigDescription& operator=(const ConfigDescription& o) {
340 *static_cast<ResTable_config*>(this) = o;
341 return *this;
342 }
343
344 inline bool operator<(const ConfigDescription& o) const { return compare(o) < 0; }
345 inline bool operator<=(const ConfigDescription& o) const { return compare(o) <= 0; }
346 inline bool operator==(const ConfigDescription& o) const { return compare(o) == 0; }
347 inline bool operator!=(const ConfigDescription& o) const { return compare(o) != 0; }
348 inline bool operator>=(const ConfigDescription& o) const { return compare(o) >= 0; }
349 inline bool operator>(const ConfigDescription& o) const { return compare(o) > 0; }
350 };
351
352 class ConfigList : public RefBase {
353 public:
354 ConfigList(const String16& name, const SourcePos& pos)
355 : mName(name), mPos(pos), mPublic(false), mEntryIndex(-1) { }
356 virtual ~ConfigList() { }
357
358 String16 getName() const { return mName; }
359 const SourcePos& getPos() const { return mPos; }
360
361 void appendComment(const String16& comment, bool onlyIfEmpty = false);
362 const String16& getComment() const { return mComment; }
363
364 void appendTypeComment(const String16& comment);
365 const String16& getTypeComment() const { return mTypeComment; }
366
367 // Index of this entry in its Type.
368 int32_t getEntryIndex() const { return mEntryIndex; }
369 void setEntryIndex(int32_t index) { mEntryIndex = index; }
370
371 void setPublic(bool pub) { mPublic = pub; }
372 bool getPublic() const { return mPublic; }
373 void setPublicSourcePos(const SourcePos& pos) { mPublicSourcePos = pos; }
374 const SourcePos& getPublicSourcePos() { return mPublicSourcePos; }
375
376 void addEntry(const ResTable_config& config, const sp<Entry>& entry) {
377 mEntries.add(config, entry);
378 }
379
380 void removeEntryAt(int32_t index) {
381 mEntries.removeItemsAt(index);
382 }
383
384 const DefaultKeyedVector<ConfigDescription, sp<Entry> >& getEntries() const { return mEntries; }
385 private:
386 const String16 mName;
387 const SourcePos mPos;
388 String16 mComment;
389 String16 mTypeComment;
390 bool mPublic;
391 SourcePos mPublicSourcePos;
392 int32_t mEntryIndex;
393 DefaultKeyedVector<ConfigDescription, sp<Entry> > mEntries;
394 };
395
396 class Public {
397 public:
398 Public() : sourcePos(), ident(0) { }
399 Public(const SourcePos& pos,
400 const String16& _comment,
401 uint32_t _ident)
402 : sourcePos(pos),
403 comment(_comment), ident(_ident) { }
404 Public(const Public& o) : sourcePos(o.sourcePos),
405 comment(o.comment), ident(o.ident) { }
406 ~Public() { }
407
408 Public& operator=(const Public& o) {
409 sourcePos = o.sourcePos;
410 comment = o.comment;
411 ident = o.ident;
412 return *this;
413 }
414
415 SourcePos sourcePos;
416 String16 comment;
417 uint32_t ident;
418 };
419
420 class Type : public RefBase {
421 public:
422 Type(const String16& name, const SourcePos& pos)
423 : mName(name), mFirstPublicSourcePos(NULL), mPublicIndex(-1), mIndex(-1), mPos(pos)
424 { }
425 virtual ~Type() { delete mFirstPublicSourcePos; }
426
427 status_t addPublic(const SourcePos& pos,
428 const String16& name,
429 const uint32_t ident);
430
431 void canAddEntry(const String16& name);
432
433 String16 getName() const { return mName; }
434 sp<Entry> getEntry(const String16& entry,
435 const SourcePos& pos,
436 const ResTable_config* config = NULL,
437 bool doSetIndex = false,
438 bool overlay = false,
439 bool autoAddOverlay = false);
440
441 const SourcePos& getFirstPublicSourcePos() const { return *mFirstPublicSourcePos; }
442
443 int32_t getPublicIndex() const { return mPublicIndex; }
444
445 int32_t getIndex() const { return mIndex; }
446 void setIndex(int32_t index) { mIndex = index; }
447
448 status_t applyPublicEntryOrder();
449
450 const SortedVector<ConfigDescription>& getUniqueConfigs() const { return mUniqueConfigs; }
451
452 const DefaultKeyedVector<String16, sp<ConfigList> >& getConfigs() const { return mConfigs; }
453 const Vector<sp<ConfigList> >& getOrderedConfigs() const { return mOrderedConfigs; }
454
455 void removeUniqueConfig(ConfigDescription& config) { mUniqueConfigs.remove(config); }
456 void removeOrderedConfigAt(uint32_t index) { mOrderedConfigs.removeItemsAt(index); }
457
458 const SortedVector<String16>& getCanAddEntries() const { return mCanAddEntries; }
459
460 const SourcePos& getPos() const { return mPos; }
461 private:
462 String16 mName;
463 SourcePos* mFirstPublicSourcePos;
464 DefaultKeyedVector<String16, Public> mPublic;
465 SortedVector<ConfigDescription> mUniqueConfigs;
466 DefaultKeyedVector<String16, sp<ConfigList> > mConfigs;
467 Vector<sp<ConfigList> > mOrderedConfigs;
468 SortedVector<String16> mCanAddEntries;
469 int32_t mPublicIndex;
470 int32_t mIndex;
471 SourcePos mPos;
472 };
473
474 class Package : public RefBase {
475 public:
476 Package(const String16& name, ssize_t includedId=-1);
477 virtual ~Package() { }
478
479 String16 getName() const { return mName; }
480 sp<Type> getType(const String16& type,
481 const SourcePos& pos,
482 bool doSetIndex = false);
483
484 ssize_t getAssignedId() const { return mIncludedId; }
485
486 const ResStringPool& getTypeStrings() const { return mTypeStrings; }
487 uint32_t indexOfTypeString(const String16& s) const { return mTypeStringsMapping.valueFor(s); }
488 const sp<AaptFile> getTypeStringsData() const { return mTypeStringsData; }
489 status_t setTypeStrings(const sp<AaptFile>& data);
490
491 const ResStringPool& getKeyStrings() const { return mKeyStrings; }
492 uint32_t indexOfKeyString(const String16& s) const { return mKeyStringsMapping.valueFor(s); }
493 const sp<AaptFile> getKeyStringsData() const { return mKeyStringsData; }
494 status_t setKeyStrings(const sp<AaptFile>& data);
495
496 status_t applyPublicTypeOrder();
497
498 const DefaultKeyedVector<String16, sp<Type> >& getTypes() const { return mTypes; }
499 const Vector<sp<Type> >& getOrderedTypes() const { return mOrderedTypes; }
500
501 private:
502 status_t setStrings(const sp<AaptFile>& data,
503 ResStringPool* strings,
504 DefaultKeyedVector<String16, uint32_t>* mappings);
505
506 const String16 mName;
507 const ssize_t mIncludedId;
508 DefaultKeyedVector<String16, sp<Type> > mTypes;
509 Vector<sp<Type> > mOrderedTypes;
510 sp<AaptFile> mTypeStringsData;
511 sp<AaptFile> mKeyStringsData;
512 ResStringPool mTypeStrings;
513 ResStringPool mKeyStrings;
514 DefaultKeyedVector<String16, uint32_t> mTypeStringsMapping;
515 DefaultKeyedVector<String16, uint32_t> mKeyStringsMapping;
516 };
517
518 private:
519 void writePublicDefinitions(const String16& package, FILE* fp, bool pub);
520 sp<Package> getPackage(const String16& package);
521 sp<Type> getType(const String16& package,
522 const String16& type,
523 const SourcePos& pos,
524 bool doSetIndex = false);
525 sp<Entry> getEntry(const String16& package,
526 const String16& type,
527 const String16& name,
528 const SourcePos& pos,
529 bool overlay,
530 const ResTable_config* config = NULL,
531 bool doSetIndex = false);
532 sp<const Entry> getEntry(uint32_t resID,
533 const ResTable_config* config = NULL) const;
534 const Item* getItem(uint32_t resID, uint32_t attrID) const;
535 bool getItemValue(uint32_t resID, uint32_t attrID,
536 Res_value* outValue);
537
538
539 String16 mAssetsPackage;
540 sp<AaptAssets> mAssets;
541 DefaultKeyedVector<String16, sp<Package> > mPackages;
542 Vector<sp<Package> > mOrderedPackages;
543 uint32_t mNextPackageId;
544 bool mHaveAppPackage;
545 bool mIsAppPackage;
546 size_t mNumLocal;
547 SourcePos mCurrentXmlPos;
548 Bundle* mBundle;
549
550 // key = string resource name, value = set of locales in which that name is defined
551 map<String16, set<String8> > mLocalizations;
552 };
553
554 class ResourceFilter
555 {
556 public:
557 ResourceFilter() : mData(), mContainsPseudo(false) {}
558 status_t parse(const char* arg);
559 bool match(int axis, uint32_t value);
560 bool match(const ResTable_config& config);
561 inline bool containsPseudo() { return mContainsPseudo; }
562
563 private:
564 KeyedVector<int,SortedVector<uint32_t> > mData;
565 bool mContainsPseudo;
566 };
567
568 class ResourceConfigReferences
569 {
570 public:
571 ResourceConfigReferences() : mRoots() {}
572 ~ResourceConfigReferences();
573 status_t add(uint32_t id, const ResTable_config& config);
574 bool isRoot(uint32_t id, const ResTable_config& config);
575 void dump();
576
577 private:
578 KeyedVector<uint32_t, Vector<const ResTable_config*> > mRoots;
579 };
580
581 #endif