blob: 0dae091dffb433ed6d03ced7999093d045ea5f7d [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_VALUES_H
18#define AAPT_RESOURCE_VALUES_H
19
Adam Lesinski1ab598f2015-08-14 14:26:04 -070020#include "util/Maybe.h"
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080021#include "Resource.h"
22#include "StringPool.h"
23
24#include <array>
25#include <androidfw/ResourceTypes.h>
26#include <ostream>
27#include <vector>
28
29namespace aapt {
30
Adam Lesinski1ab598f2015-08-14 14:26:04 -070031struct RawValueVisitor;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080032
33/**
34 * A resource value. This is an all-encompassing representation
35 * of Item and Map and their subclasses. The way to do
36 * type specific operations is to check the Value's type() and
37 * cast it to the appropriate subclass. This isn't super clean,
38 * but it is the simplest strategy.
39 */
40struct Value {
Adam Lesinski1ab598f2015-08-14 14:26:04 -070041 virtual ~Value() = default;
42
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080043 /**
44 * Whether or not this is an Item.
45 */
46 virtual bool isItem() const;
47
48 /**
Adam Lesinski1ab598f2015-08-14 14:26:04 -070049 * Whether this value is weak and can be overridden without
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080050 * warning or error. Default for base class is false.
51 */
52 virtual bool isWeak() const;
53
54 /**
55 * Calls the appropriate overload of ValueVisitor.
56 */
Adam Lesinski1ab598f2015-08-14 14:26:04 -070057 virtual void accept(RawValueVisitor* visitor) = 0;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080058
59 /**
60 * Clone the value.
61 */
Adam Lesinski769de982015-04-10 19:43:55 -070062 virtual Value* clone(StringPool* newPool) const = 0;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080063
64 /**
65 * Human readable printout of this value.
66 */
Adam Lesinski1ab598f2015-08-14 14:26:04 -070067 virtual void print(std::ostream* out) const = 0;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080068};
69
70/**
71 * Inherit from this to get visitor accepting implementations for free.
72 */
73template <typename Derived>
74struct BaseValue : public Value {
Adam Lesinski1ab598f2015-08-14 14:26:04 -070075 void accept(RawValueVisitor* visitor) override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080076};
77
78/**
79 * A resource item with a single value. This maps to android::ResTable_entry.
80 */
81struct Item : public Value {
82 /**
83 * An Item is, of course, an Item.
84 */
85 virtual bool isItem() const override;
86
87 /**
88 * Clone the Item.
89 */
Adam Lesinski769de982015-04-10 19:43:55 -070090 virtual Item* clone(StringPool* newPool) const override = 0;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080091
92 /**
93 * Fills in an android::Res_value structure with this Item's binary representation.
Adam Lesinski1ab598f2015-08-14 14:26:04 -070094 * Returns false if an error occurred.
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080095 */
Adam Lesinski1ab598f2015-08-14 14:26:04 -070096 virtual bool flatten(android::Res_value* outValue) const = 0;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080097};
98
99/**
100 * Inherit from this to get visitor accepting implementations for free.
101 */
102template <typename Derived>
103struct BaseItem : public Item {
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700104 void accept(RawValueVisitor* visitor) override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800105};
106
107/**
108 * A reference to another resource. This maps to android::Res_value::TYPE_REFERENCE.
109 *
110 * A reference can be symbolic (with the name set to a valid resource name) or be
111 * numeric (the id is set to a valid resource ID).
112 */
113struct Reference : public BaseItem<Reference> {
114 enum class Type {
115 kResource,
116 kAttribute,
117 };
118
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700119 Maybe<ResourceName> name;
120 Maybe<ResourceId> id;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800121 Reference::Type referenceType;
122 bool privateReference = false;
123
124 Reference();
125 Reference(const ResourceNameRef& n, Type type = Type::kResource);
126 Reference(const ResourceId& i, Type type = Type::kResource);
127
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700128 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700129 Reference* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700130 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800131};
132
133/**
134 * An ID resource. Has no real value, just a place holder.
135 */
136struct Id : public BaseItem<Id> {
137 bool isWeak() const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700138 bool flatten(android::Res_value* out) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700139 Id* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700140 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800141};
142
143/**
144 * A raw, unprocessed string. This may contain quotations,
145 * escape sequences, and whitespace. This shall *NOT*
146 * end up in the final resource table.
147 */
148struct RawString : public BaseItem<RawString> {
149 StringPool::Ref value;
150
151 RawString(const StringPool::Ref& ref);
152
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700153 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700154 RawString* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700155 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800156};
157
158struct String : public BaseItem<String> {
159 StringPool::Ref value;
160
161 String(const StringPool::Ref& ref);
162
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700163 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700164 String* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700165 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800166};
167
168struct StyledString : public BaseItem<StyledString> {
169 StringPool::StyleRef value;
170
171 StyledString(const StringPool::StyleRef& ref);
172
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700173 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700174 StyledString* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700175 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800176};
177
178struct FileReference : public BaseItem<FileReference> {
179 StringPool::Ref path;
180
181 FileReference() = default;
182 FileReference(const StringPool::Ref& path);
183
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700184 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700185 FileReference* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700186 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800187};
188
189/**
190 * Represents any other android::Res_value.
191 */
192struct BinaryPrimitive : public BaseItem<BinaryPrimitive> {
193 android::Res_value value;
194
195 BinaryPrimitive() = default;
196 BinaryPrimitive(const android::Res_value& val);
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700197 BinaryPrimitive(uint8_t dataType, uint32_t data);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800198
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700199 bool flatten(android::Res_value* outValue) const override;
Adam Lesinski769de982015-04-10 19:43:55 -0700200 BinaryPrimitive* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700201 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800202};
203
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800204struct Attribute : public BaseValue<Attribute> {
205 struct Symbol {
206 Reference symbol;
207 uint32_t value;
208 };
209
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700210 bool weak;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800211 uint32_t typeMask;
212 uint32_t minInt;
213 uint32_t maxInt;
214 std::vector<Symbol> symbols;
215
216 Attribute(bool w, uint32_t t = 0u);
217
218 bool isWeak() const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700219 Attribute* clone(StringPool* newPool) const override;
220 void printMask(std::ostream* out) const;
221 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800222};
223
224struct Style : public BaseValue<Style> {
225 struct Entry {
226 Reference key;
227 std::unique_ptr<Item> value;
228 };
229
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700230 Maybe<Reference> parent;
Adam Lesinskibdaa0922015-05-08 20:16:23 -0700231
232 /**
233 * If set to true, the parent was auto inferred from the
234 * style's name.
235 */
236 bool parentInferred = false;
237
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800238 std::vector<Entry> entries;
239
Adam Lesinski769de982015-04-10 19:43:55 -0700240 Style* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700241 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800242};
243
244struct Array : public BaseValue<Array> {
245 std::vector<std::unique_ptr<Item>> items;
246
Adam Lesinski769de982015-04-10 19:43:55 -0700247 Array* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700248 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800249};
250
251struct Plural : public BaseValue<Plural> {
252 enum {
253 Zero = 0,
254 One,
255 Two,
256 Few,
257 Many,
258 Other,
259 Count
260 };
261
262 std::array<std::unique_ptr<Item>, Count> values;
263
Adam Lesinski769de982015-04-10 19:43:55 -0700264 Plural* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700265 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800266};
267
268struct Styleable : public BaseValue<Styleable> {
269 std::vector<Reference> entries;
270
Adam Lesinski769de982015-04-10 19:43:55 -0700271 Styleable* clone(StringPool* newPool) const override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700272 void print(std::ostream* out) const override;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800273};
274
275/**
276 * Stream operator for printing Value objects.
277 */
278inline ::std::ostream& operator<<(::std::ostream& out, const Value& value) {
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700279 value.print(&out);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800280 return out;
281}
282
Adam Lesinski330edcd2015-05-04 17:40:56 -0700283inline ::std::ostream& operator<<(::std::ostream& out, const Attribute::Symbol& s) {
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700284 if (s.symbol.name) {
285 out << s.symbol.name.value().entry;
286 } else {
287 out << "???";
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800288 }
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700289 return out << "=" << s.value;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800290}
291
292} // namespace aapt
293
294#endif // AAPT_RESOURCE_VALUES_H