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