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