• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_VALUES_H
18 #define AAPT_RESOURCE_VALUES_H
19 
20 #include "Diagnostics.h"
21 #include "Resource.h"
22 #include "StringPool.h"
23 #include "io/File.h"
24 #include "util/Maybe.h"
25 
26 #include <array>
27 #include <androidfw/ResourceTypes.h>
28 #include <ostream>
29 #include <vector>
30 
31 namespace aapt {
32 
33 struct RawValueVisitor;
34 
35 /**
36  * A resource value. This is an all-encompassing representation
37  * of Item and Map and their subclasses. The way to do
38  * type specific operations is to check the Value's type() and
39  * cast it to the appropriate subclass. This isn't super clean,
40  * but it is the simplest strategy.
41  */
42 struct Value {
43 	virtual ~Value() = default;
44 
45     /**
46      * Whether this value is weak and can be overridden without
47      * warning or error. Default is false.
48      */
isWeakValue49     bool isWeak() const {
50         return mWeak;
51     }
52 
setWeakValue53     void setWeak(bool val) {
54         mWeak = val;
55     }
56 
57     // Whether the value is marked as translateable.
58     // This does not persist when flattened.
59     // It is only used during compilation phase.
setTranslateableValue60     void setTranslateable(bool val) {
61         mTranslateable = val;
62     }
63 
64     // Default true.
isTranslateableValue65     bool isTranslateable() const {
66         return mTranslateable;
67     }
68 
69     /**
70      * Returns the source where this value was defined.
71      */
getSourceValue72     const Source& getSource() const {
73         return mSource;
74     }
75 
setSourceValue76     void setSource(const Source& source) {
77         mSource = source;
78     }
79 
setSourceValue80     void setSource(Source&& source) {
81         mSource = std::move(source);
82     }
83 
84     /**
85      * Returns the comment that was associated with this resource.
86      */
getCommentValue87     StringPiece16 getComment() const {
88         return mComment;
89     }
90 
setCommentValue91     void setComment(const StringPiece16& str) {
92         mComment = str.toString();
93     }
94 
setCommentValue95     void setComment(std::u16string&& str) {
96         mComment = std::move(str);
97     }
98 
99     virtual bool equals(const Value* value) const = 0;
100 
101     /**
102      * Calls the appropriate overload of ValueVisitor.
103      */
104     virtual void accept(RawValueVisitor* visitor) = 0;
105 
106     /**
107      * Clone the value.
108      */
109     virtual Value* clone(StringPool* newPool) const = 0;
110 
111     /**
112      * Human readable printout of this value.
113      */
114     virtual void print(std::ostream* out) const = 0;
115 
116 protected:
117     Source mSource;
118     std::u16string mComment;
119     bool mWeak = false;
120     bool mTranslateable = true;
121 };
122 
123 /**
124  * Inherit from this to get visitor accepting implementations for free.
125  */
126 template <typename Derived>
127 struct BaseValue : public Value {
128     void accept(RawValueVisitor* visitor) override;
129 };
130 
131 /**
132  * A resource item with a single value. This maps to android::ResTable_entry.
133  */
134 struct Item : public Value {
135     /**
136      * Clone the Item.
137      */
138     virtual Item* clone(StringPool* newPool) const override = 0;
139 
140     /**
141      * Fills in an android::Res_value structure with this Item's binary representation.
142      * Returns false if an error occurred.
143      */
144     virtual bool flatten(android::Res_value* outValue) const = 0;
145 };
146 
147 /**
148  * Inherit from this to get visitor accepting implementations for free.
149  */
150 template <typename Derived>
151 struct BaseItem : public Item {
152     void accept(RawValueVisitor* visitor) override;
153 };
154 
155 /**
156  * A reference to another resource. This maps to android::Res_value::TYPE_REFERENCE.
157  *
158  * A reference can be symbolic (with the name set to a valid resource name) or be
159  * numeric (the id is set to a valid resource ID).
160  */
161 struct Reference : public BaseItem<Reference> {
162     enum class Type {
163         kResource,
164         kAttribute,
165     };
166 
167     Maybe<ResourceName> name;
168     Maybe<ResourceId> id;
169     Reference::Type referenceType;
170     bool privateReference = false;
171 
172     Reference();
173     explicit Reference(const ResourceNameRef& n, Type type = Type::kResource);
174     explicit Reference(const ResourceId& i, Type type = Type::kResource);
175 
176     bool equals(const Value* value) const override;
177     bool flatten(android::Res_value* outValue) const override;
178     Reference* clone(StringPool* newPool) const override;
179     void print(std::ostream* out) const override;
180 };
181 
182 /**
183  * An ID resource. Has no real value, just a place holder.
184  */
185 struct Id : public BaseItem<Id> {
IdId186     Id() { mWeak = true; }
187     bool equals(const Value* value) const override;
188     bool flatten(android::Res_value* out) const override;
189     Id* clone(StringPool* newPool) const override;
190     void print(std::ostream* out) const override;
191 };
192 
193 /**
194  * A raw, unprocessed string. This may contain quotations,
195  * escape sequences, and whitespace. This shall *NOT*
196  * end up in the final resource table.
197  */
198 struct RawString : public BaseItem<RawString> {
199     StringPool::Ref value;
200 
201     RawString(const StringPool::Ref& ref);
202 
203     bool equals(const Value* value) const override;
204     bool flatten(android::Res_value* outValue) const override;
205     RawString* clone(StringPool* newPool) const override;
206     void print(std::ostream* out) const override;
207 };
208 
209 struct String : public BaseItem<String> {
210     StringPool::Ref value;
211 
212     String(const StringPool::Ref& ref);
213 
214     bool equals(const Value* value) const override;
215     bool flatten(android::Res_value* outValue) const override;
216     String* clone(StringPool* newPool) const override;
217     void print(std::ostream* out) const override;
218 };
219 
220 struct StyledString : public BaseItem<StyledString> {
221     StringPool::StyleRef value;
222 
223     StyledString(const StringPool::StyleRef& ref);
224 
225     bool equals(const Value* value) const override;
226     bool flatten(android::Res_value* outValue) const override;
227     StyledString* clone(StringPool* newPool) const override;
228     void print(std::ostream* out) const override;
229 };
230 
231 struct FileReference : public BaseItem<FileReference> {
232     StringPool::Ref path;
233 
234     /**
235      * A handle to the file object from which this file can be read.
236      */
237     io::IFile* file = nullptr;
238 
239     FileReference() = default;
240     FileReference(const StringPool::Ref& path);
241 
242     bool equals(const Value* value) const override;
243     bool flatten(android::Res_value* outValue) const override;
244     FileReference* clone(StringPool* newPool) const override;
245     void print(std::ostream* out) const override;
246 };
247 
248 /**
249  * Represents any other android::Res_value.
250  */
251 struct BinaryPrimitive : public BaseItem<BinaryPrimitive> {
252     android::Res_value value;
253 
254     BinaryPrimitive() = default;
255     BinaryPrimitive(const android::Res_value& val);
256     BinaryPrimitive(uint8_t dataType, uint32_t data);
257 
258     bool equals(const Value* value) const override;
259     bool flatten(android::Res_value* outValue) const override;
260     BinaryPrimitive* clone(StringPool* newPool) const override;
261     void print(std::ostream* out) const override;
262 };
263 
264 struct Attribute : public BaseValue<Attribute> {
265     struct Symbol {
266         Reference symbol;
267         uint32_t value;
268     };
269 
270     uint32_t typeMask;
271     int32_t minInt;
272     int32_t maxInt;
273     std::vector<Symbol> symbols;
274 
275     Attribute(bool w, uint32_t t = 0u);
276 
277     bool equals(const Value* value) const override;
278     Attribute* clone(StringPool* newPool) const override;
279     void printMask(std::ostream* out) const;
280     void print(std::ostream* out) const override;
281     bool matches(const Item* item, DiagMessage* outMsg) const;
282 };
283 
284 struct Style : public BaseValue<Style> {
285     struct Entry {
286         Reference key;
287         std::unique_ptr<Item> value;
288     };
289 
290     Maybe<Reference> parent;
291 
292     /**
293      * If set to true, the parent was auto inferred from the
294      * style's name.
295      */
296     bool parentInferred = false;
297 
298     std::vector<Entry> entries;
299 
300     bool equals(const Value* value) const override;
301     Style* clone(StringPool* newPool) const override;
302     void print(std::ostream* out) const override;
303 };
304 
305 struct Array : public BaseValue<Array> {
306     std::vector<std::unique_ptr<Item>> items;
307 
308     bool equals(const Value* value) const override;
309     Array* clone(StringPool* newPool) const override;
310     void print(std::ostream* out) const override;
311 };
312 
313 struct Plural : public BaseValue<Plural> {
314     enum {
315         Zero = 0,
316         One,
317         Two,
318         Few,
319         Many,
320         Other,
321         Count
322     };
323 
324     std::array<std::unique_ptr<Item>, Count> values;
325 
326     bool equals(const Value* value) const override;
327     Plural* clone(StringPool* newPool) const override;
328     void print(std::ostream* out) const override;
329 };
330 
331 struct Styleable : public BaseValue<Styleable> {
332     std::vector<Reference> entries;
333 
334     bool equals(const Value* value) const override;
335     Styleable* clone(StringPool* newPool) const override;
336     void print(std::ostream* out) const override;
337 };
338 
339 /**
340  * Stream operator for printing Value objects.
341  */
342 inline ::std::ostream& operator<<(::std::ostream& out, const Value& value) {
343     value.print(&out);
344     return out;
345 }
346 
347 inline ::std::ostream& operator<<(::std::ostream& out, const Attribute::Symbol& s) {
348     if (s.symbol.name) {
349         out << s.symbol.name.value().entry;
350     } else {
351         out << "???";
352     }
353     return out << "=" << s.value;
354 }
355 
356 } // namespace aapt
357 
358 #endif // AAPT_RESOURCE_VALUES_H
359