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