2 * Copyright (C) 2015 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #ifndef AAPT_RESOURCE_TABLE_H
18 #define AAPT_RESOURCE_TABLE_H
20 #include "ConfigDescription.h"
21 #include "Diagnostics.h"
23 #include "ResourceValues.h"
25 #include "StringPool.h"
28 #include <android-base/macros.h>
34 #include <unordered_map>
39 enum class SymbolState {
46 * The Public status of a resource.
49 SymbolState state = SymbolState::kUndefined;
51 std::u16string comment;
54 class ResourceConfigValue {
57 * The configuration for which this value is defined.
59 const ConfigDescription config;
62 * The product for which this value is defined.
64 const std::string product;
69 std::unique_ptr<Value> value;
71 ResourceConfigValue(const ConfigDescription& config, const StringPiece& product) :
72 config(config), product(product.toString()) { }
75 DISALLOW_COPY_AND_ASSIGN(ResourceConfigValue);
79 * Represents a resource entry, which may have
80 * varying values for each defined configuration.
85 * The name of the resource. Immutable, as
86 * this determines the order of this resource
89 const std::u16string name;
92 * The entry ID for this resource.
97 * Whether this resource is public (and must maintain the same entry ID across builds).
102 * The resource's values for each configuration.
104 std::vector<std::unique_ptr<ResourceConfigValue>> values;
106 ResourceEntry(const StringPiece16& name) : name(name.toString()) { }
108 ResourceConfigValue* findValue(const ConfigDescription& config);
109 ResourceConfigValue* findValue(const ConfigDescription& config, const StringPiece& product);
110 ResourceConfigValue* findOrCreateValue(const ConfigDescription& config,
111 const StringPiece& product);
112 std::vector<ResourceConfigValue*> findAllValues(const ConfigDescription& config);
113 std::vector<ResourceConfigValue*> findValuesIf(
114 const std::function<bool(ResourceConfigValue*)>& f);
118 DISALLOW_COPY_AND_ASSIGN(ResourceEntry);
122 * Represents a resource type, which holds entries defined
125 class ResourceTableType {
128 * The logical type of resource (string, drawable, layout, etc.).
130 const ResourceType type;
133 * The type ID for this resource.
138 * Whether this type is public (and must maintain the same
139 * type ID across builds).
144 * List of resources for this type.
146 std::vector<std::unique_ptr<ResourceEntry>> entries;
148 explicit ResourceTableType(const ResourceType type) : type(type) { }
150 ResourceEntry* findEntry(const StringPiece16& name);
151 ResourceEntry* findOrCreateEntry(const StringPiece16& name);
154 DISALLOW_COPY_AND_ASSIGN(ResourceTableType);
157 enum class PackageType {
164 class ResourceTablePackage {
166 PackageType type = PackageType::App;
170 std::vector<std::unique_ptr<ResourceTableType>> types;
172 ResourceTablePackage() = default;
173 ResourceTableType* findType(ResourceType type);
174 ResourceTableType* findOrCreateType(const ResourceType type);
177 DISALLOW_COPY_AND_ASSIGN(ResourceTablePackage);
181 * The container and index for all resources defined for an app. This gets
182 * flattened into a binary resource table (resources.arsc).
184 class ResourceTable {
186 ResourceTable() = default;
189 * When a collision of resources occurs, this method decides which value to keep.
190 * Returns -1 if the existing value should be chosen.
191 * Returns 0 if the collision can not be resolved (error).
192 * Returns 1 if the incoming value should be chosen.
194 static int resolveValueCollision(Value* existing, Value* incoming);
196 bool addResource(const ResourceNameRef& name,
197 const ConfigDescription& config,
198 const StringPiece& product,
199 std::unique_ptr<Value> value,
202 bool addResource(const ResourceNameRef& name,
203 const ResourceId resId,
204 const ConfigDescription& config,
205 const StringPiece& product,
206 std::unique_ptr<Value> value,
209 bool addFileReference(const ResourceNameRef& name,
210 const ConfigDescription& config,
211 const Source& source,
212 const StringPiece16& path,
215 bool addFileReferenceAllowMangled(const ResourceNameRef& name,
216 const ConfigDescription& config,
217 const Source& source,
218 const StringPiece16& path,
223 * Same as addResource, but doesn't verify the validity of the name. This is used
224 * when loading resources from an existing binary resource table that may have mangled
227 bool addResourceAllowMangled(const ResourceNameRef& name,
228 const ConfigDescription& config,
229 const StringPiece& product,
230 std::unique_ptr<Value> value,
233 bool addResourceAllowMangled(const ResourceNameRef& name,
235 const ConfigDescription& config,
236 const StringPiece& product,
237 std::unique_ptr<Value> value,
240 bool setSymbolState(const ResourceNameRef& name,
241 const ResourceId resId,
242 const Symbol& symbol,
245 bool setSymbolStateAllowMangled(const ResourceNameRef& name,
246 const ResourceId resId,
247 const Symbol& symbol,
250 struct SearchResult {
251 ResourceTablePackage* package;
252 ResourceTableType* type;
253 ResourceEntry* entry;
256 Maybe<SearchResult> findResource(const ResourceNameRef& name);
259 * The string pool used by this resource table. Values that reference strings must use
260 * this pool to create their strings.
262 * NOTE: `stringPool` must come before `packages` so that it is destroyed after.
263 * When `string pool` references are destroyed (as they will be when `packages`
264 * is destroyed), they decrement a refCount, which would cause invalid
265 * memory access if the pool was already destroyed.
267 StringPool stringPool;
270 * The list of packages in this table, sorted alphabetically by package name.
272 std::vector<std::unique_ptr<ResourceTablePackage>> packages;
275 * Returns the package struct with the given name, or nullptr if such a package does not
276 * exist. The empty string is a valid package and typically is used to represent the
277 * 'current' package before it is known to the ResourceTable.
279 ResourceTablePackage* findPackage(const StringPiece16& name);
281 ResourceTablePackage* findPackageById(uint8_t id);
283 ResourceTablePackage* createPackage(const StringPiece16& name, Maybe<uint8_t> id = {});
286 ResourceTablePackage* findOrCreatePackage(const StringPiece16& name);
288 bool addFileReferenceImpl(const ResourceNameRef& name,
289 const ConfigDescription& config,
290 const Source& source,
291 const StringPiece16& path,
293 const char16_t* validChars,
296 bool addResourceImpl(const ResourceNameRef& name,
298 const ConfigDescription& config,
299 const StringPiece& product,
300 std::unique_ptr<Value> value,
301 const char16_t* validChars,
302 std::function<int(Value*,Value*)> conflictResolver,
305 bool setSymbolStateImpl(const ResourceNameRef& name,
307 const Symbol& symbol,
308 const char16_t* validChars,
311 DISALLOW_COPY_AND_ASSIGN(ResourceTable);
316 #endif // AAPT_RESOURCE_TABLE_H