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_TEST_BUILDERS_H
18 #define AAPT_TEST_BUILDERS_H
19
20 #include "ResourceTable.h"
21 #include "ResourceValues.h"
22 #include "test/Common.h"
23 #include "util/Util.h"
24 #include "xml/XmlDom.h"
25
26 #include <memory>
27
28 namespace aapt {
29 namespace test {
30
31 class ResourceTableBuilder {
32 private:
33 DummyDiagnosticsImpl mDiagnostics;
34 std::unique_ptr<ResourceTable> mTable = util::make_unique<ResourceTable>();
35
36 public:
37 ResourceTableBuilder() = default;
38
getStringPool()39 StringPool* getStringPool() {
40 return &mTable->stringPool;
41 }
42
setPackageId(const StringPiece16 & packageName,uint8_t id)43 ResourceTableBuilder& setPackageId(const StringPiece16& packageName, uint8_t id) {
44 ResourceTablePackage* package = mTable->createPackage(packageName, id);
45 assert(package);
46 return *this;
47 }
48
49 ResourceTableBuilder& addSimple(const StringPiece16& name, const ResourceId id = {}) {
50 return addValue(name, id, util::make_unique<Id>());
51 }
52
addReference(const StringPiece16 & name,const StringPiece16 & ref)53 ResourceTableBuilder& addReference(const StringPiece16& name, const StringPiece16& ref) {
54 return addReference(name, {}, ref);
55 }
56
addReference(const StringPiece16 & name,const ResourceId id,const StringPiece16 & ref)57 ResourceTableBuilder& addReference(const StringPiece16& name, const ResourceId id,
58 const StringPiece16& ref) {
59 return addValue(name, id, util::make_unique<Reference>(parseNameOrDie(ref)));
60 }
61
addString(const StringPiece16 & name,const StringPiece16 & str)62 ResourceTableBuilder& addString(const StringPiece16& name, const StringPiece16& str) {
63 return addString(name, {}, str);
64 }
65
addString(const StringPiece16 & name,const ResourceId id,const StringPiece16 & str)66 ResourceTableBuilder& addString(const StringPiece16& name, const ResourceId id,
67 const StringPiece16& str) {
68 return addValue(name, id, util::make_unique<String>(mTable->stringPool.makeRef(str)));
69 }
70
addString(const StringPiece16 & name,const ResourceId id,const ConfigDescription & config,const StringPiece16 & str)71 ResourceTableBuilder& addString(const StringPiece16& name, const ResourceId id,
72 const ConfigDescription& config, const StringPiece16& str) {
73 return addValue(name, id, config,
74 util::make_unique<String>(mTable->stringPool.makeRef(str)));
75 }
76
addFileReference(const StringPiece16 & name,const StringPiece16 & path)77 ResourceTableBuilder& addFileReference(const StringPiece16& name, const StringPiece16& path) {
78 return addFileReference(name, {}, path);
79 }
80
addFileReference(const StringPiece16 & name,const ResourceId id,const StringPiece16 & path)81 ResourceTableBuilder& addFileReference(const StringPiece16& name, const ResourceId id,
82 const StringPiece16& path) {
83 return addValue(name, id,
84 util::make_unique<FileReference>(mTable->stringPool.makeRef(path)));
85 }
86
addFileReference(const StringPiece16 & name,const StringPiece16 & path,const ConfigDescription & config)87 ResourceTableBuilder& addFileReference(const StringPiece16& name, const StringPiece16& path,
88 const ConfigDescription& config) {
89 return addValue(name, {}, config,
90 util::make_unique<FileReference>(mTable->stringPool.makeRef(path)));
91 }
92
addValue(const StringPiece16 & name,std::unique_ptr<Value> value)93 ResourceTableBuilder& addValue(const StringPiece16& name,
94 std::unique_ptr<Value> value) {
95 return addValue(name, {}, std::move(value));
96 }
97
addValue(const StringPiece16 & name,const ResourceId id,std::unique_ptr<Value> value)98 ResourceTableBuilder& addValue(const StringPiece16& name, const ResourceId id,
99 std::unique_ptr<Value> value) {
100 return addValue(name, id, {}, std::move(value));
101 }
102
addValue(const StringPiece16 & name,const ResourceId id,const ConfigDescription & config,std::unique_ptr<Value> value)103 ResourceTableBuilder& addValue(const StringPiece16& name, const ResourceId id,
104 const ConfigDescription& config,
105 std::unique_ptr<Value> value) {
106 ResourceName resName = parseNameOrDie(name);
107 bool result = mTable->addResourceAllowMangled(resName, id, config, std::string(),
108 std::move(value), &mDiagnostics);
109 assert(result);
110 return *this;
111 }
112
setSymbolState(const StringPiece16 & name,ResourceId id,SymbolState state)113 ResourceTableBuilder& setSymbolState(const StringPiece16& name, ResourceId id,
114 SymbolState state) {
115 ResourceName resName = parseNameOrDie(name);
116 Symbol symbol;
117 symbol.state = state;
118 bool result = mTable->setSymbolStateAllowMangled(resName, id, symbol, &mDiagnostics);
119 assert(result);
120 return *this;
121 }
122
build()123 std::unique_ptr<ResourceTable> build() {
124 return std::move(mTable);
125 }
126 };
127
128 inline std::unique_ptr<Reference> buildReference(const StringPiece16& ref,
129 Maybe<ResourceId> id = {}) {
130 std::unique_ptr<Reference> reference = util::make_unique<Reference>(parseNameOrDie(ref));
131 reference->id = id;
132 return reference;
133 }
134
buildPrimitive(uint8_t type,uint32_t data)135 inline std::unique_ptr<BinaryPrimitive> buildPrimitive(uint8_t type, uint32_t data) {
136 android::Res_value value = {};
137 value.size = sizeof(value);
138 value.dataType = type;
139 value.data = data;
140 return util::make_unique<BinaryPrimitive>(value);
141 }
142
143 template <typename T>
144 class ValueBuilder {
145 private:
146 std::unique_ptr<Value> mValue;
147
148 public:
149 template <typename... Args>
ValueBuilder(Args &&...args)150 ValueBuilder(Args&&... args) : mValue(new T{ std::forward<Args>(args)... }) {
151 }
152
153 template <typename... Args>
setSource(Args &&...args)154 ValueBuilder& setSource(Args&&... args) {
155 mValue->setSource(Source{ std::forward<Args>(args)... });
156 return *this;
157 }
158
setComment(const StringPiece16 & str)159 ValueBuilder& setComment(const StringPiece16& str) {
160 mValue->setComment(str);
161 return *this;
162 }
163
build()164 std::unique_ptr<Value> build() {
165 return std::move(mValue);
166 }
167 };
168
169 class AttributeBuilder {
170 private:
171 std::unique_ptr<Attribute> mAttr;
172
173 public:
mAttr(util::make_unique<Attribute> (weak))174 AttributeBuilder(bool weak = false) : mAttr(util::make_unique<Attribute>(weak)) {
175 mAttr->typeMask = android::ResTable_map::TYPE_ANY;
176 }
177
setTypeMask(uint32_t typeMask)178 AttributeBuilder& setTypeMask(uint32_t typeMask) {
179 mAttr->typeMask = typeMask;
180 return *this;
181 }
182
addItem(const StringPiece16 & name,uint32_t value)183 AttributeBuilder& addItem(const StringPiece16& name, uint32_t value) {
184 mAttr->symbols.push_back(Attribute::Symbol{
185 Reference(ResourceName{ {}, ResourceType::kId, name.toString()}),
186 value});
187 return *this;
188 }
189
build()190 std::unique_ptr<Attribute> build() {
191 return std::move(mAttr);
192 }
193 };
194
195 class StyleBuilder {
196 private:
197 std::unique_ptr<Style> mStyle = util::make_unique<Style>();
198
199 public:
setParent(const StringPiece16 & str)200 StyleBuilder& setParent(const StringPiece16& str) {
201 mStyle->parent = Reference(parseNameOrDie(str));
202 return *this;
203 }
204
addItem(const StringPiece16 & str,std::unique_ptr<Item> value)205 StyleBuilder& addItem(const StringPiece16& str, std::unique_ptr<Item> value) {
206 mStyle->entries.push_back(Style::Entry{ Reference(parseNameOrDie(str)), std::move(value) });
207 return *this;
208 }
209
addItem(const StringPiece16 & str,ResourceId id,std::unique_ptr<Item> value)210 StyleBuilder& addItem(const StringPiece16& str, ResourceId id, std::unique_ptr<Item> value) {
211 addItem(str, std::move(value));
212 mStyle->entries.back().key.id = id;
213 return *this;
214 }
215
build()216 std::unique_ptr<Style> build() {
217 return std::move(mStyle);
218 }
219 };
220
221 class StyleableBuilder {
222 private:
223 std::unique_ptr<Styleable> mStyleable = util::make_unique<Styleable>();
224
225 public:
226 StyleableBuilder& addItem(const StringPiece16& str, Maybe<ResourceId> id = {}) {
227 mStyleable->entries.push_back(Reference(parseNameOrDie(str)));
228 mStyleable->entries.back().id = id;
229 return *this;
230 }
231
build()232 std::unique_ptr<Styleable> build() {
233 return std::move(mStyleable);
234 }
235 };
236
buildXmlDom(const StringPiece & str)237 inline std::unique_ptr<xml::XmlResource> buildXmlDom(const StringPiece& str) {
238 std::stringstream in;
239 in << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" << str;
240 StdErrDiagnostics diag;
241 std::unique_ptr<xml::XmlResource> doc = xml::inflate(&in, &diag, Source("test.xml"));
242 assert(doc);
243 return doc;
244 }
245
buildXmlDomForPackageName(IAaptContext * context,const StringPiece & str)246 inline std::unique_ptr<xml::XmlResource> buildXmlDomForPackageName(IAaptContext* context,
247 const StringPiece& str) {
248 std::unique_ptr<xml::XmlResource> doc = buildXmlDom(str);
249 doc->file.name.package = context->getCompilationPackage();
250 return doc;
251 }
252
253 } // namespace test
254 } // namespace aapt
255
256 #endif /* AAPT_TEST_BUILDERS_H */
257