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