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