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