Home | History | Annotate | Download | only in aapt2
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef AAPT_RESOURCE_TABLE_H
     18 #define AAPT_RESOURCE_TABLE_H
     19 
     20 #include "ConfigDescription.h"
     21 #include "Resource.h"
     22 #include "ResourceValues.h"
     23 #include "Source.h"
     24 #include "StringPool.h"
     25 
     26 #include <memory>
     27 #include <string>
     28 #include <tuple>
     29 #include <vector>
     30 
     31 namespace aapt {
     32 
     33 /**
     34  * The Public status of a resource.
     35  */
     36 struct Public {
     37     bool isPublic = false;
     38     SourceLine source;
     39     std::u16string comment;
     40 };
     41 
     42 /**
     43  * The resource value for a specific configuration.
     44  */
     45 struct ResourceConfigValue {
     46     ConfigDescription config;
     47     SourceLine source;
     48     std::u16string comment;
     49     std::unique_ptr<Value> value;
     50 };
     51 
     52 /**
     53  * Represents a resource entry, which may have
     54  * varying values for each defined configuration.
     55  */
     56 struct ResourceEntry {
     57     enum {
     58         kUnsetEntryId = 0xffffffffu
     59     };
     60 
     61     /**
     62      * The name of the resource. Immutable, as
     63      * this determines the order of this resource
     64      * when doing lookups.
     65      */
     66     const std::u16string name;
     67 
     68     /**
     69      * The entry ID for this resource.
     70      */
     71     size_t entryId;
     72 
     73     /**
     74      * Whether this resource is public (and must maintain the same
     75      * entry ID across builds).
     76      */
     77     Public publicStatus;
     78 
     79     /**
     80      * The resource's values for each configuration.
     81      */
     82     std::vector<ResourceConfigValue> values;
     83 
     84     inline ResourceEntry(const StringPiece16& _name);
     85     inline ResourceEntry(const ResourceEntry* rhs);
     86 };
     87 
     88 /**
     89  * Represents a resource type, which holds entries defined
     90  * for this type.
     91  */
     92 struct ResourceTableType {
     93     enum {
     94         kUnsetTypeId = 0xffffffffu
     95     };
     96 
     97     /**
     98      * The logical type of resource (string, drawable, layout, etc.).
     99      */
    100     const ResourceType type;
    101 
    102     /**
    103      * The type ID for this resource.
    104      */
    105     size_t typeId;
    106 
    107     /**
    108      * Whether this type is public (and must maintain the same
    109      * type ID across builds).
    110      */
    111     Public publicStatus;
    112 
    113     /**
    114      * List of resources for this type.
    115      */
    116     std::vector<std::unique_ptr<ResourceEntry>> entries;
    117 
    118     ResourceTableType(const ResourceType _type);
    119     ResourceTableType(const ResourceTableType* rhs);
    120 };
    121 
    122 /**
    123  * The container and index for all resources defined for an app. This gets
    124  * flattened into a binary resource table (resources.arsc).
    125  */
    126 class ResourceTable {
    127 public:
    128     using iterator = std::vector<std::unique_ptr<ResourceTableType>>::iterator;
    129     using const_iterator = std::vector<std::unique_ptr<ResourceTableType>>::const_iterator;
    130 
    131     enum {
    132         kUnsetPackageId = 0xffffffff
    133     };
    134 
    135     ResourceTable();
    136 
    137     size_t getPackageId() const;
    138     void setPackageId(size_t packageId);
    139 
    140     const std::u16string& getPackage() const;
    141     void setPackage(const StringPiece16& package);
    142 
    143     bool addResource(const ResourceNameRef& name, const ConfigDescription& config,
    144                      const SourceLine& source, std::unique_ptr<Value> value);
    145 
    146     /**
    147      * Same as addResource, but doesn't verify the validity of the name. This is used
    148      * when loading resources from an existing binary resource table that may have mangled
    149      * names.
    150      */
    151     bool addResourceAllowMangled(const ResourceNameRef& name, const ConfigDescription& config,
    152                                  const SourceLine& source, std::unique_ptr<Value> value);
    153 
    154     bool addResource(const ResourceNameRef& name, const ResourceId resId,
    155                      const ConfigDescription& config, const SourceLine& source,
    156                      std::unique_ptr<Value> value);
    157 
    158     bool markPublic(const ResourceNameRef& name, const ResourceId resId, const SourceLine& source);
    159     bool markPublicAllowMangled(const ResourceNameRef& name, const ResourceId resId,
    160                                 const SourceLine& source);
    161 
    162     /*
    163      * Merges the resources from `other` into this table, mangling the names of the resources
    164      * if `other` has a different package name.
    165      */
    166     bool merge(ResourceTable&& other);
    167 
    168     /**
    169      * Returns the string pool used by this ResourceTable.
    170      * Values that reference strings should use this pool to create
    171      * their strings.
    172      */
    173     StringPool& getValueStringPool();
    174     const StringPool& getValueStringPool() const;
    175 
    176     std::tuple<const ResourceTableType*, const ResourceEntry*>
    177     findResource(const ResourceNameRef& name) const;
    178 
    179     iterator begin();
    180     iterator end();
    181     const_iterator begin() const;
    182     const_iterator end() const;
    183 
    184 private:
    185     std::unique_ptr<ResourceTableType>& findOrCreateType(ResourceType type);
    186     std::unique_ptr<ResourceEntry>& findOrCreateEntry(std::unique_ptr<ResourceTableType>& type,
    187                                                       const StringPiece16& name);
    188 
    189     bool addResourceImpl(const ResourceNameRef& name, const ResourceId resId,
    190                          const ConfigDescription& config, const SourceLine& source,
    191                          std::unique_ptr<Value> value, const char16_t* validChars);
    192     bool markPublicImpl(const ResourceNameRef& name, const ResourceId resId,
    193                         const SourceLine& source, const char16_t* validChars);
    194 
    195     std::u16string mPackage;
    196     size_t mPackageId;
    197 
    198     // StringPool must come before mTypes so that it is destroyed after.
    199     // When StringPool references are destroyed (as they will be when mTypes
    200     // is destroyed), they decrement a refCount, which would cause invalid
    201     // memory access if the pool was already destroyed.
    202     StringPool mValuePool;
    203 
    204     std::vector<std::unique_ptr<ResourceTableType>> mTypes;
    205 };
    206 
    207 //
    208 // ResourceEntry implementation.
    209 //
    210 
    211 inline ResourceEntry::ResourceEntry(const StringPiece16& _name) :
    212         name(_name.toString()), entryId(kUnsetEntryId) {
    213 }
    214 
    215 inline ResourceEntry::ResourceEntry(const ResourceEntry* rhs) :
    216         name(rhs->name), entryId(rhs->entryId), publicStatus(rhs->publicStatus) {
    217 }
    218 
    219 //
    220 // ResourceTableType implementation.
    221 //
    222 
    223 inline ResourceTableType::ResourceTableType(const ResourceType _type) :
    224         type(_type), typeId(kUnsetTypeId) {
    225 }
    226 
    227 inline ResourceTableType::ResourceTableType(const ResourceTableType* rhs) :
    228         type(rhs->type), typeId(rhs->typeId), publicStatus(rhs->publicStatus) {
    229 }
    230 
    231 //
    232 // ResourceTable implementation.
    233 //
    234 
    235 inline StringPool& ResourceTable::getValueStringPool() {
    236     return mValuePool;
    237 }
    238 
    239 inline const StringPool& ResourceTable::getValueStringPool() const {
    240     return mValuePool;
    241 }
    242 
    243 inline ResourceTable::iterator ResourceTable::begin() {
    244     return mTypes.begin();
    245 }
    246 
    247 inline ResourceTable::iterator ResourceTable::end() {
    248     return mTypes.end();
    249 }
    250 
    251 inline ResourceTable::const_iterator ResourceTable::begin() const {
    252     return mTypes.begin();
    253 }
    254 
    255 inline ResourceTable::const_iterator ResourceTable::end() const {
    256     return mTypes.end();
    257 }
    258 
    259 inline const std::u16string& ResourceTable::getPackage() const {
    260     return mPackage;
    261 }
    262 
    263 inline size_t ResourceTable::getPackageId() const {
    264     return mPackageId;
    265 }
    266 
    267 inline void ResourceTable::setPackage(const StringPiece16& package) {
    268     mPackage = package.toString();
    269 }
    270 
    271 inline void ResourceTable::setPackageId(size_t packageId) {
    272     mPackageId = packageId;
    273 }
    274 
    275 } // namespace aapt
    276 
    277 #endif // AAPT_RESOURCE_TABLE_H
    278