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