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