blob: 60fed2f0e26bb37b7d20ce2a7551034183b3e5cc [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
34/**
35 * The Public status of a resource.
36 */
37struct Public {
38 bool isPublic = false;
Adam Lesinski1ab598f2015-08-14 14:26:04 -070039 Source source;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080040 std::u16string comment;
41};
42
43/**
44 * The resource value for a specific configuration.
45 */
46struct ResourceConfigValue {
47 ConfigDescription config;
Adam Lesinski1ab598f2015-08-14 14:26:04 -070048 Source source;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080049 std::u16string comment;
50 std::unique_ptr<Value> value;
51};
52
53/**
54 * Represents a resource entry, which may have
55 * varying values for each defined configuration.
56 */
57struct ResourceEntry {
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080058 /**
59 * The name of the resource. Immutable, as
60 * this determines the order of this resource
61 * when doing lookups.
62 */
63 const std::u16string name;
64
65 /**
66 * The entry ID for this resource.
67 */
Adam Lesinski1ab598f2015-08-14 14:26:04 -070068 Maybe<uint16_t> id;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080069
70 /**
71 * Whether this resource is public (and must maintain the same
72 * entry ID across builds).
73 */
74 Public publicStatus;
75
76 /**
77 * The resource's values for each configuration.
78 */
79 std::vector<ResourceConfigValue> values;
80
Adam Lesinski1ab598f2015-08-14 14:26:04 -070081 ResourceEntry(const StringPiece16& name) : name(name.toString()) { }
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080082};
83
84/**
85 * Represents a resource type, which holds entries defined
86 * for this type.
87 */
88struct ResourceTableType {
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080089 /**
90 * The logical type of resource (string, drawable, layout, etc.).
91 */
92 const ResourceType type;
93
94 /**
95 * The type ID for this resource.
96 */
Adam Lesinski1ab598f2015-08-14 14:26:04 -070097 Maybe<uint8_t> id;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080098
99 /**
100 * Whether this type is public (and must maintain the same
101 * type ID across builds).
102 */
103 Public publicStatus;
104
105 /**
106 * List of resources for this type.
107 */
108 std::vector<std::unique_ptr<ResourceEntry>> entries;
109
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700110 explicit ResourceTableType(const ResourceType type) : type(type) { }
111
112 ResourceEntry* findEntry(const StringPiece16& name);
113
114 ResourceEntry* findOrCreateEntry(const StringPiece16& name);
115};
116
117enum class PackageType {
118 System,
119 Vendor,
120 App,
121 Dynamic
122};
123
124struct ResourceTablePackage {
125 PackageType type = PackageType::App;
126 Maybe<uint8_t> id;
127 std::u16string name;
128
129 std::vector<std::unique_ptr<ResourceTableType>> types;
130
131 ResourceTableType* findType(ResourceType type);
132
133 ResourceTableType* findOrCreateType(const ResourceType type);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800134};
135
136/**
137 * The container and index for all resources defined for an app. This gets
138 * flattened into a binary resource table (resources.arsc).
139 */
140class ResourceTable {
141public:
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700142 ResourceTable() = default;
143 ResourceTable(const ResourceTable&) = delete;
144 ResourceTable& operator=(const ResourceTable&) = delete;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800145
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700146 /**
147 * When a collision of resources occurs, this method decides which value to keep.
148 * Returns -1 if the existing value should be chosen.
149 * Returns 0 if the collision can not be resolved (error).
150 * Returns 1 if the incoming value should be chosen.
151 */
152 static int resolveValueCollision(Value* existing, Value* incoming);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800153
154 bool addResource(const ResourceNameRef& name, const ConfigDescription& config,
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700155 const Source& source, std::unique_ptr<Value> value,
156 IDiagnostics* diag);
157
158 bool addResource(const ResourceNameRef& name, const ResourceId resId,
159 const ConfigDescription& config, const Source& source,
160 std::unique_ptr<Value> value, IDiagnostics* diag);
161
162 bool addFileReference(const ResourceNameRef& name, const ConfigDescription& config,
163 const Source& source, const StringPiece16& path, IDiagnostics* diag);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800164
Adam Lesinski330edcd2015-05-04 17:40:56 -0700165 /**
166 * Same as addResource, but doesn't verify the validity of the name. This is used
167 * when loading resources from an existing binary resource table that may have mangled
168 * names.
169 */
170 bool addResourceAllowMangled(const ResourceNameRef& name, const ConfigDescription& config,
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700171 const Source& source, std::unique_ptr<Value> value,
172 IDiagnostics* diag);
Adam Lesinski330edcd2015-05-04 17:40:56 -0700173
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700174 bool markPublic(const ResourceNameRef& name, const ResourceId resId, const Source& source,
175 IDiagnostics* diag);
Adam Lesinski330edcd2015-05-04 17:40:56 -0700176 bool markPublicAllowMangled(const ResourceNameRef& name, const ResourceId resId,
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700177 const Source& source, IDiagnostics* diag);
178 struct SearchResult {
Adam Lesinski9ba47d82015-10-13 11:37:10 -0700179 ResourceTablePackage* package;
180 ResourceTableType* type;
181 ResourceEntry* entry;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700182 };
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800183
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700184 Maybe<SearchResult> findResource(const ResourceNameRef& name);
Adam Lesinski769de982015-04-10 19:43:55 -0700185
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800186 /**
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700187 * The string pool used by this resource table. Values that reference strings must use
188 * this pool to create their strings.
189 *
190 * NOTE: `stringPool` must come before `packages` so that it is destroyed after.
191 * When `string pool` references are destroyed (as they will be when `packages`
192 * is destroyed), they decrement a refCount, which would cause invalid
193 * memory access if the pool was already destroyed.
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800194 */
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700195 StringPool stringPool;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800196
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700197 /**
198 * The list of packages in this table, sorted alphabetically by package name.
199 */
200 std::vector<std::unique_ptr<ResourceTablePackage>> packages;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800201
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700202 /**
203 * Returns the package struct with the given name, or nullptr if such a package does not
204 * exist. The empty string is a valid package and typically is used to represent the
205 * 'current' package before it is known to the ResourceTable.
206 */
207 ResourceTablePackage* findPackage(const StringPiece16& name);
208
209 ResourceTablePackage* findPackageById(uint8_t id);
210
Adam Lesinski9ba47d82015-10-13 11:37:10 -0700211 ResourceTablePackage* createPackage(const StringPiece16& name, Maybe<uint8_t> id = {});
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800212
213private:
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700214 ResourceTablePackage* findOrCreatePackage(const StringPiece16& name);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800215
Adam Lesinski330edcd2015-05-04 17:40:56 -0700216 bool addResourceImpl(const ResourceNameRef& name, const ResourceId resId,
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700217 const ConfigDescription& config, const Source& source,
218 std::unique_ptr<Value> value, const char16_t* validChars,
219 IDiagnostics* diag);
Adam Lesinski330edcd2015-05-04 17:40:56 -0700220 bool markPublicImpl(const ResourceNameRef& name, const ResourceId resId,
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700221 const Source& source, const char16_t* validChars, IDiagnostics* diag);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800222};
223
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800224} // namespace aapt
225
226#endif // AAPT_RESOURCE_TABLE_H