1 /*
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"
21 #include "Resource.h"
22 #include "ResourceValues.h"
23 #include "Source.h"
24 #include "StringPool.h"
25
26 #include <memory>
27 #include <string>
28 #include <tuple>
29 #include <vector>
30
31 namespace aapt {
32
33 /**
34 * The Public status of a resource.
35 */
36 struct Public {
37 bool isPublic = false;
38 SourceLine source;
39 std::u16string comment;
40 };
41
42 /**
43 * The resource value for a specific configuration.
44 */
45 struct ResourceConfigValue {
46 ConfigDescription config;
47 SourceLine source;
48 std::u16string comment;
49 std::unique_ptr<Value> value;
50 };
51
52 /**
53 * Represents a resource entry, which may have
54 * varying values for each defined configuration.
55 */
56 struct ResourceEntry {
57 enum {
58 kUnsetEntryId = 0xffffffffu
59 };
60
61 /**
62 * The name of the resource. Immutable, as
63 * this determines the order of this resource
64 * when doing lookups.
65 */
66 const std::u16string name;
67
68 /**
69 * The entry ID for this resource.
70 */
71 size_t entryId;
72
73 /**
74 * Whether this resource is public (and must maintain the same
75 * entry ID across builds).
76 */
77 Public publicStatus;
78
79 /**
80 * The resource's values for each configuration.
81 */
82 std::vector<ResourceConfigValue> values;
83
84 inline ResourceEntry(const StringPiece16& _name);
85 inline ResourceEntry(const ResourceEntry* rhs);
86 };
87
88 /**
89 * Represents a resource type, which holds entries defined
90 * for this type.
91 */
92 struct ResourceTableType {
93 enum {
94 kUnsetTypeId = 0xffffffffu
95 };
96
97 /**
98 * The logical type of resource (string, drawable, layout, etc.).
99 */
100 const ResourceType type;
101
102 /**
103 * The type ID for this resource.
104 */
105 size_t typeId;
106
107 /**
108 * Whether this type is public (and must maintain the same
109 * type ID across builds).
110 */
111 Public publicStatus;
112
113 /**
114 * List of resources for this type.
115 */
116 std::vector<std::unique_ptr<ResourceEntry>> entries;
117
118 ResourceTableType(const ResourceType _type);
119 ResourceTableType(const ResourceTableType* rhs);
120 };
121
122 /**
123 * The container and index for all resources defined for an app. This gets
124 * flattened into a binary resource table (resources.arsc).
125 */
126 class ResourceTable {
127 public:
128 using iterator = std::vector<std::unique_ptr<ResourceTableType>>::iterator;
129 using const_iterator = std::vector<std::unique_ptr<ResourceTableType>>::const_iterator;
130
131 enum {
132 kUnsetPackageId = 0xffffffff
133 };
134
135 ResourceTable();
136
137 size_t getPackageId() const;
138 void setPackageId(size_t packageId);
139
140 const std::u16string& getPackage() const;
141 void setPackage(const StringPiece16& package);
142
143 bool addResource(const ResourceNameRef& name, const ConfigDescription& config,
144 const SourceLine& source, std::unique_ptr<Value> value);
145
146 /**
147 * Same as addResource, but doesn't verify the validity of the name. This is used
148 * when loading resources from an existing binary resource table that may have mangled
149 * names.
150 */
151 bool addResourceAllowMangled(const ResourceNameRef& name, const ConfigDescription& config,
152 const SourceLine& source, std::unique_ptr<Value> value);
153
154 bool addResource(const ResourceNameRef& name, const ResourceId resId,
155 const ConfigDescription& config, const SourceLine& source,
156 std::unique_ptr<Value> value);
157
158 bool markPublic(const ResourceNameRef& name, const ResourceId resId, const SourceLine& source);
159 bool markPublicAllowMangled(const ResourceNameRef& name, const ResourceId resId,
160 const SourceLine& source);
161
162 /*
163 * Merges the resources from `other` into this table, mangling the names of the resources
164 * if `other` has a different package name.
165 */
166 bool merge(ResourceTable&& other);
167
168 /**
169 * Returns the string pool used by this ResourceTable.
170 * Values that reference strings should use this pool to create
171 * their strings.
172 */
173 StringPool& getValueStringPool();
174 const StringPool& getValueStringPool() const;
175
176 std::tuple<const ResourceTableType*, const ResourceEntry*>
177 findResource(const ResourceNameRef& name) const;
178
179 iterator begin();
180 iterator end();
181 const_iterator begin() const;
182 const_iterator end() const;
183
184 private:
185 std::unique_ptr<ResourceTableType>& findOrCreateType(ResourceType type);
186 std::unique_ptr<ResourceEntry>& findOrCreateEntry(std::unique_ptr<ResourceTableType>& type,
187 const StringPiece16& name);
188
189 bool addResourceImpl(const ResourceNameRef& name, const ResourceId resId,
190 const ConfigDescription& config, const SourceLine& source,
191 std::unique_ptr<Value> value, const char16_t* validChars);
192 bool markPublicImpl(const ResourceNameRef& name, const ResourceId resId,
193 const SourceLine& source, const char16_t* validChars);
194
195 std::u16string mPackage;
196 size_t mPackageId;
197
198 // StringPool must come before mTypes so that it is destroyed after.
199 // When StringPool references are destroyed (as they will be when mTypes
200 // is destroyed), they decrement a refCount, which would cause invalid
201 // memory access if the pool was already destroyed.
202 StringPool mValuePool;
203
204 std::vector<std::unique_ptr<ResourceTableType>> mTypes;
205 };
206
207 //
208 // ResourceEntry implementation.
209 //
210
ResourceEntry(const StringPiece16 & _name)211 inline ResourceEntry::ResourceEntry(const StringPiece16& _name) :
212 name(_name.toString()), entryId(kUnsetEntryId) {
213 }
214
ResourceEntry(const ResourceEntry * rhs)215 inline ResourceEntry::ResourceEntry(const ResourceEntry* rhs) :
216 name(rhs->name), entryId(rhs->entryId), publicStatus(rhs->publicStatus) {
217 }
218
219 //
220 // ResourceTableType implementation.
221 //
222
ResourceTableType(const ResourceType _type)223 inline ResourceTableType::ResourceTableType(const ResourceType _type) :
224 type(_type), typeId(kUnsetTypeId) {
225 }
226
ResourceTableType(const ResourceTableType * rhs)227 inline ResourceTableType::ResourceTableType(const ResourceTableType* rhs) :
228 type(rhs->type), typeId(rhs->typeId), publicStatus(rhs->publicStatus) {
229 }
230
231 //
232 // ResourceTable implementation.
233 //
234
getValueStringPool()235 inline StringPool& ResourceTable::getValueStringPool() {
236 return mValuePool;
237 }
238
getValueStringPool()239 inline const StringPool& ResourceTable::getValueStringPool() const {
240 return mValuePool;
241 }
242
begin()243 inline ResourceTable::iterator ResourceTable::begin() {
244 return mTypes.begin();
245 }
246
end()247 inline ResourceTable::iterator ResourceTable::end() {
248 return mTypes.end();
249 }
250
begin()251 inline ResourceTable::const_iterator ResourceTable::begin() const {
252 return mTypes.begin();
253 }
254
end()255 inline ResourceTable::const_iterator ResourceTable::end() const {
256 return mTypes.end();
257 }
258
getPackage()259 inline const std::u16string& ResourceTable::getPackage() const {
260 return mPackage;
261 }
262
getPackageId()263 inline size_t ResourceTable::getPackageId() const {
264 return mPackageId;
265 }
266
setPackage(const StringPiece16 & package)267 inline void ResourceTable::setPackage(const StringPiece16& package) {
268 mPackage = package.toString();
269 }
270
setPackageId(size_t packageId)271 inline void ResourceTable::setPackageId(size_t packageId) {
272 mPackageId = packageId;
273 }
274
275 } // namespace aapt
276
277 #endif // AAPT_RESOURCE_TABLE_H
278