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