ResourceTable.h revision e6b680364dd992907a8d2037685a2e500d188dfb
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<AaptFile>& target,
41                        const sp<AaptFile>& outTarget,
42                        ResourceTable* table,
43                        int options = XML_COMPILE_STANDARD_RESOURCE);
44
45status_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
51status_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
58struct AccessorCookie
59{
60    SourcePos sourcePos;
61    String8 attr;
62    String8 value;
63
64    AccessorCookie(const SourcePos&p, const String8& a, const String8& v)
65        :sourcePos(p),
66         attr(a),
67         value(v)
68    {
69    }
70};
71
72class ResourceTable : public ResTable::Accessor
73{
74public:
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
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
220    void setCurrentXmlPos(const SourcePos& pos) { mCurrentXmlPos = pos; }
221
222    class Item {
223    public:
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);
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        }
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:
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        { }
265        virtual ~Entry() { }
266
267        enum type {
268            TYPE_UNKNOWN = 0,
269            TYPE_ITEM,
270            TYPE_BAG
271        };
272
273        String16 getName() const { return mName; }
274        type getType() const { return mType; }
275
276        void setParent(const String16& parent) { mParent = parent; }
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.
296        int32_t getNameIndex() const { return mNameIndex; }
297        void setNameIndex(int32_t index) { mNameIndex = index; }
298
299        const Item* getItem() const { return mType == TYPE_ITEM ? &mItem : NULL; }
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
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 {
327        ConfigDescription() {
328            memset(this, 0, sizeof(*this));
329            size = sizeof(ResTable_config);
330        }
331        ConfigDescription(const ResTable_config&o) {
332            *static_cast<ResTable_config*>(this) = o;
333            size = sizeof(ResTable_config);
334        }
335        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:
359        ConfigList(const String16& name, const SourcePos& pos)
360            : mName(name), mPos(pos), mPublic(false), mEntryIndex(-1) { }
361        virtual ~ConfigList() { }
362
363        String16 getName() const { return mName; }
364        const SourcePos& getPos() const { return mPos; }
365
366        void appendComment(const String16& comment, bool onlyIfEmpty = false);
367        const String16& getComment() const { return mComment; }
368
369        void appendTypeComment(const String16& comment);
370        const String16& getTypeComment() const { return mTypeComment; }
371
372        // Index of this entry in its Type.
373        int32_t getEntryIndex() const { return mEntryIndex; }
374        void setEntryIndex(int32_t index) { mEntryIndex = index; }
375
376        void setPublic(bool pub) { mPublic = pub; }
377        bool getPublic() const { return mPublic; }
378        void setPublicSourcePos(const SourcePos& pos) { mPublicSourcePos = pos; }
379        const SourcePos& getPublicSourcePos() { return mPublicSourcePos; }
380
381        void addEntry(const ResTable_config& config, const sp<Entry>& entry) {
382            mEntries.add(config, entry);
383        }
384
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:
399        Public() : sourcePos(), ident(0) { }
400        Public(const SourcePos& pos,
401               const String16& _comment,
402               uint32_t _ident)
403            : sourcePos(pos),
404            comment(_comment), ident(_ident) { }
405        Public(const Public& o) : sourcePos(o.sourcePos),
406            comment(o.comment), ident(o.ident) { }
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:
423        Type(const String16& name, const SourcePos& pos)
424                : mName(name), mFirstPublicSourcePos(NULL), mPublicIndex(-1), mIndex(-1), mPos(pos)
425        { }
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
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
442        const SourcePos& getFirstPublicSourcePos() const { return *mFirstPublicSourcePos; }
443
444        int32_t getPublicIndex() const { return mPublicIndex; }
445
446        int32_t getIndex() const { return mIndex; }
447        void setIndex(int32_t index) { mIndex = index; }
448
449        status_t applyPublicEntryOrder();
450
451        const SortedVector<ConfigDescription>& getUniqueConfigs() const { return mUniqueConfigs; }
452
453        const DefaultKeyedVector<String16, sp<ConfigList> >& getConfigs() const { return mConfigs; }
454        const Vector<sp<ConfigList> >& getOrderedConfigs() const { return mOrderedConfigs; }
455
456        const SortedVector<String16>& getCanAddEntries() const { return mCanAddEntries; }
457
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);
475        virtual ~Package() { }
476
477        String16 getName() const { return mName; }
478        sp<Type> getType(const String16& type,
479                         const SourcePos& pos,
480                         bool doSetIndex = false);
481
482        ssize_t getAssignedId() const { return mIncludedId; }
483
484        const ResStringPool& getTypeStrings() const { return mTypeStrings; }
485        uint32_t indexOfTypeString(const String16& s) const { return mTypeStringsMapping.valueFor(s); }
486        const sp<AaptFile> getTypeStringsData() const { return mTypeStringsData; }
487        status_t setTypeStrings(const sp<AaptFile>& data);
488
489        const ResStringPool& getKeyStrings() const { return mKeyStrings; }
490        uint32_t indexOfKeyString(const String16& s) const { return mKeyStringsMapping.valueFor(s); }
491        const sp<AaptFile> getKeyStringsData() const { return mKeyStringsData; }
492        status_t setKeyStrings(const sp<AaptFile>& data);
493
494        status_t applyPublicTypeOrder();
495
496        const DefaultKeyedVector<String16, sp<Type> >& getTypes() const { return mTypes; }
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
516private:
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