blob: 6b7b07ea3a93e8b3cf7415f0d3a927374191c947 [file] [log] [blame]
Adam Lesinski6f6ceb72014-11-14 14:48:12 -08001/*
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"
Adam Lesinski1ab598f2015-08-14 14:26:04 -070021#include "Diagnostics.h"
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080022#include "Resource.h"
23#include "ResourceValues.h"
24#include "Source.h"
25#include "StringPool.h"
26
27#include <memory>
28#include <string>
29#include <tuple>
30#include <vector>
31
32namespace aapt {
33
Adam Lesinski9e10ac72015-10-16 14:37:48 -070034enum class SymbolState {
35 kUndefined,
36 kPublic,
37 kPrivate
38};
39
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080040/**
41 * The Public status of a resource.
42 */
Adam Lesinski9e10ac72015-10-16 14:37:48 -070043struct Symbol {
44 SymbolState state = SymbolState::kUndefined;
Adam Lesinski1ab598f2015-08-14 14:26:04 -070045 Source source;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080046 std::u16string comment;
47};
48
49/**
Adam Lesinskie78fd612015-10-22 12:48:43 -070050 * Represents a value defined for a given configuration.
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080051 */
52struct ResourceConfigValue {
53 ConfigDescription config;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080054 std::unique_ptr<Value> value;
55};
56
57/**
58 * Represents a resource entry, which may have
59 * varying values for each defined configuration.
60 */
61struct ResourceEntry {
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080062 /**
63 * The name of the resource. Immutable, as
64 * this determines the order of this resource
65 * when doing lookups.
66 */
67 const std::u16string name;
68
69 /**
70 * The entry ID for this resource.
71 */
Adam Lesinski1ab598f2015-08-14 14:26:04 -070072 Maybe<uint16_t> id;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080073
74 /**
75 * Whether this resource is public (and must maintain the same
76 * entry ID across builds).
77 */
Adam Lesinski9e10ac72015-10-16 14:37:48 -070078 Symbol symbolStatus;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080079
80 /**
81 * The resource's values for each configuration.
82 */
83 std::vector<ResourceConfigValue> values;
84
Adam Lesinski1ab598f2015-08-14 14:26:04 -070085 ResourceEntry(const StringPiece16& name) : name(name.toString()) { }
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080086};
87
88/**
89 * Represents a resource type, which holds entries defined
90 * for this type.
91 */
92struct ResourceTableType {
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080093 /**
94 * The logical type of resource (string, drawable, layout, etc.).
95 */
96 const ResourceType type;
97
98 /**
99 * The type ID for this resource.
100 */
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700101 Maybe<uint8_t> id;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800102
103 /**
104 * Whether this type is public (and must maintain the same
105 * type ID across builds).
106 */
Adam Lesinski9e10ac72015-10-16 14:37:48 -0700107 Symbol symbolStatus;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800108
109 /**
110 * List of resources for this type.
111 */
112 std::vector<std::unique_ptr<ResourceEntry>> entries;
113
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700114 explicit ResourceTableType(const ResourceType type) : type(type) { }
115
116 ResourceEntry* findEntry(const StringPiece16& name);
117
118 ResourceEntry* findOrCreateEntry(const StringPiece16& name);
119};
120
121enum class PackageType {
122 System,
123 Vendor,
124 App,
125 Dynamic
126};
127
128struct ResourceTablePackage {
129 PackageType type = PackageType::App;
130 Maybe<uint8_t> id;
131 std::u16string name;
132
133 std::vector<std::unique_ptr<ResourceTableType>> types;
134
135 ResourceTableType* findType(ResourceType type);
136
137 ResourceTableType* findOrCreateType(const ResourceType type);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800138};
139
140/**
141 * The container and index for all resources defined for an app. This gets
142 * flattened into a binary resource table (resources.arsc).
143 */
144class ResourceTable {
145public:
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700146 ResourceTable() = default;
147 ResourceTable(const ResourceTable&) = delete;
148 ResourceTable& operator=(const ResourceTable&) = delete;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800149
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700150 /**
151 * When a collision of resources occurs, this method decides which value to keep.
152 * Returns -1 if the existing value should be chosen.
153 * Returns 0 if the collision can not be resolved (error).
154 * Returns 1 if the incoming value should be chosen.
155 */
156 static int resolveValueCollision(Value* existing, Value* incoming);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800157
158 bool addResource(const ResourceNameRef& name, const ConfigDescription& config,
Adam Lesinskie78fd612015-10-22 12:48:43 -0700159 std::unique_ptr<Value> value, IDiagnostics* diag);
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700160
161 bool addResource(const ResourceNameRef& name, const ResourceId resId,
Adam Lesinskie78fd612015-10-22 12:48:43 -0700162 const ConfigDescription& config, std::unique_ptr<Value> value,
163 IDiagnostics* diag);
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700164
165 bool addFileReference(const ResourceNameRef& name, const ConfigDescription& config,
Adam Lesinskifb48d292015-11-07 15:52:13 -0800166 const Source& source, const StringPiece16& path,
167 IDiagnostics* diag);
168
169 bool addFileReference(const ResourceNameRef& name, const ConfigDescription& config,
170 const Source& source, const StringPiece16& path,
171 std::function<int(Value*,Value*)> conflictResolver, IDiagnostics* diag);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800172
Adam Lesinski330edcd2015-05-04 17:40:56 -0700173 /**
174 * Same as addResource, but doesn't verify the validity of the name. This is used
175 * when loading resources from an existing binary resource table that may have mangled
176 * names.
177 */
178 bool addResourceAllowMangled(const ResourceNameRef& name, const ConfigDescription& config,
Adam Lesinskie78fd612015-10-22 12:48:43 -0700179 std::unique_ptr<Value> value, IDiagnostics* diag);
Adam Lesinski330edcd2015-05-04 17:40:56 -0700180
Adam Lesinski9e10ac72015-10-16 14:37:48 -0700181 bool addResourceAllowMangled(const ResourceNameRef& name, const ResourceId id,
Adam Lesinskie78fd612015-10-22 12:48:43 -0700182 const ConfigDescription& config, std::unique_ptr<Value> value,
Adam Lesinski9e10ac72015-10-16 14:37:48 -0700183 IDiagnostics* diag);
184
Adam Lesinskie78fd612015-10-22 12:48:43 -0700185 bool setSymbolState(const ResourceNameRef& name, const ResourceId resId,
186 const Symbol& symbol, IDiagnostics* diag);
187
Adam Lesinski9e10ac72015-10-16 14:37:48 -0700188 bool setSymbolStateAllowMangled(const ResourceNameRef& name, const ResourceId resId,
Adam Lesinskie78fd612015-10-22 12:48:43 -0700189 const Symbol& symbol, IDiagnostics* diag);
190
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700191 struct SearchResult {
Adam Lesinski9ba47d82015-10-13 11:37:10 -0700192 ResourceTablePackage* package;
193 ResourceTableType* type;
194 ResourceEntry* entry;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700195 };
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800196
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700197 Maybe<SearchResult> findResource(const ResourceNameRef& name);
Adam Lesinski769de982015-04-10 19:43:55 -0700198
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800199 /**
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700200 * The string pool used by this resource table. Values that reference strings must use
201 * this pool to create their strings.
202 *
203 * NOTE: `stringPool` must come before `packages` so that it is destroyed after.
204 * When `string pool` references are destroyed (as they will be when `packages`
205 * is destroyed), they decrement a refCount, which would cause invalid
206 * memory access if the pool was already destroyed.
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800207 */
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700208 StringPool stringPool;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800209
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700210 /**
211 * The list of packages in this table, sorted alphabetically by package name.
212 */
213 std::vector<std::unique_ptr<ResourceTablePackage>> packages;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800214
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700215 /**
216 * Returns the package struct with the given name, or nullptr if such a package does not
217 * exist. The empty string is a valid package and typically is used to represent the
218 * 'current' package before it is known to the ResourceTable.
219 */
220 ResourceTablePackage* findPackage(const StringPiece16& name);
221
222 ResourceTablePackage* findPackageById(uint8_t id);
223
Adam Lesinski9ba47d82015-10-13 11:37:10 -0700224 ResourceTablePackage* createPackage(const StringPiece16& name, Maybe<uint8_t> id = {});
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800225
226private:
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700227 ResourceTablePackage* findOrCreatePackage(const StringPiece16& name);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800228
Adam Lesinskifb48d292015-11-07 15:52:13 -0800229 bool addResourceImpl(const ResourceNameRef& name,
230 ResourceId resId,
231 const ConfigDescription& config,
232 std::unique_ptr<Value> value,
233 const char16_t* validChars,
234 std::function<int(Value*,Value*)> conflictResolver,
235 IDiagnostics* diag);
236
Adam Lesinskie78fd612015-10-22 12:48:43 -0700237 bool setSymbolStateImpl(const ResourceNameRef& name, ResourceId resId,
238 const Symbol& symbol, const char16_t* validChars, IDiagnostics* diag);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800239};
240
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800241} // namespace aapt
242
243#endif // AAPT_RESOURCE_TABLE_H