blob: a73993c9022f031b5668f69211136dab1d7a0748 [file] [log] [blame]
Adam Lesinski282e1812014-01-23 18:17:42 -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
Adam Lesinskifab50872014-04-16 14:40:42 -070010#include "ConfigDescription.h"
Adam Lesinski282e1812014-01-23 18:17:42 -080011#include "StringPool.h"
12#include "SourcePos.h"
Adam Lesinskifab50872014-04-16 14:40:42 -070013#include "ResourceFilter.h"
Adam Lesinski282e1812014-01-23 18:17:42 -080014
15#include <set>
16#include <map>
17
18using namespace std;
19
20class XMLNode;
21class ResourceTable;
22
23enum {
24 XML_COMPILE_STRIP_COMMENTS = 1<<0,
25 XML_COMPILE_ASSIGN_ATTRIBUTE_IDS = 1<<1,
26 XML_COMPILE_COMPACT_WHITESPACE = 1<<2,
27 XML_COMPILE_STRIP_WHITESPACE = 1<<3,
28 XML_COMPILE_STRIP_RAW_VALUES = 1<<4,
29 XML_COMPILE_UTF8 = 1<<5,
30
31 XML_COMPILE_STANDARD_RESOURCE =
32 XML_COMPILE_STRIP_COMMENTS | XML_COMPILE_ASSIGN_ATTRIBUTE_IDS
33 | XML_COMPILE_STRIP_WHITESPACE | XML_COMPILE_STRIP_RAW_VALUES
34};
35
36status_t compileXmlFile(const sp<AaptAssets>& assets,
37 const sp<AaptFile>& target,
38 ResourceTable* table,
39 int options = XML_COMPILE_STANDARD_RESOURCE);
40
41status_t compileXmlFile(const sp<AaptAssets>& assets,
42 const sp<AaptFile>& target,
43 const sp<AaptFile>& outTarget,
44 ResourceTable* table,
45 int options = XML_COMPILE_STANDARD_RESOURCE);
46
47status_t compileXmlFile(const sp<AaptAssets>& assets,
48 const sp<XMLNode>& xmlTree,
49 const sp<AaptFile>& target,
50 ResourceTable* table,
51 int options = XML_COMPILE_STANDARD_RESOURCE);
52
53status_t compileResourceFile(Bundle* bundle,
54 const sp<AaptAssets>& assets,
55 const sp<AaptFile>& in,
56 const ResTable_config& defParams,
57 const bool overwrite,
58 ResourceTable* outTable);
59
60struct AccessorCookie
61{
62 SourcePos sourcePos;
63 String8 attr;
64 String8 value;
65
66 AccessorCookie(const SourcePos&p, const String8& a, const String8& v)
67 :sourcePos(p),
68 attr(a),
69 value(v)
70 {
71 }
72};
73
74class ResourceTable : public ResTable::Accessor
75{
76public:
77 class Package;
78 class Type;
79 class Entry;
80
Adam Lesinski282e1812014-01-23 18:17:42 -080081 ResourceTable(Bundle* bundle, const String16& assetsPackage);
82
83 status_t addIncludedResources(Bundle* bundle, const sp<AaptAssets>& assets);
84
85 status_t addPublic(const SourcePos& pos,
86 const String16& package,
87 const String16& type,
88 const String16& name,
89 const uint32_t ident);
90
91 status_t addEntry(const SourcePos& pos,
92 const String16& package,
93 const String16& type,
94 const String16& name,
95 const String16& value,
96 const Vector<StringPool::entry_style_span>* style = NULL,
97 const ResTable_config* params = NULL,
98 const bool doSetIndex = false,
99 const int32_t format = ResTable_map::TYPE_ANY,
100 const bool overwrite = false);
101
102 status_t startBag(const SourcePos& pos,
103 const String16& package,
104 const String16& type,
105 const String16& name,
106 const String16& bagParent,
107 const ResTable_config* params = NULL,
108 bool overlay = false,
109 bool replace = false,
110 bool isId = false);
111
112 status_t addBag(const SourcePos& pos,
113 const String16& package,
114 const String16& type,
115 const String16& name,
116 const String16& bagParent,
117 const String16& bagKey,
118 const String16& value,
119 const Vector<StringPool::entry_style_span>* style = NULL,
120 const ResTable_config* params = NULL,
121 bool replace = false,
122 bool isId = false,
123 const int32_t format = ResTable_map::TYPE_ANY);
124
125 bool hasBagOrEntry(const String16& package,
126 const String16& type,
127 const String16& name) const;
128
129 bool hasBagOrEntry(const String16& package,
130 const String16& type,
131 const String16& name,
132 const ResTable_config& config) const;
133
134 bool hasBagOrEntry(const String16& ref,
135 const String16* defType = NULL,
136 const String16* defPackage = NULL);
137
138 bool appendComment(const String16& package,
139 const String16& type,
140 const String16& name,
141 const String16& comment,
142 bool onlyIfEmpty = false);
143
144 bool appendTypeComment(const String16& package,
145 const String16& type,
146 const String16& name,
147 const String16& comment);
148
149 void canAddEntry(const SourcePos& pos,
150 const String16& package, const String16& type, const String16& name);
151
152 size_t size() const;
153 size_t numLocalResources() const;
154 bool hasResources() const;
155
Adam Lesinskifab50872014-04-16 14:40:42 -0700156 sp<AaptFile> flatten(Bundle* bundle, const sp<const ResourceFilter>& filter);
Adam Lesinski282e1812014-01-23 18:17:42 -0800157
158 static inline uint32_t makeResId(uint32_t packageId,
159 uint32_t typeId,
160 uint32_t nameId)
161 {
162 return nameId | (typeId<<16) | (packageId<<24);
163 }
164
165 static inline uint32_t getResId(const sp<Package>& p,
166 const sp<Type>& t,
167 uint32_t nameId);
168
169 uint32_t getResId(const String16& package,
170 const String16& type,
171 const String16& name,
172 bool onlyPublic = true) const;
173
174 uint32_t getResId(const String16& ref,
175 const String16* defType = NULL,
176 const String16* defPackage = NULL,
177 const char** outErrorMsg = NULL,
178 bool onlyPublic = true) const;
179
180 static bool isValidResourceName(const String16& s);
181
182 bool stringToValue(Res_value* outValue, StringPool* pool,
183 const String16& str,
184 bool preserveSpaces, bool coerceType,
185 uint32_t attrID,
186 const Vector<StringPool::entry_style_span>* style = NULL,
187 String16* outStr = NULL, void* accessorCookie = NULL,
188 uint32_t attrType = ResTable_map::TYPE_ANY,
189 const String8* configTypeName = NULL,
190 const ConfigDescription* config = NULL);
191
192 status_t assignResourceIds();
193 status_t addSymbols(const sp<AaptSymbols>& outSymbols = NULL);
Adam Lesinskia01a9372014-03-20 18:04:57 -0700194 void addLocalization(const String16& name, const String8& locale, const SourcePos& src);
Adam Lesinski282e1812014-01-23 18:17:42 -0800195 status_t validateLocalizations(void);
196
Adam Lesinskifab50872014-04-16 14:40:42 -0700197 status_t flatten(Bundle* bundle, const sp<const ResourceFilter>& filter, const sp<AaptFile>& dest);
Adam Lesinskide898ff2014-01-29 18:20:45 -0800198 status_t flattenLibraryTable(const sp<AaptFile>& dest, const Vector<sp<Package> >& libs);
Adam Lesinski282e1812014-01-23 18:17:42 -0800199
200 void writePublicDefinitions(const String16& package, FILE* fp);
201
202 virtual uint32_t getCustomResource(const String16& package,
203 const String16& type,
204 const String16& name) const;
205 virtual uint32_t getCustomResourceWithCreation(const String16& package,
206 const String16& type,
207 const String16& name,
208 const bool createIfNeeded);
209 virtual uint32_t getRemappedPackage(uint32_t origPackage) const;
210 virtual bool getAttributeType(uint32_t attrID, uint32_t* outType);
211 virtual bool getAttributeMin(uint32_t attrID, uint32_t* outMin);
212 virtual bool getAttributeMax(uint32_t attrID, uint32_t* outMax);
213 virtual bool getAttributeKeys(uint32_t attrID, Vector<String16>* outKeys);
214 virtual bool getAttributeEnum(uint32_t attrID,
215 const char16_t* name, size_t nameLen,
216 Res_value* outValue);
217 virtual bool getAttributeFlags(uint32_t attrID,
218 const char16_t* name, size_t nameLen,
219 Res_value* outValue);
220 virtual uint32_t getAttributeL10N(uint32_t attrID);
221
222 virtual bool getLocalizationSetting();
223 virtual void reportError(void* accessorCookie, const char* fmt, ...);
224
225 void setCurrentXmlPos(const SourcePos& pos) { mCurrentXmlPos = pos; }
226
227 class Item {
228 public:
229 Item() : isId(false), format(ResTable_map::TYPE_ANY), bagKeyId(0), evaluating(false)
230 { memset(&parsedValue, 0, sizeof(parsedValue)); }
231 Item(const SourcePos& pos,
232 bool _isId,
233 const String16& _value,
234 const Vector<StringPool::entry_style_span>* _style = NULL,
235 int32_t format = ResTable_map::TYPE_ANY);
236 Item(const Item& o) : sourcePos(o.sourcePos),
237 isId(o.isId), value(o.value), style(o.style),
238 format(o.format), bagKeyId(o.bagKeyId), evaluating(false) {
239 memset(&parsedValue, 0, sizeof(parsedValue));
240 }
241 ~Item() { }
242
243 Item& operator=(const Item& o) {
244 sourcePos = o.sourcePos;
245 isId = o.isId;
246 value = o.value;
247 style = o.style;
248 format = o.format;
249 bagKeyId = o.bagKeyId;
250 parsedValue = o.parsedValue;
251 return *this;
252 }
253
254 SourcePos sourcePos;
255 mutable bool isId;
256 String16 value;
257 Vector<StringPool::entry_style_span> style;
258 int32_t format;
259 uint32_t bagKeyId;
260 mutable bool evaluating;
261 Res_value parsedValue;
262 };
263
264 class Entry : public RefBase {
265 public:
266 Entry(const String16& name, const SourcePos& pos)
267 : mName(name), mType(TYPE_UNKNOWN),
268 mItemFormat(ResTable_map::TYPE_ANY), mNameIndex(-1), mPos(pos)
269 { }
270 virtual ~Entry() { }
271
272 enum type {
273 TYPE_UNKNOWN = 0,
274 TYPE_ITEM,
275 TYPE_BAG
276 };
277
278 String16 getName() const { return mName; }
279 type getType() const { return mType; }
280
281 void setParent(const String16& parent) { mParent = parent; }
282 String16 getParent() const { return mParent; }
283
284 status_t makeItABag(const SourcePos& sourcePos);
285
286 status_t emptyBag(const SourcePos& sourcePos);
287
288 status_t setItem(const SourcePos& pos,
289 const String16& value,
290 const Vector<StringPool::entry_style_span>* style = NULL,
291 int32_t format = ResTable_map::TYPE_ANY,
292 const bool overwrite = false);
293
294 status_t addToBag(const SourcePos& pos,
295 const String16& key, const String16& value,
296 const Vector<StringPool::entry_style_span>* style = NULL,
297 bool replace=false, bool isId = false,
298 int32_t format = ResTable_map::TYPE_ANY);
299
300 // Index of the entry's name string in the key pool.
301 int32_t getNameIndex() const { return mNameIndex; }
302 void setNameIndex(int32_t index) { mNameIndex = index; }
303
304 const Item* getItem() const { return mType == TYPE_ITEM ? &mItem : NULL; }
305 const KeyedVector<String16, Item>& getBag() const { return mBag; }
306
307 status_t generateAttributes(ResourceTable* table,
308 const String16& package);
309
310 status_t assignResourceIds(ResourceTable* table,
311 const String16& package);
312
313 status_t prepareFlatten(StringPool* strings, ResourceTable* table,
314 const String8* configTypeName, const ConfigDescription* config);
315
316 status_t remapStringValue(StringPool* strings);
317
318 ssize_t flatten(Bundle*, const sp<AaptFile>& data, bool isPublic);
319
320 const SourcePos& getPos() const { return mPos; }
321
322 private:
323 String16 mName;
324 String16 mParent;
325 type mType;
326 Item mItem;
327 int32_t mItemFormat;
328 KeyedVector<String16, Item> mBag;
329 int32_t mNameIndex;
330 uint32_t mParentId;
331 SourcePos mPos;
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 void canAddEntry(const String16& name);
410
411 String16 getName() const { return mName; }
412 sp<Entry> getEntry(const String16& entry,
413 const SourcePos& pos,
414 const ResTable_config* config = NULL,
415 bool doSetIndex = false,
416 bool overlay = false,
417 bool autoAddOverlay = false);
418
419 const SourcePos& getFirstPublicSourcePos() const { return *mFirstPublicSourcePos; }
420
421 int32_t getPublicIndex() const { return mPublicIndex; }
422
423 int32_t getIndex() const { return mIndex; }
424 void setIndex(int32_t index) { mIndex = index; }
425
426 status_t applyPublicEntryOrder();
427
428 const SortedVector<ConfigDescription>& getUniqueConfigs() const { return mUniqueConfigs; }
429
430 const DefaultKeyedVector<String16, sp<ConfigList> >& getConfigs() const { return mConfigs; }
431 const Vector<sp<ConfigList> >& getOrderedConfigs() const { return mOrderedConfigs; }
432
433 const SortedVector<String16>& getCanAddEntries() const { return mCanAddEntries; }
434
435 const SourcePos& getPos() const { return mPos; }
436 private:
437 String16 mName;
438 SourcePos* mFirstPublicSourcePos;
439 DefaultKeyedVector<String16, Public> mPublic;
440 SortedVector<ConfigDescription> mUniqueConfigs;
441 DefaultKeyedVector<String16, sp<ConfigList> > mConfigs;
442 Vector<sp<ConfigList> > mOrderedConfigs;
443 SortedVector<String16> mCanAddEntries;
444 int32_t mPublicIndex;
445 int32_t mIndex;
446 SourcePos mPos;
447 };
448
449 class Package : public RefBase {
450 public:
451 Package(const String16& name, ssize_t includedId=-1);
452 virtual ~Package() { }
453
454 String16 getName() const { return mName; }
455 sp<Type> getType(const String16& type,
456 const SourcePos& pos,
457 bool doSetIndex = false);
458
459 ssize_t getAssignedId() const { return mIncludedId; }
460
461 const ResStringPool& getTypeStrings() const { return mTypeStrings; }
462 uint32_t indexOfTypeString(const String16& s) const { return mTypeStringsMapping.valueFor(s); }
463 const sp<AaptFile> getTypeStringsData() const { return mTypeStringsData; }
464 status_t setTypeStrings(const sp<AaptFile>& data);
465
466 const ResStringPool& getKeyStrings() const { return mKeyStrings; }
467 uint32_t indexOfKeyString(const String16& s) const { return mKeyStringsMapping.valueFor(s); }
468 const sp<AaptFile> getKeyStringsData() const { return mKeyStringsData; }
469 status_t setKeyStrings(const sp<AaptFile>& data);
470
471 status_t applyPublicTypeOrder();
472
473 const DefaultKeyedVector<String16, sp<Type> >& getTypes() const { return mTypes; }
474 const Vector<sp<Type> >& getOrderedTypes() const { return mOrderedTypes; }
475
476 private:
477 status_t setStrings(const sp<AaptFile>& data,
478 ResStringPool* strings,
479 DefaultKeyedVector<String16, uint32_t>* mappings);
480
481 const String16 mName;
482 const ssize_t mIncludedId;
483 DefaultKeyedVector<String16, sp<Type> > mTypes;
484 Vector<sp<Type> > mOrderedTypes;
485 sp<AaptFile> mTypeStringsData;
486 sp<AaptFile> mKeyStringsData;
487 ResStringPool mTypeStrings;
488 ResStringPool mKeyStrings;
489 DefaultKeyedVector<String16, uint32_t> mTypeStringsMapping;
490 DefaultKeyedVector<String16, uint32_t> mKeyStringsMapping;
491 };
492
493private:
494 void writePublicDefinitions(const String16& package, FILE* fp, bool pub);
495 sp<Package> getPackage(const String16& package);
496 sp<Type> getType(const String16& package,
497 const String16& type,
498 const SourcePos& pos,
499 bool doSetIndex = false);
500 sp<Entry> getEntry(const String16& package,
501 const String16& type,
502 const String16& name,
503 const SourcePos& pos,
504 bool overlay,
505 const ResTable_config* config = NULL,
506 bool doSetIndex = false);
507 sp<const Entry> getEntry(uint32_t resID,
508 const ResTable_config* config = NULL) const;
509 const Item* getItem(uint32_t resID, uint32_t attrID) const;
510 bool getItemValue(uint32_t resID, uint32_t attrID,
511 Res_value* outValue);
512
513
514 String16 mAssetsPackage;
515 sp<AaptAssets> mAssets;
516 DefaultKeyedVector<String16, sp<Package> > mPackages;
517 Vector<sp<Package> > mOrderedPackages;
518 uint32_t mNextPackageId;
519 bool mHaveAppPackage;
520 bool mIsAppPackage;
Adam Lesinskide898ff2014-01-29 18:20:45 -0800521 bool mIsSharedLibrary;
Adam Lesinski282e1812014-01-23 18:17:42 -0800522 size_t mNumLocal;
523 SourcePos mCurrentXmlPos;
524 Bundle* mBundle;
525
526 // key = string resource name, value = set of locales in which that name is defined
Adam Lesinskia01a9372014-03-20 18:04:57 -0700527 map<String16, map<String8, SourcePos> > mLocalizations;
Adam Lesinski282e1812014-01-23 18:17:42 -0800528};
529
530#endif