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