blob: be909361bef1055c04013d1756eee86c6efa5e05 [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/**
50 * The resource value for a specific configuration.
51 */
52struct ResourceConfigValue {
53 ConfigDescription config;
Adam Lesinski1ab598f2015-08-14 14:26:04 -070054 Source source;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080055 std::u16string comment;
56 std::unique_ptr<Value> value;
57};
58
59/**
60 * Represents a resource entry, which may have
61 * varying values for each defined configuration.
62 */
63struct ResourceEntry {
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080064 /**
65 * The name of the resource. Immutable, as
66 * this determines the order of this resource
67 * when doing lookups.
68 */
69 const std::u16string name;
70
71 /**
72 * The entry ID for this resource.
73 */
Adam Lesinski1ab598f2015-08-14 14:26:04 -070074 Maybe<uint16_t> id;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080075
76 /**
77 * Whether this resource is public (and must maintain the same
78 * entry ID across builds).
79 */
Adam Lesinski9e10ac72015-10-16 14:37:48 -070080 Symbol symbolStatus;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080081
82 /**
83 * The resource's values for each configuration.
84 */
85 std::vector<ResourceConfigValue> values;
86
Adam Lesinski1ab598f2015-08-14 14:26:04 -070087 ResourceEntry(const StringPiece16& name) : name(name.toString()) { }
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080088};
89
90/**
91 * Represents a resource type, which holds entries defined
92 * for this type.
93 */
94struct ResourceTableType {
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080095 /**
96 * The logical type of resource (string, drawable, layout, etc.).
97 */
98 const ResourceType type;
99
100 /**
101 * The type ID for this resource.
102 */
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700103 Maybe<uint8_t> id;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800104
105 /**
106 * Whether this type is public (and must maintain the same
107 * type ID across builds).
108 */
Adam Lesinski9e10ac72015-10-16 14:37:48 -0700109 Symbol symbolStatus;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800110
111 /**
112 * List of resources for this type.
113 */
114 std::vector<std::unique_ptr<ResourceEntry>> entries;
115
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700116 explicit ResourceTableType(const ResourceType type) : type(type) { }
117
118 ResourceEntry* findEntry(const StringPiece16& name);
119
120 ResourceEntry* findOrCreateEntry(const StringPiece16& name);
121};
122
123enum class PackageType {
124 System,
125 Vendor,
126 App,
127 Dynamic
128};
129
130struct ResourceTablePackage {
131 PackageType type = PackageType::App;
132 Maybe<uint8_t> id;
133 std::u16string name;
134
135 std::vector<std::unique_ptr<ResourceTableType>> types;
136
137 ResourceTableType* findType(ResourceType type);
138
139 ResourceTableType* findOrCreateType(const ResourceType type);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800140};
141
142/**
143 * The container and index for all resources defined for an app. This gets
144 * flattened into a binary resource table (resources.arsc).
145 */
146class ResourceTable {
147public:
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700148 ResourceTable() = default;
149 ResourceTable(const ResourceTable&) = delete;
150 ResourceTable& operator=(const ResourceTable&) = delete;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800151
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700152 /**
153 * When a collision of resources occurs, this method decides which value to keep.
154 * Returns -1 if the existing value should be chosen.
155 * Returns 0 if the collision can not be resolved (error).
156 * Returns 1 if the incoming value should be chosen.
157 */
158 static int resolveValueCollision(Value* existing, Value* incoming);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800159
160 bool addResource(const ResourceNameRef& name, const ConfigDescription& config,
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700161 const Source& source, std::unique_ptr<Value> value,
162 IDiagnostics* diag);
163
164 bool addResource(const ResourceNameRef& name, const ResourceId resId,
165 const ConfigDescription& config, const Source& source,
166 std::unique_ptr<Value> value, IDiagnostics* diag);
167
168 bool addFileReference(const ResourceNameRef& name, const ConfigDescription& config,
169 const Source& source, const StringPiece16& path, IDiagnostics* diag);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800170
Adam Lesinski330edcd2015-05-04 17:40:56 -0700171 /**
172 * Same as addResource, but doesn't verify the validity of the name. This is used
173 * when loading resources from an existing binary resource table that may have mangled
174 * names.
175 */
176 bool addResourceAllowMangled(const ResourceNameRef& name, const ConfigDescription& config,
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700177 const Source& source, std::unique_ptr<Value> value,
178 IDiagnostics* diag);
Adam Lesinski330edcd2015-05-04 17:40:56 -0700179
Adam Lesinski9e10ac72015-10-16 14:37:48 -0700180 bool addResourceAllowMangled(const ResourceNameRef& name, const ResourceId id,
181 const ConfigDescription& config,
182 const Source& source, std::unique_ptr<Value> value,
183 IDiagnostics* diag);
184
185 bool setSymbolState(const ResourceNameRef& name, const ResourceId resId, const Source& source,
186 SymbolState state, IDiagnostics* diag);
187 bool setSymbolStateAllowMangled(const ResourceNameRef& name, const ResourceId resId,
188 const Source& source, SymbolState state, IDiagnostics* diag);
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700189 struct SearchResult {
Adam Lesinski9ba47d82015-10-13 11:37:10 -0700190 ResourceTablePackage* package;
191 ResourceTableType* type;
192 ResourceEntry* entry;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700193 };
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800194
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700195 Maybe<SearchResult> findResource(const ResourceNameRef& name);
Adam Lesinski769de982015-04-10 19:43:55 -0700196
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800197 /**
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700198 * The string pool used by this resource table. Values that reference strings must use
199 * this pool to create their strings.
200 *
201 * NOTE: `stringPool` must come before `packages` so that it is destroyed after.
202 * When `string pool` references are destroyed (as they will be when `packages`
203 * is destroyed), they decrement a refCount, which would cause invalid
204 * memory access if the pool was already destroyed.
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800205 */
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700206 StringPool stringPool;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800207
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700208 /**
209 * The list of packages in this table, sorted alphabetically by package name.
210 */
211 std::vector<std::unique_ptr<ResourceTablePackage>> packages;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800212
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700213 /**
214 * Returns the package struct with the given name, or nullptr if such a package does not
215 * exist. The empty string is a valid package and typically is used to represent the
216 * 'current' package before it is known to the ResourceTable.
217 */
218 ResourceTablePackage* findPackage(const StringPiece16& name);
219
220 ResourceTablePackage* findPackageById(uint8_t id);
221
Adam Lesinski9ba47d82015-10-13 11:37:10 -0700222 ResourceTablePackage* createPackage(const StringPiece16& name, Maybe<uint8_t> id = {});
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800223
224private:
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700225 ResourceTablePackage* findOrCreatePackage(const StringPiece16& name);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800226
Adam Lesinski330edcd2015-05-04 17:40:56 -0700227 bool addResourceImpl(const ResourceNameRef& name, const ResourceId resId,
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700228 const ConfigDescription& config, const Source& source,
229 std::unique_ptr<Value> value, const char16_t* validChars,
230 IDiagnostics* diag);
Adam Lesinski9e10ac72015-10-16 14:37:48 -0700231 bool setSymbolStateImpl(const ResourceNameRef& name, const ResourceId resId,
232 const Source& source, SymbolState state, const char16_t* validChars,
233 IDiagnostics* diag);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800234};
235
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800236} // namespace aapt
237
238#endif // AAPT_RESOURCE_TABLE_H