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