blob: 980504be377b2f6dc3ddc1eeab08eae22a01f17b [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,
166 const Source& source, const StringPiece16& path, IDiagnostics* diag);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800167
Adam Lesinski330edcd2015-05-04 17:40:56 -0700168 /**
169 * Same as addResource, but doesn't verify the validity of the name. This is used
170 * when loading resources from an existing binary resource table that may have mangled
171 * names.
172 */
173 bool addResourceAllowMangled(const ResourceNameRef& name, const ConfigDescription& config,
Adam Lesinskie78fd612015-10-22 12:48:43 -0700174 std::unique_ptr<Value> value, IDiagnostics* diag);
Adam Lesinski330edcd2015-05-04 17:40:56 -0700175
Adam Lesinski9e10ac72015-10-16 14:37:48 -0700176 bool addResourceAllowMangled(const ResourceNameRef& name, const ResourceId id,
Adam Lesinskie78fd612015-10-22 12:48:43 -0700177 const ConfigDescription& config, std::unique_ptr<Value> value,
Adam Lesinski9e10ac72015-10-16 14:37:48 -0700178 IDiagnostics* diag);
179
Adam Lesinskie78fd612015-10-22 12:48:43 -0700180 bool setSymbolState(const ResourceNameRef& name, const ResourceId resId,
181 const Symbol& symbol, IDiagnostics* diag);
182
Adam Lesinski9e10ac72015-10-16 14:37:48 -0700183 bool setSymbolStateAllowMangled(const ResourceNameRef& name, const ResourceId resId,
Adam Lesinskie78fd612015-10-22 12:48:43 -0700184 const Symbol& symbol, IDiagnostics* diag);
185
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700186 struct SearchResult {
Adam Lesinski9ba47d82015-10-13 11:37:10 -0700187 ResourceTablePackage* package;
188 ResourceTableType* type;
189 ResourceEntry* entry;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700190 };
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800191
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700192 Maybe<SearchResult> findResource(const ResourceNameRef& name);
Adam Lesinski769de982015-04-10 19:43:55 -0700193
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800194 /**
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700195 * The string pool used by this resource table. Values that reference strings must use
196 * this pool to create their strings.
197 *
198 * NOTE: `stringPool` must come before `packages` so that it is destroyed after.
199 * When `string pool` references are destroyed (as they will be when `packages`
200 * is destroyed), they decrement a refCount, which would cause invalid
201 * memory access if the pool was already destroyed.
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800202 */
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700203 StringPool stringPool;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800204
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700205 /**
206 * The list of packages in this table, sorted alphabetically by package name.
207 */
208 std::vector<std::unique_ptr<ResourceTablePackage>> packages;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800209
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700210 /**
211 * Returns the package struct with the given name, or nullptr if such a package does not
212 * exist. The empty string is a valid package and typically is used to represent the
213 * 'current' package before it is known to the ResourceTable.
214 */
215 ResourceTablePackage* findPackage(const StringPiece16& name);
216
217 ResourceTablePackage* findPackageById(uint8_t id);
218
Adam Lesinski9ba47d82015-10-13 11:37:10 -0700219 ResourceTablePackage* createPackage(const StringPiece16& name, Maybe<uint8_t> id = {});
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800220
221private:
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700222 ResourceTablePackage* findOrCreatePackage(const StringPiece16& name);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800223
Adam Lesinskie78fd612015-10-22 12:48:43 -0700224 bool addResourceImpl(const ResourceNameRef& name, ResourceId resId,
225 const ConfigDescription& config, std::unique_ptr<Value> value,
226 const char16_t* validChars, IDiagnostics* diag);
227 bool setSymbolStateImpl(const ResourceNameRef& name, ResourceId resId,
228 const Symbol& symbol, const char16_t* validChars, IDiagnostics* diag);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800229};
230
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800231} // namespace aapt
232
233#endif // AAPT_RESOURCE_TABLE_H