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     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);
    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 
    521 private:
    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, set<String8> > mLocalizations;
    555 };
    556 
    557 #endif
    558