• 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     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 
AccessorCookieAccessorCookie64     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 
makeResId(uint32_t packageId,uint32_t typeId,uint32_t nameId)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 
setCurrentXmlPos(const SourcePos & pos)215     void setCurrentXmlPos(const SourcePos& pos) { mCurrentXmlPos = pos; }
216 
217     class Item {
218     public:
Item()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);
Item(const Item & o)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         }
~Item()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:
Entry(const String16 & name,const SourcePos & pos)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         { }
~Entry()260         virtual ~Entry() { }
261 
262         enum type {
263             TYPE_UNKNOWN = 0,
264             TYPE_ITEM,
265             TYPE_BAG
266         };
267 
getName()268         String16 getName() const { return mName; }
getType()269         type getType() const { return mType; }
270 
setParent(const String16 & parent)271         void setParent(const String16& parent) { mParent = parent; }
getParent()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.
getNameIndex()291         int32_t getNameIndex() const { return mNameIndex; }
setNameIndex(int32_t index)292         void setNameIndex(int32_t index) { mNameIndex = index; }
293 
getItem()294         const Item* getItem() const { return mType == TYPE_ITEM ? &mItem : NULL; }
getBag()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 
getPos()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 {
ConfigDescriptionConfigDescription322         ConfigDescription() {
323             memset(this, 0, sizeof(*this));
324             size = sizeof(ResTable_config);
325         }
ConfigDescriptionConfigDescription326         ConfigDescription(const ResTable_config&o) {
327             *static_cast<ResTable_config*>(this) = o;
328             size = sizeof(ResTable_config);
329         }
ConfigDescriptionConfigDescription330         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:
ConfigList(const String16 & name,const SourcePos & pos)354         ConfigList(const String16& name, const SourcePos& pos)
355             : mName(name), mPos(pos), mPublic(false), mEntryIndex(-1) { }
~ConfigList()356         virtual ~ConfigList() { }
357 
getName()358         String16 getName() const { return mName; }
getPos()359         const SourcePos& getPos() const { return mPos; }
360 
361         void appendComment(const String16& comment, bool onlyIfEmpty = false);
getComment()362         const String16& getComment() const { return mComment; }
363 
364         void appendTypeComment(const String16& comment);
getTypeComment()365         const String16& getTypeComment() const { return mTypeComment; }
366 
367         // Index of this entry in its Type.
getEntryIndex()368         int32_t getEntryIndex() const { return mEntryIndex; }
setEntryIndex(int32_t index)369         void setEntryIndex(int32_t index) { mEntryIndex = index; }
370 
setPublic(bool pub)371         void setPublic(bool pub) { mPublic = pub; }
getPublic()372         bool getPublic() const { return mPublic; }
setPublicSourcePos(const SourcePos & pos)373         void setPublicSourcePos(const SourcePos& pos) { mPublicSourcePos = pos; }
getPublicSourcePos()374         const SourcePos& getPublicSourcePos() { return mPublicSourcePos; }
375 
addEntry(const ResTable_config & config,const sp<Entry> & entry)376         void addEntry(const ResTable_config& config, const sp<Entry>& entry) {
377             mEntries.add(config, entry);
378         }
379 
getEntries()380         const DefaultKeyedVector<ConfigDescription, sp<Entry> >& getEntries() const { return mEntries; }
381     private:
382         const String16 mName;
383         const SourcePos mPos;
384         String16 mComment;
385         String16 mTypeComment;
386         bool mPublic;
387         SourcePos mPublicSourcePos;
388         int32_t mEntryIndex;
389         DefaultKeyedVector<ConfigDescription, sp<Entry> > mEntries;
390     };
391 
392     class Public {
393     public:
Public()394         Public() : sourcePos(), ident(0) { }
Public(const SourcePos & pos,const String16 & _comment,uint32_t _ident)395         Public(const SourcePos& pos,
396                const String16& _comment,
397                uint32_t _ident)
398             : sourcePos(pos),
399             comment(_comment), ident(_ident) { }
Public(const Public & o)400         Public(const Public& o) : sourcePos(o.sourcePos),
401             comment(o.comment), ident(o.ident) { }
~Public()402         ~Public() { }
403 
404         Public& operator=(const Public& o) {
405             sourcePos = o.sourcePos;
406             comment = o.comment;
407             ident = o.ident;
408             return *this;
409         }
410 
411         SourcePos   sourcePos;
412         String16    comment;
413         uint32_t    ident;
414     };
415 
416     class Type : public RefBase {
417     public:
Type(const String16 & name,const SourcePos & pos)418         Type(const String16& name, const SourcePos& pos)
419                 : mName(name), mFirstPublicSourcePos(NULL), mPublicIndex(-1), mIndex(-1), mPos(pos)
420         { }
~Type()421         virtual ~Type() { delete mFirstPublicSourcePos; }
422 
423         status_t addPublic(const SourcePos& pos,
424                            const String16& name,
425                            const uint32_t ident);
426 
427         void canAddEntry(const String16& name);
428 
getName()429         String16 getName() const { return mName; }
430         sp<Entry> getEntry(const String16& entry,
431                            const SourcePos& pos,
432                            const ResTable_config* config = NULL,
433                            bool doSetIndex = false,
434                            bool overlay = false,
435                            bool autoAddOverlay = false);
436 
getFirstPublicSourcePos()437         const SourcePos& getFirstPublicSourcePos() const { return *mFirstPublicSourcePos; }
438 
getPublicIndex()439         int32_t getPublicIndex() const { return mPublicIndex; }
440 
getIndex()441         int32_t getIndex() const { return mIndex; }
setIndex(int32_t index)442         void setIndex(int32_t index) { mIndex = index; }
443 
444         status_t applyPublicEntryOrder();
445 
getUniqueConfigs()446         const SortedVector<ConfigDescription>& getUniqueConfigs() const { return mUniqueConfigs; }
447 
getConfigs()448         const DefaultKeyedVector<String16, sp<ConfigList> >& getConfigs() const { return mConfigs; }
getOrderedConfigs()449         const Vector<sp<ConfigList> >& getOrderedConfigs() const { return mOrderedConfigs; }
450 
getCanAddEntries()451         const SortedVector<String16>& getCanAddEntries() const { return mCanAddEntries; }
452 
getPos()453         const SourcePos& getPos() const { return mPos; }
454     private:
455         String16 mName;
456         SourcePos* mFirstPublicSourcePos;
457         DefaultKeyedVector<String16, Public> mPublic;
458         SortedVector<ConfigDescription> mUniqueConfigs;
459         DefaultKeyedVector<String16, sp<ConfigList> > mConfigs;
460         Vector<sp<ConfigList> > mOrderedConfigs;
461         SortedVector<String16> mCanAddEntries;
462         int32_t mPublicIndex;
463         int32_t mIndex;
464         SourcePos mPos;
465     };
466 
467     class Package : public RefBase {
468     public:
469         Package(const String16& name, ssize_t includedId=-1);
~Package()470         virtual ~Package() { }
471 
getName()472         String16 getName() const { return mName; }
473         sp<Type> getType(const String16& type,
474                          const SourcePos& pos,
475                          bool doSetIndex = false);
476 
getAssignedId()477         ssize_t getAssignedId() const { return mIncludedId; }
478 
getTypeStrings()479         const ResStringPool& getTypeStrings() const { return mTypeStrings; }
indexOfTypeString(const String16 & s)480         uint32_t indexOfTypeString(const String16& s) const { return mTypeStringsMapping.valueFor(s); }
getTypeStringsData()481         const sp<AaptFile> getTypeStringsData() const { return mTypeStringsData; }
482         status_t setTypeStrings(const sp<AaptFile>& data);
483 
getKeyStrings()484         const ResStringPool& getKeyStrings() const { return mKeyStrings; }
indexOfKeyString(const String16 & s)485         uint32_t indexOfKeyString(const String16& s) const { return mKeyStringsMapping.valueFor(s); }
getKeyStringsData()486         const sp<AaptFile> getKeyStringsData() const { return mKeyStringsData; }
487         status_t setKeyStrings(const sp<AaptFile>& data);
488 
489         status_t applyPublicTypeOrder();
490 
getTypes()491         const DefaultKeyedVector<String16, sp<Type> >& getTypes() const { return mTypes; }
getOrderedTypes()492         const Vector<sp<Type> >& getOrderedTypes() const { return mOrderedTypes; }
493 
494     private:
495         status_t setStrings(const sp<AaptFile>& data,
496                             ResStringPool* strings,
497                             DefaultKeyedVector<String16, uint32_t>* mappings);
498 
499         const String16 mName;
500         const ssize_t mIncludedId;
501         DefaultKeyedVector<String16, sp<Type> > mTypes;
502         Vector<sp<Type> > mOrderedTypes;
503         sp<AaptFile> mTypeStringsData;
504         sp<AaptFile> mKeyStringsData;
505         ResStringPool mTypeStrings;
506         ResStringPool mKeyStrings;
507         DefaultKeyedVector<String16, uint32_t> mTypeStringsMapping;
508         DefaultKeyedVector<String16, uint32_t> mKeyStringsMapping;
509     };
510 
511 private:
512     void writePublicDefinitions(const String16& package, FILE* fp, bool pub);
513     sp<Package> getPackage(const String16& package);
514     sp<Type> getType(const String16& package,
515                      const String16& type,
516                      const SourcePos& pos,
517                      bool doSetIndex = false);
518     sp<Entry> getEntry(const String16& package,
519                        const String16& type,
520                        const String16& name,
521                        const SourcePos& pos,
522                        bool overlay,
523                        const ResTable_config* config = NULL,
524                        bool doSetIndex = false);
525     sp<const Entry> getEntry(uint32_t resID,
526                              const ResTable_config* config = NULL) const;
527     const Item* getItem(uint32_t resID, uint32_t attrID) const;
528     bool getItemValue(uint32_t resID, uint32_t attrID,
529                       Res_value* outValue);
530 
531 
532     String16 mAssetsPackage;
533     sp<AaptAssets> mAssets;
534     DefaultKeyedVector<String16, sp<Package> > mPackages;
535     Vector<sp<Package> > mOrderedPackages;
536     uint32_t mNextPackageId;
537     bool mHaveAppPackage;
538     bool mIsAppPackage;
539     size_t mNumLocal;
540     SourcePos mCurrentXmlPos;
541     Bundle* mBundle;
542 
543     // key = string resource name, value = set of locales in which that name is defined
544     map<String16, set<String8> > mLocalizations;
545 };
546 
547 class ResourceFilter
548 {
549 public:
ResourceFilter()550     ResourceFilter() : mData(), mContainsPseudo(false) {}
551     status_t parse(const char* arg);
552     bool match(int axis, uint32_t value);
553     bool match(const ResTable_config& config);
containsPseudo()554     inline bool containsPseudo() { return mContainsPseudo; }
555 
556 private:
557     KeyedVector<int,SortedVector<uint32_t> > mData;
558     bool mContainsPseudo;
559 };
560 
561 
562 #endif
563