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 28namespace aapt { 29namespace test { 30 31class ResourceTableBuilder { 32private: 33 DummyDiagnosticsImpl mDiagnostics; 34 std::unique_ptr<ResourceTable> mTable = util::make_unique<ResourceTable>(); 35 36public: 37 ResourceTableBuilder() = default; 38 39 StringPool* getStringPool() { 40 return &mTable->stringPool; 41 } 42 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 53 ResourceTableBuilder& addReference(const StringPiece16& name, const StringPiece16& ref) { 54 return addReference(name, {}, ref); 55 } 56 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 62 ResourceTableBuilder& addString(const StringPiece16& name, const StringPiece16& str) { 63 return addString(name, {}, str); 64 } 65 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 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 77 ResourceTableBuilder& addFileReference(const StringPiece16& name, const StringPiece16& path) { 78 return addFileReference(name, {}, path); 79 } 80 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 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 93 ResourceTableBuilder& addValue(const StringPiece16& name, 94 std::unique_ptr<Value> value) { 95 return addValue(name, {}, std::move(value)); 96 } 97 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 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 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 123 std::unique_ptr<ResourceTable> build() { 124 return std::move(mTable); 125 } 126}; 127 128inline 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 135inline 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 143template <typename T> 144class ValueBuilder { 145private: 146 std::unique_ptr<Value> mValue; 147 148public: 149 template <typename... Args> 150 ValueBuilder(Args&&... args) : mValue(new T{ std::forward<Args>(args)... }) { 151 } 152 153 template <typename... Args> 154 ValueBuilder& setSource(Args&&... args) { 155 mValue->setSource(Source{ std::forward<Args>(args)... }); 156 return *this; 157 } 158 159 ValueBuilder& setComment(const StringPiece16& str) { 160 mValue->setComment(str); 161 return *this; 162 } 163 164 std::unique_ptr<Value> build() { 165 return std::move(mValue); 166 } 167}; 168 169class AttributeBuilder { 170private: 171 std::unique_ptr<Attribute> mAttr; 172 173public: 174 AttributeBuilder(bool weak = false) : mAttr(util::make_unique<Attribute>(weak)) { 175 mAttr->typeMask = android::ResTable_map::TYPE_ANY; 176 } 177 178 AttributeBuilder& setTypeMask(uint32_t typeMask) { 179 mAttr->typeMask = typeMask; 180 return *this; 181 } 182 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 190 std::unique_ptr<Attribute> build() { 191 return std::move(mAttr); 192 } 193}; 194 195class StyleBuilder { 196private: 197 std::unique_ptr<Style> mStyle = util::make_unique<Style>(); 198 199public: 200 StyleBuilder& setParent(const StringPiece16& str) { 201 mStyle->parent = Reference(parseNameOrDie(str)); 202 return *this; 203 } 204 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 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 216 std::unique_ptr<Style> build() { 217 return std::move(mStyle); 218 } 219}; 220 221class StyleableBuilder { 222private: 223 std::unique_ptr<Styleable> mStyleable = util::make_unique<Styleable>(); 224 225public: 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 232 std::unique_ptr<Styleable> build() { 233 return std::move(mStyleable); 234 } 235}; 236 237inline 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 246inline 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