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