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 31namespace aapt { 32 33/** 34 * The Public status of a resource. 35 */ 36struct Public { 37 bool isPublic = false; 38 SourceLine source; 39 std::u16string comment; 40}; 41 42/** 43 * The resource value for a specific configuration. 44 */ 45struct 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 */ 56struct 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 */ 92struct 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 */ 126class ResourceTable { 127public: 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 184private: 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 211inline ResourceEntry::ResourceEntry(const StringPiece16& _name) : 212 name(_name.toString()), entryId(kUnsetEntryId) { 213} 214 215inline ResourceEntry::ResourceEntry(const ResourceEntry* rhs) : 216 name(rhs->name), entryId(rhs->entryId), publicStatus(rhs->publicStatus) { 217} 218 219// 220// ResourceTableType implementation. 221// 222 223inline ResourceTableType::ResourceTableType(const ResourceType _type) : 224 type(_type), typeId(kUnsetTypeId) { 225} 226 227inline ResourceTableType::ResourceTableType(const ResourceTableType* rhs) : 228 type(rhs->type), typeId(rhs->typeId), publicStatus(rhs->publicStatus) { 229} 230 231// 232// ResourceTable implementation. 233// 234 235inline StringPool& ResourceTable::getValueStringPool() { 236 return mValuePool; 237} 238 239inline const StringPool& ResourceTable::getValueStringPool() const { 240 return mValuePool; 241} 242 243inline ResourceTable::iterator ResourceTable::begin() { 244 return mTypes.begin(); 245} 246 247inline ResourceTable::iterator ResourceTable::end() { 248 return mTypes.end(); 249} 250 251inline ResourceTable::const_iterator ResourceTable::begin() const { 252 return mTypes.begin(); 253} 254 255inline ResourceTable::const_iterator ResourceTable::end() const { 256 return mTypes.end(); 257} 258 259inline const std::u16string& ResourceTable::getPackage() const { 260 return mPackage; 261} 262 263inline size_t ResourceTable::getPackageId() const { 264 return mPackageId; 265} 266 267inline void ResourceTable::setPackage(const StringPiece16& package) { 268 mPackage = package.toString(); 269} 270 271inline void ResourceTable::setPackageId(size_t packageId) { 272 mPackageId = packageId; 273} 274 275} // namespace aapt 276 277#endif // AAPT_RESOURCE_TABLE_H 278