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 <array> 21 #include <limits> 22 #include <ostream> 23 #include <vector> 24 25 #include "androidfw/ResourceTypes.h" 26 #include "androidfw/StringPiece.h" 27 28 #include "Diagnostics.h" 29 #include "Resource.h" 30 #include "StringPool.h" 31 #include "io/File.h" 32 #include "text/Printer.h" 33 #include "util/Maybe.h" 34 35 namespace aapt { 36 37 class ValueVisitor; 38 class ConstValueVisitor; 39 40 // A resource value. This is an all-encompassing representation 41 // of Item and Map and their subclasses. The way to do 42 // type specific operations is to check the Value's type() and 43 // cast it to the appropriate subclass. This isn't super clean, 44 // but it is the simplest strategy. 45 class Value { 46 public: 47 virtual ~Value() = default; 48 49 // Whether this value is weak and can be overridden without warning or error. Default is false. IsWeak()50 bool IsWeak() const { 51 return weak_; 52 } 53 SetWeak(bool val)54 void SetWeak(bool val) { 55 weak_ = val; 56 } 57 58 // Whether the value is marked as translatable. This does not persist when flattened to binary. 59 // It is only used during compilation phase. SetTranslatable(bool val)60 void SetTranslatable(bool val) { 61 translatable_ = val; 62 } 63 64 // Default true. IsTranslatable()65 bool IsTranslatable() const { 66 return translatable_; 67 } 68 69 // Returns the source where this value was defined. GetSource()70 const Source& GetSource() const { 71 return source_; 72 } 73 SetSource(const Source & source)74 void SetSource(const Source& source) { 75 source_ = source; 76 } 77 SetSource(Source && source)78 void SetSource(Source&& source) { 79 source_ = std::move(source); 80 } 81 82 // Returns the comment that was associated with this resource. GetComment()83 const std::string& GetComment() const { 84 return comment_; 85 } 86 SetComment(const android::StringPiece & str)87 void SetComment(const android::StringPiece& str) { 88 comment_ = str.to_string(); 89 } 90 SetComment(std::string && str)91 void SetComment(std::string&& str) { 92 comment_ = std::move(str); 93 } 94 95 virtual bool Equals(const Value* value) const = 0; 96 97 // Calls the appropriate overload of ValueVisitor. 98 virtual void Accept(ValueVisitor* visitor) = 0; 99 100 // Calls the appropriate overload of ConstValueVisitor. 101 virtual void Accept(ConstValueVisitor* visitor) const = 0; 102 103 // Clone the value. `new_pool` is the new StringPool that 104 // any resources with strings should use when copying their string. 105 virtual Value* Clone(StringPool* new_pool) const = 0; 106 107 // Human readable printout of this value. 108 virtual void Print(std::ostream* out) const = 0; 109 110 // Human readable printout of this value that may omit some information for the sake 111 // of brevity and readability. Default implementation just calls Print(). 112 virtual void PrettyPrint(text::Printer* printer) const; 113 114 friend std::ostream& operator<<(std::ostream& out, const Value& value); 115 116 protected: 117 Source source_; 118 std::string comment_; 119 bool weak_ = false; 120 bool translatable_ = true; 121 }; 122 123 // Inherit from this to get visitor accepting implementations for free. 124 template <typename Derived> 125 struct BaseValue : public Value { 126 void Accept(ValueVisitor* visitor) override; 127 void Accept(ConstValueVisitor* visitor) const override; 128 }; 129 130 // A resource item with a single value. This maps to android::ResTable_entry. 131 struct Item : public Value { 132 // Clone the Item. 133 virtual Item* Clone(StringPool* new_pool) const override = 0; 134 135 // Fills in an android::Res_value structure with this Item's binary representation. 136 // Returns false if an error occurred. 137 virtual bool Flatten(android::Res_value* out_value) const = 0; 138 }; 139 140 // Inherit from this to get visitor accepting implementations for free. 141 template <typename Derived> 142 struct BaseItem : public Item { 143 void Accept(ValueVisitor* visitor) override; 144 void Accept(ConstValueVisitor* visitor) const override; 145 }; 146 147 // A reference to another resource. This maps to android::Res_value::TYPE_REFERENCE. 148 // A reference can be symbolic (with the name set to a valid resource name) or be 149 // numeric (the id is set to a valid resource ID). 150 struct Reference : public BaseItem<Reference> { 151 enum class Type { 152 kResource, 153 kAttribute, 154 }; 155 156 Maybe<ResourceName> name; 157 Maybe<ResourceId> id; 158 Reference::Type reference_type; 159 bool private_reference = false; 160 bool is_dynamic = false; 161 162 Reference(); 163 explicit Reference(const ResourceNameRef& n, Type type = Type::kResource); 164 explicit Reference(const ResourceId& i, Type type = Type::kResource); 165 Reference(const ResourceNameRef& n, const ResourceId& i); 166 167 bool Equals(const Value* value) const override; 168 bool Flatten(android::Res_value* out_value) const override; 169 Reference* Clone(StringPool* new_pool) const override; 170 void Print(std::ostream* out) const override; 171 void PrettyPrint(text::Printer* printer) const override; 172 173 // Prints the reference without a package name if the package name matches the one given. 174 void PrettyPrint(const android::StringPiece& package, text::Printer* printer) const; 175 }; 176 177 bool operator<(const Reference&, const Reference&); 178 bool operator==(const Reference&, const Reference&); 179 180 // An ID resource. Has no real value, just a place holder. 181 struct Id : public BaseItem<Id> { IdId182 Id() { 183 weak_ = true; 184 } 185 186 bool Equals(const Value* value) const override; 187 bool Flatten(android::Res_value* out) const override; 188 Id* Clone(StringPool* new_pool) const override; 189 void Print(std::ostream* out) const override; 190 }; 191 192 // A raw, unprocessed string. This may contain quotations, escape sequences, and whitespace. 193 // This shall *NOT* end up in the final resource table. 194 struct RawString : public BaseItem<RawString> { 195 StringPool::Ref value; 196 197 explicit RawString(const StringPool::Ref& ref); 198 199 bool Equals(const Value* value) const override; 200 bool Flatten(android::Res_value* out_value) const override; 201 RawString* Clone(StringPool* new_pool) const override; 202 void Print(std::ostream* out) const override; 203 }; 204 205 // Identifies a range of characters in a string that are untranslatable. 206 // These should not be pseudolocalized. The start and end indices are measured in bytes. 207 struct UntranslatableSection { 208 // Start offset inclusive. 209 size_t start; 210 211 // End offset exclusive. 212 size_t end; 213 }; 214 215 inline bool operator==(const UntranslatableSection& a, const UntranslatableSection& b) { 216 return a.start == b.start && a.end == b.end; 217 } 218 219 inline bool operator!=(const UntranslatableSection& a, const UntranslatableSection& b) { 220 return a.start != b.start || a.end != b.end; 221 } 222 223 struct String : public BaseItem<String> { 224 StringPool::Ref value; 225 226 // Sections of the string to NOT translate. Mainly used 227 // for pseudolocalization. This data is NOT persisted 228 // in any format. 229 std::vector<UntranslatableSection> untranslatable_sections; 230 231 explicit String(const StringPool::Ref& ref); 232 233 bool Equals(const Value* value) const override; 234 bool Flatten(android::Res_value* out_value) const override; 235 String* Clone(StringPool* new_pool) const override; 236 void Print(std::ostream* out) const override; 237 void PrettyPrint(text::Printer* printer) const override; 238 }; 239 240 struct StyledString : public BaseItem<StyledString> { 241 StringPool::StyleRef value; 242 243 // Sections of the string to NOT translate. Mainly used 244 // for pseudolocalization. This data is NOT persisted 245 // in any format. 246 std::vector<UntranslatableSection> untranslatable_sections; 247 248 explicit StyledString(const StringPool::StyleRef& ref); 249 250 bool Equals(const Value* value) const override; 251 bool Flatten(android::Res_value* out_value) const override; 252 StyledString* Clone(StringPool* new_pool) const override; 253 void Print(std::ostream* out) const override; 254 }; 255 256 struct FileReference : public BaseItem<FileReference> { 257 StringPool::Ref path; 258 259 // A handle to the file object from which this file can be read. 260 // This field is NOT persisted in any format. It is transient. 261 io::IFile* file = nullptr; 262 263 // FileType of the file pointed to by `file`. This is used to know how to inflate the file, 264 // or if to inflate at all (just copy). 265 ResourceFile::Type type = ResourceFile::Type::kUnknown; 266 267 FileReference() = default; 268 explicit FileReference(const StringPool::Ref& path); 269 270 bool Equals(const Value* value) const override; 271 bool Flatten(android::Res_value* out_value) const override; 272 FileReference* Clone(StringPool* new_pool) const override; 273 void Print(std::ostream* out) const override; 274 }; 275 276 // Represents any other android::Res_value. 277 struct BinaryPrimitive : public BaseItem<BinaryPrimitive> { 278 android::Res_value value; 279 280 BinaryPrimitive() = default; 281 explicit BinaryPrimitive(const android::Res_value& val); 282 BinaryPrimitive(uint8_t dataType, uint32_t data); 283 284 bool Equals(const Value* value) const override; 285 bool Flatten(android::Res_value* out_value) const override; 286 BinaryPrimitive* Clone(StringPool* new_pool) const override; 287 void Print(std::ostream* out) const override; 288 void PrettyPrint(text::Printer* printer) const override; 289 }; 290 291 struct Attribute : public BaseValue<Attribute> { 292 struct Symbol { 293 Reference symbol; 294 uint32_t value; 295 296 friend std::ostream& operator<<(std::ostream& out, const Symbol& symbol); 297 }; 298 299 uint32_t type_mask; 300 int32_t min_int; 301 int32_t max_int; 302 std::vector<Symbol> symbols; 303 304 explicit Attribute(uint32_t t = 0u); 305 306 bool Equals(const Value* value) const override; 307 308 // Returns true if this Attribute's format is compatible with the given Attribute. The basic 309 // rule is that TYPE_REFERENCE can be ignored for both of the Attributes, and TYPE_FLAGS and 310 // TYPE_ENUMS are never compatible. 311 bool IsCompatibleWith(const Attribute& attr) const; 312 313 Attribute* Clone(StringPool* new_pool) const override; 314 std::string MaskString() const; 315 void Print(std::ostream* out) const override; 316 bool Matches(const Item& item, DiagMessage* out_msg = nullptr) const; 317 }; 318 319 struct Style : public BaseValue<Style> { 320 struct Entry { 321 Reference key; 322 std::unique_ptr<Item> value; 323 324 friend std::ostream& operator<<(std::ostream& out, const Entry& entry); 325 }; 326 327 Maybe<Reference> parent; 328 329 // If set to true, the parent was auto inferred from the style's name. 330 bool parent_inferred = false; 331 332 std::vector<Entry> entries; 333 334 bool Equals(const Value* value) const override; 335 Style* Clone(StringPool* new_pool) const override; 336 void Print(std::ostream* out) const override; 337 338 // Merges `style` into this Style. All identical attributes of `style` take precedence, including 339 // the parent, if there is one. 340 void MergeWith(Style* style, StringPool* pool); 341 }; 342 343 struct Array : public BaseValue<Array> { 344 std::vector<std::unique_ptr<Item>> elements; 345 346 bool Equals(const Value* value) const override; 347 Array* Clone(StringPool* new_pool) const override; 348 void Print(std::ostream* out) const override; 349 }; 350 351 struct Plural : public BaseValue<Plural> { 352 enum { Zero = 0, One, Two, Few, Many, Other, Count }; 353 354 std::array<std::unique_ptr<Item>, Count> values; 355 356 bool Equals(const Value* value) const override; 357 Plural* Clone(StringPool* new_pool) const override; 358 void Print(std::ostream* out) const override; 359 }; 360 361 struct Styleable : public BaseValue<Styleable> { 362 std::vector<Reference> entries; 363 364 bool Equals(const Value* value) const override; 365 Styleable* Clone(StringPool* newPool) const override; 366 void Print(std::ostream* out) const override; 367 void MergeWith(Styleable* styleable); 368 }; 369 370 template <typename T> 371 typename std::enable_if<std::is_base_of<Value, T>::value, std::ostream&>::type operator<<( 372 std::ostream& out, const std::unique_ptr<T>& value) { 373 if (value == nullptr) { 374 out << "NULL"; 375 } else { 376 value->Print(&out); 377 } 378 return out; 379 } 380 381 } // namespace aapt 382 383 #endif // AAPT_RESOURCE_VALUES_H 384