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_H
     18 #define AAPT_RESOURCE_H
     19 
     20 #include "ConfigDescription.h"
     21 #include "Source.h"
     22 
     23 #include "util/StringPiece.h"
     24 
     25 #include <iomanip>
     26 #include <limits>
     27 #include <string>
     28 #include <tuple>
     29 #include <vector>
     30 
     31 namespace aapt {
     32 
     33 /**
     34  * The various types of resource types available. Corresponds
     35  * to the 'type' in package:type/entry.
     36  */
     37 enum class ResourceType {
     38     kAnim,
     39     kAnimator,
     40     kArray,
     41     kAttr,
     42     kAttrPrivate,
     43     kBool,
     44     kColor,
     45     kDimen,
     46     kDrawable,
     47     kFraction,
     48     kId,
     49     kInteger,
     50     kInterpolator,
     51     kLayout,
     52     kMenu,
     53     kMipmap,
     54     kPlurals,
     55     kRaw,
     56     kString,
     57     kStyle,
     58     kStyleable,
     59     kTransition,
     60     kXml,
     61 };
     62 
     63 StringPiece16 toString(ResourceType type);
     64 
     65 /**
     66  * Returns a pointer to a valid ResourceType, or nullptr if
     67  * the string was invalid.
     68  */
     69 const ResourceType* parseResourceType(const StringPiece16& str);
     70 
     71 /**
     72  * A resource's name. This can uniquely identify
     73  * a resource in the ResourceTable.
     74  */
     75 struct ResourceName {
     76     std::u16string package;
     77     ResourceType type;
     78     std::u16string entry;
     79 
     80     ResourceName() : type(ResourceType::kRaw) {}
     81     ResourceName(const StringPiece16& p, ResourceType t, const StringPiece16& e);
     82 
     83     bool isValid() const;
     84     std::u16string toString() const;
     85 };
     86 
     87 /**
     88  * Same as ResourceName, but uses StringPieces instead.
     89  * Use this if you need to avoid copying and know that
     90  * the lifetime of this object is shorter than that
     91  * of the original string.
     92  */
     93 struct ResourceNameRef {
     94     StringPiece16 package;
     95     ResourceType type;
     96     StringPiece16 entry;
     97 
     98     ResourceNameRef() = default;
     99     ResourceNameRef(const ResourceNameRef&) = default;
    100     ResourceNameRef(ResourceNameRef&&) = default;
    101     ResourceNameRef(const ResourceName& rhs);
    102     ResourceNameRef(const StringPiece16& p, ResourceType t, const StringPiece16& e);
    103     ResourceNameRef& operator=(const ResourceNameRef& rhs) = default;
    104     ResourceNameRef& operator=(ResourceNameRef&& rhs) = default;
    105     ResourceNameRef& operator=(const ResourceName& rhs);
    106 
    107     ResourceName toResourceName() const;
    108     bool isValid() const;
    109 };
    110 
    111 /**
    112  * A binary identifier representing a resource. Internally it
    113  * is a 32bit integer split as follows:
    114  *
    115  * 0xPPTTEEEE
    116  *
    117  * PP: 8 bit package identifier. 0x01 is reserved for system
    118  *     and 0x7f is reserved for the running app.
    119  * TT: 8 bit type identifier. 0x00 is invalid.
    120  * EEEE: 16 bit entry identifier.
    121  */
    122 struct ResourceId {
    123     uint32_t id;
    124 
    125     ResourceId();
    126     ResourceId(const ResourceId& rhs);
    127     ResourceId(uint32_t resId);
    128     ResourceId(uint8_t p, uint8_t t, uint16_t e);
    129 
    130     bool isValid() const;
    131     uint8_t packageId() const;
    132     uint8_t typeId() const;
    133     uint16_t entryId() const;
    134 };
    135 
    136 struct SourcedResourceName {
    137     ResourceName name;
    138     size_t line;
    139 };
    140 
    141 struct ResourceFile {
    142     // Name
    143     ResourceName name;
    144 
    145     // Configuration
    146     ConfigDescription config;
    147 
    148     // Source
    149     Source source;
    150 
    151     // Exported symbols
    152     std::vector<SourcedResourceName> exportedSymbols;
    153 };
    154 
    155 /**
    156  * Useful struct used as a key to represent a unique resource in associative containers.
    157  */
    158 struct ResourceKey {
    159     ResourceName name;
    160     ConfigDescription config;
    161 };
    162 
    163 bool operator<(const ResourceKey& a, const ResourceKey& b);
    164 
    165 /**
    166  * Useful struct used as a key to represent a unique resource in associative containers.
    167  * Holds a reference to the name, so that name better live longer than this key!
    168  */
    169 struct ResourceKeyRef {
    170     ResourceNameRef name;
    171     ConfigDescription config;
    172 
    173     ResourceKeyRef() = default;
    174     ResourceKeyRef(const ResourceNameRef& n, const ConfigDescription& c) : name(n), config(c) {
    175     }
    176 
    177     /**
    178      * Prevent taking a reference to a temporary. This is bad.
    179      */
    180     ResourceKeyRef(ResourceName&& n, const ConfigDescription& c) = delete;
    181 };
    182 
    183 bool operator<(const ResourceKeyRef& a, const ResourceKeyRef& b);
    184 
    185 //
    186 // ResourceId implementation.
    187 //
    188 
    189 inline ResourceId::ResourceId() : id(0) {
    190 }
    191 
    192 inline ResourceId::ResourceId(const ResourceId& rhs) : id(rhs.id) {
    193 }
    194 
    195 inline ResourceId::ResourceId(uint32_t resId) : id(resId) {
    196 }
    197 
    198 inline ResourceId::ResourceId(uint8_t p, uint8_t t, uint16_t e) : id((p << 24) | (t << 16) | e) {
    199 }
    200 
    201 inline bool ResourceId::isValid() const {
    202     return (id & 0xff000000u) != 0 && (id & 0x00ff0000u) != 0;
    203 }
    204 
    205 inline uint8_t ResourceId::packageId() const {
    206     return static_cast<uint8_t>(id >> 24);
    207 }
    208 
    209 inline uint8_t ResourceId::typeId() const {
    210     return static_cast<uint8_t>(id >> 16);
    211 }
    212 
    213 inline uint16_t ResourceId::entryId() const {
    214     return static_cast<uint16_t>(id);
    215 }
    216 
    217 inline bool operator<(const ResourceId& lhs, const ResourceId& rhs) {
    218     return lhs.id < rhs.id;
    219 }
    220 
    221 inline bool operator>(const ResourceId& lhs, const ResourceId& rhs) {
    222     return lhs.id > rhs.id;
    223 }
    224 
    225 inline bool operator==(const ResourceId& lhs, const ResourceId& rhs) {
    226     return lhs.id == rhs.id;
    227 }
    228 
    229 inline bool operator!=(const ResourceId& lhs, const ResourceId& rhs) {
    230     return lhs.id != rhs.id;
    231 }
    232 
    233 inline ::std::ostream& operator<<(::std::ostream& out, const ResourceId& resId) {
    234     std::ios_base::fmtflags oldFlags = out.flags();
    235     char oldFill = out.fill();
    236     out << "0x" << std::internal << std::setfill('0') << std::setw(8)
    237         << std::hex << resId.id;
    238     out.flags(oldFlags);
    239     out.fill(oldFill);
    240     return out;
    241 }
    242 
    243 //
    244 // ResourceType implementation.
    245 //
    246 
    247 inline ::std::ostream& operator<<(::std::ostream& out, const ResourceType& val) {
    248     return out << toString(val);
    249 }
    250 
    251 //
    252 // ResourceName implementation.
    253 //
    254 
    255 inline ResourceName::ResourceName(const StringPiece16& p, ResourceType t, const StringPiece16& e) :
    256         package(p.toString()), type(t), entry(e.toString()) {
    257 }
    258 
    259 inline bool ResourceName::isValid() const {
    260     return !package.empty() && !entry.empty();
    261 }
    262 
    263 inline bool operator<(const ResourceName& lhs, const ResourceName& rhs) {
    264     return std::tie(lhs.package, lhs.type, lhs.entry)
    265             < std::tie(rhs.package, rhs.type, rhs.entry);
    266 }
    267 
    268 inline bool operator==(const ResourceName& lhs, const ResourceName& rhs) {
    269     return std::tie(lhs.package, lhs.type, lhs.entry)
    270             == std::tie(rhs.package, rhs.type, rhs.entry);
    271 }
    272 
    273 inline bool operator!=(const ResourceName& lhs, const ResourceName& rhs) {
    274     return std::tie(lhs.package, lhs.type, lhs.entry)
    275             != std::tie(rhs.package, rhs.type, rhs.entry);
    276 }
    277 
    278 inline std::u16string ResourceName::toString() const {
    279     std::u16string result;
    280     if (!package.empty()) {
    281         result = package + u":";
    282     }
    283     return result + aapt::toString(type).toString() + u"/" + entry;
    284 }
    285 
    286 inline ::std::ostream& operator<<(::std::ostream& out, const ResourceName& name) {
    287     if (!name.package.empty()) {
    288         out << name.package << ":";
    289     }
    290     return out << name.type << "/" << name.entry;
    291 }
    292 
    293 
    294 //
    295 // ResourceNameRef implementation.
    296 //
    297 
    298 inline ResourceNameRef::ResourceNameRef(const ResourceName& rhs) :
    299         package(rhs.package), type(rhs.type), entry(rhs.entry) {
    300 }
    301 
    302 inline ResourceNameRef::ResourceNameRef(const StringPiece16& p, ResourceType t,
    303                                         const StringPiece16& e) :
    304         package(p), type(t), entry(e) {
    305 }
    306 
    307 inline ResourceNameRef& ResourceNameRef::operator=(const ResourceName& rhs) {
    308     package = rhs.package;
    309     type = rhs.type;
    310     entry = rhs.entry;
    311     return *this;
    312 }
    313 
    314 inline ResourceName ResourceNameRef::toResourceName() const {
    315     return { package.toString(), type, entry.toString() };
    316 }
    317 
    318 inline bool ResourceNameRef::isValid() const {
    319     return !package.empty() && !entry.empty();
    320 }
    321 
    322 inline bool operator<(const ResourceNameRef& lhs, const ResourceNameRef& rhs) {
    323     return std::tie(lhs.package, lhs.type, lhs.entry)
    324             < std::tie(rhs.package, rhs.type, rhs.entry);
    325 }
    326 
    327 inline bool operator==(const ResourceNameRef& lhs, const ResourceNameRef& rhs) {
    328     return std::tie(lhs.package, lhs.type, lhs.entry)
    329             == std::tie(rhs.package, rhs.type, rhs.entry);
    330 }
    331 
    332 inline bool operator!=(const ResourceNameRef& lhs, const ResourceNameRef& rhs) {
    333     return std::tie(lhs.package, lhs.type, lhs.entry)
    334             != std::tie(rhs.package, rhs.type, rhs.entry);
    335 }
    336 
    337 inline ::std::ostream& operator<<(::std::ostream& out, const ResourceNameRef& name) {
    338     if (!name.package.empty()) {
    339         out << name.package << ":";
    340     }
    341     return out << name.type << "/" << name.entry;
    342 }
    343 
    344 inline bool operator<(const ResourceName& lhs, const ResourceNameRef& b) {
    345     return ResourceNameRef(lhs) < b;
    346 }
    347 
    348 inline bool operator!=(const ResourceName& lhs, const ResourceNameRef& rhs) {
    349     return ResourceNameRef(lhs) != rhs;
    350 }
    351 
    352 inline bool operator==(const SourcedResourceName& lhs, const SourcedResourceName& rhs) {
    353     return lhs.name == rhs.name && lhs.line == rhs.line;
    354 }
    355 
    356 } // namespace aapt
    357 
    358 #endif // AAPT_RESOURCE_H
    359