1 // 2 // Copyright 2006 The Android Open Source Project 3 // 4 // Build resource files from raw assets. 5 // 6 7 #ifndef RESOURCE_TABLE_H 8 #define RESOURCE_TABLE_H 9 10 #include "StringPool.h" 11 #include "SourcePos.h" 12 13 #include <set> 14 #include <map> 15 16 using namespace std; 17 18 class XMLNode; 19 class ResourceTable; 20 21 enum { 22 XML_COMPILE_STRIP_COMMENTS = 1<<0, 23 XML_COMPILE_ASSIGN_ATTRIBUTE_IDS = 1<<1, 24 XML_COMPILE_COMPACT_WHITESPACE = 1<<2, 25 XML_COMPILE_STRIP_WHITESPACE = 1<<3, 26 XML_COMPILE_STRIP_RAW_VALUES = 1<<4, 27 XML_COMPILE_UTF8 = 1<<5, 28 29 XML_COMPILE_STANDARD_RESOURCE = 30 XML_COMPILE_STRIP_COMMENTS | XML_COMPILE_ASSIGN_ATTRIBUTE_IDS 31 | XML_COMPILE_STRIP_WHITESPACE | XML_COMPILE_STRIP_RAW_VALUES 32 }; 33 34 status_t compileXmlFile(const sp<AaptAssets>& assets, 35 const sp<AaptFile>& target, 36 ResourceTable* table, 37 int options = XML_COMPILE_STANDARD_RESOURCE); 38 39 status_t compileXmlFile(const sp<AaptAssets>& assets, 40 const sp<AaptFile>& target, 41 const sp<AaptFile>& outTarget, 42 ResourceTable* table, 43 int options = XML_COMPILE_STANDARD_RESOURCE); 44 45 status_t compileXmlFile(const sp<AaptAssets>& assets, 46 const sp<XMLNode>& xmlTree, 47 const sp<AaptFile>& target, 48 ResourceTable* table, 49 int options = XML_COMPILE_STANDARD_RESOURCE); 50 51 status_t compileResourceFile(Bundle* bundle, 52 const sp<AaptAssets>& assets, 53 const sp<AaptFile>& in, 54 const ResTable_config& defParams, 55 const bool overwrite, 56 ResourceTable* outTable); 57 58 struct AccessorCookie 59 { 60 SourcePos sourcePos; 61 String8 attr; 62 String8 value; 63 64 AccessorCookie(const SourcePos&p, const String8& a, const String8& v) 65 :sourcePos(p), 66 attr(a), 67 value(v) 68 { 69 } 70 }; 71 72 class ResourceTable : public ResTable::Accessor 73 { 74 public: 75 class Package; 76 class Type; 77 class Entry; 78 79 ResourceTable(Bundle* bundle, const String16& assetsPackage); 80 81 status_t addIncludedResources(Bundle* bundle, const sp<AaptAssets>& assets); 82 83 status_t addPublic(const SourcePos& pos, 84 const String16& package, 85 const String16& type, 86 const String16& name, 87 const uint32_t ident); 88 89 status_t addEntry(const SourcePos& pos, 90 const String16& package, 91 const String16& type, 92 const String16& name, 93 const String16& value, 94 const Vector<StringPool::entry_style_span>* style = NULL, 95 const ResTable_config* params = NULL, 96 const bool doSetIndex = false, 97 const int32_t format = ResTable_map::TYPE_ANY, 98 const bool overwrite = false); 99 100 status_t startBag(const SourcePos& pos, 101 const String16& package, 102 const String16& type, 103 const String16& name, 104 const String16& bagParent, 105 const ResTable_config* params = NULL, 106 bool overlay = false, 107 bool replace = false, 108 bool isId = false); 109 110 status_t addBag(const SourcePos& pos, 111 const String16& package, 112 const String16& type, 113 const String16& name, 114 const String16& bagParent, 115 const String16& bagKey, 116 const String16& value, 117 const Vector<StringPool::entry_style_span>* style = NULL, 118 const ResTable_config* params = NULL, 119 bool replace = false, 120 bool isId = false, 121 const int32_t format = ResTable_map::TYPE_ANY); 122 123 bool hasBagOrEntry(const String16& package, 124 const String16& type, 125 const String16& name) const; 126 127 bool hasBagOrEntry(const String16& ref, 128 const String16* defType = NULL, 129 const String16* defPackage = NULL); 130 131 bool appendComment(const String16& package, 132 const String16& type, 133 const String16& name, 134 const String16& comment, 135 bool onlyIfEmpty = false); 136 137 bool appendTypeComment(const String16& package, 138 const String16& type, 139 const String16& name, 140 const String16& comment); 141 142 void canAddEntry(const SourcePos& pos, 143 const String16& package, const String16& type, const String16& name); 144 145 size_t size() const; 146 size_t numLocalResources() const; 147 bool hasResources() const; 148 149 sp<AaptFile> flatten(Bundle*); 150 151 static inline uint32_t makeResId(uint32_t packageId, 152 uint32_t typeId, 153 uint32_t nameId) 154 { 155 return nameId | (typeId<<16) | (packageId<<24); 156 } 157 158 static inline uint32_t getResId(const sp<Package>& p, 159 const sp<Type>& t, 160 uint32_t nameId); 161 162 uint32_t getResId(const String16& package, 163 const String16& type, 164 const String16& name, 165 bool onlyPublic = false) const; 166 167 uint32_t getResId(const String16& ref, 168 const String16* defType = NULL, 169 const String16* defPackage = NULL, 170 const char** outErrorMsg = NULL, 171 bool onlyPublic = false) const; 172 173 static bool isValidResourceName(const String16& s); 174 175 bool stringToValue(Res_value* outValue, StringPool* pool, 176 const String16& str, 177 bool preserveSpaces, bool coerceType, 178 uint32_t attrID, 179 const Vector<StringPool::entry_style_span>* style = NULL, 180 String16* outStr = NULL, void* accessorCookie = NULL, 181 uint32_t attrType = ResTable_map::TYPE_ANY); 182 183 status_t assignResourceIds(); 184 status_t addSymbols(const sp<AaptSymbols>& outSymbols = NULL); 185 void addLocalization(const String16& name, const String8& locale); 186 status_t validateLocalizations(void); 187 188 status_t flatten(Bundle*, const sp<AaptFile>& dest); 189 190 void writePublicDefinitions(const String16& package, FILE* fp); 191 192 virtual uint32_t getCustomResource(const String16& package, 193 const String16& type, 194 const String16& name) const; 195 virtual uint32_t getCustomResourceWithCreation(const String16& package, 196 const String16& type, 197 const String16& name, 198 const bool createIfNeeded); 199 virtual uint32_t getRemappedPackage(uint32_t origPackage) const; 200 virtual bool getAttributeType(uint32_t attrID, uint32_t* outType); 201 virtual bool getAttributeMin(uint32_t attrID, uint32_t* outMin); 202 virtual bool getAttributeMax(uint32_t attrID, uint32_t* outMax); 203 virtual bool getAttributeKeys(uint32_t attrID, Vector<String16>* outKeys); 204 virtual bool getAttributeEnum(uint32_t attrID, 205 const char16_t* name, size_t nameLen, 206 Res_value* outValue); 207 virtual bool getAttributeFlags(uint32_t attrID, 208 const char16_t* name, size_t nameLen, 209 Res_value* outValue); 210 virtual uint32_t getAttributeL10N(uint32_t attrID); 211 212 virtual bool getLocalizationSetting(); 213 virtual void reportError(void* accessorCookie, const char* fmt, ...); 214 215 void setCurrentXmlPos(const SourcePos& pos) { mCurrentXmlPos = pos; } 216 217 class Item { 218 public: 219 Item() : isId(false), format(ResTable_map::TYPE_ANY), bagKeyId(0), evaluating(false) 220 { memset(&parsedValue, 0, sizeof(parsedValue)); } 221 Item(const SourcePos& pos, 222 bool _isId, 223 const String16& _value, 224 const Vector<StringPool::entry_style_span>* _style = NULL, 225 int32_t format = ResTable_map::TYPE_ANY); 226 Item(const Item& o) : sourcePos(o.sourcePos), 227 isId(o.isId), value(o.value), style(o.style), 228 format(o.format), bagKeyId(o.bagKeyId), evaluating(false) { 229 memset(&parsedValue, 0, sizeof(parsedValue)); 230 } 231 ~Item() { } 232 233 Item& operator=(const Item& o) { 234 sourcePos = o.sourcePos; 235 isId = o.isId; 236 value = o.value; 237 style = o.style; 238 format = o.format; 239 bagKeyId = o.bagKeyId; 240 parsedValue = o.parsedValue; 241 return *this; 242 } 243 244 SourcePos sourcePos; 245 mutable bool isId; 246 String16 value; 247 Vector<StringPool::entry_style_span> style; 248 int32_t format; 249 uint32_t bagKeyId; 250 mutable bool evaluating; 251 Res_value parsedValue; 252 }; 253 254 class Entry : public RefBase { 255 public: 256 Entry(const String16& name, const SourcePos& pos) 257 : mName(name), mType(TYPE_UNKNOWN), 258 mItemFormat(ResTable_map::TYPE_ANY), mNameIndex(-1), mPos(pos) 259 { } 260 virtual ~Entry() { } 261 262 enum type { 263 TYPE_UNKNOWN = 0, 264 TYPE_ITEM, 265 TYPE_BAG 266 }; 267 268 String16 getName() const { return mName; } 269 type getType() const { return mType; } 270 271 void setParent(const String16& parent) { mParent = parent; } 272 String16 getParent() const { return mParent; } 273 274 status_t makeItABag(const SourcePos& sourcePos); 275 276 status_t emptyBag(const SourcePos& sourcePos); 277 278 status_t setItem(const SourcePos& pos, 279 const String16& value, 280 const Vector<StringPool::entry_style_span>* style = NULL, 281 int32_t format = ResTable_map::TYPE_ANY, 282 const bool overwrite = false); 283 284 status_t addToBag(const SourcePos& pos, 285 const String16& key, const String16& value, 286 const Vector<StringPool::entry_style_span>* style = NULL, 287 bool replace=false, bool isId = false, 288 int32_t format = ResTable_map::TYPE_ANY); 289 290 // Index of the entry's name string in the key pool. 291 int32_t getNameIndex() const { return mNameIndex; } 292 void setNameIndex(int32_t index) { mNameIndex = index; } 293 294 const Item* getItem() const { return mType == TYPE_ITEM ? &mItem : NULL; } 295 const KeyedVector<String16, Item>& getBag() const { return mBag; } 296 297 status_t generateAttributes(ResourceTable* table, 298 const String16& package); 299 300 status_t assignResourceIds(ResourceTable* table, 301 const String16& package); 302 303 status_t prepareFlatten(StringPool* strings, ResourceTable* table); 304 305 ssize_t flatten(Bundle*, const sp<AaptFile>& data, bool isPublic); 306 307 const SourcePos& getPos() const { return mPos; } 308 309 private: 310 String16 mName; 311 String16 mParent; 312 type mType; 313 Item mItem; 314 int32_t mItemFormat; 315 KeyedVector<String16, Item> mBag; 316 int32_t mNameIndex; 317 uint32_t mParentId; 318 SourcePos mPos; 319 }; 320 321 struct ConfigDescription : public ResTable_config { 322 ConfigDescription() { 323 memset(this, 0, sizeof(*this)); 324 size = sizeof(ResTable_config); 325 } 326 ConfigDescription(const ResTable_config&o) { 327 *static_cast<ResTable_config*>(this) = o; 328 size = sizeof(ResTable_config); 329 } 330 ConfigDescription(const ConfigDescription&o) { 331 *static_cast<ResTable_config*>(this) = o; 332 } 333 334 ConfigDescription& operator=(const ResTable_config& o) { 335 *static_cast<ResTable_config*>(this) = o; 336 size = sizeof(ResTable_config); 337 return *this; 338 } 339 ConfigDescription& operator=(const ConfigDescription& o) { 340 *static_cast<ResTable_config*>(this) = o; 341 return *this; 342 } 343 344 inline bool operator<(const ConfigDescription& o) const { return compare(o) < 0; } 345 inline bool operator<=(const ConfigDescription& o) const { return compare(o) <= 0; } 346 inline bool operator==(const ConfigDescription& o) const { return compare(o) == 0; } 347 inline bool operator!=(const ConfigDescription& o) const { return compare(o) != 0; } 348 inline bool operator>=(const ConfigDescription& o) const { return compare(o) >= 0; } 349 inline bool operator>(const ConfigDescription& o) const { return compare(o) > 0; } 350 }; 351 352 class ConfigList : public RefBase { 353 public: 354 ConfigList(const String16& name, const SourcePos& pos) 355 : mName(name), mPos(pos), mPublic(false), mEntryIndex(-1) { } 356 virtual ~ConfigList() { } 357 358 String16 getName() const { return mName; } 359 const SourcePos& getPos() const { return mPos; } 360 361 void appendComment(const String16& comment, bool onlyIfEmpty = false); 362 const String16& getComment() const { return mComment; } 363 364 void appendTypeComment(const String16& comment); 365 const String16& getTypeComment() const { return mTypeComment; } 366 367 // Index of this entry in its Type. 368 int32_t getEntryIndex() const { return mEntryIndex; } 369 void setEntryIndex(int32_t index) { mEntryIndex = index; } 370 371 void setPublic(bool pub) { mPublic = pub; } 372 bool getPublic() const { return mPublic; } 373 void setPublicSourcePos(const SourcePos& pos) { mPublicSourcePos = pos; } 374 const SourcePos& getPublicSourcePos() { return mPublicSourcePos; } 375 376 void addEntry(const ResTable_config& config, const sp<Entry>& entry) { 377 mEntries.add(config, entry); 378 } 379 380 const DefaultKeyedVector<ConfigDescription, sp<Entry> >& getEntries() const { return mEntries; } 381 private: 382 const String16 mName; 383 const SourcePos mPos; 384 String16 mComment; 385 String16 mTypeComment; 386 bool mPublic; 387 SourcePos mPublicSourcePos; 388 int32_t mEntryIndex; 389 DefaultKeyedVector<ConfigDescription, sp<Entry> > mEntries; 390 }; 391 392 class Public { 393 public: 394 Public() : sourcePos(), ident(0) { } 395 Public(const SourcePos& pos, 396 const String16& _comment, 397 uint32_t _ident) 398 : sourcePos(pos), 399 comment(_comment), ident(_ident) { } 400 Public(const Public& o) : sourcePos(o.sourcePos), 401 comment(o.comment), ident(o.ident) { } 402 ~Public() { } 403 404 Public& operator=(const Public& o) { 405 sourcePos = o.sourcePos; 406 comment = o.comment; 407 ident = o.ident; 408 return *this; 409 } 410 411 SourcePos sourcePos; 412 String16 comment; 413 uint32_t ident; 414 }; 415 416 class Type : public RefBase { 417 public: 418 Type(const String16& name, const SourcePos& pos) 419 : mName(name), mFirstPublicSourcePos(NULL), mPublicIndex(-1), mIndex(-1), mPos(pos) 420 { } 421 virtual ~Type() { delete mFirstPublicSourcePos; } 422 423 status_t addPublic(const SourcePos& pos, 424 const String16& name, 425 const uint32_t ident); 426 427 void canAddEntry(const String16& name); 428 429 String16 getName() const { return mName; } 430 sp<Entry> getEntry(const String16& entry, 431 const SourcePos& pos, 432 const ResTable_config* config = NULL, 433 bool doSetIndex = false, 434 bool overlay = false, 435 bool autoAddOverlay = false); 436 437 const SourcePos& getFirstPublicSourcePos() const { return *mFirstPublicSourcePos; } 438 439 int32_t getPublicIndex() const { return mPublicIndex; } 440 441 int32_t getIndex() const { return mIndex; } 442 void setIndex(int32_t index) { mIndex = index; } 443 444 status_t applyPublicEntryOrder(); 445 446 const SortedVector<ConfigDescription>& getUniqueConfigs() const { return mUniqueConfigs; } 447 448 const DefaultKeyedVector<String16, sp<ConfigList> >& getConfigs() const { return mConfigs; } 449 const Vector<sp<ConfigList> >& getOrderedConfigs() const { return mOrderedConfigs; } 450 451 const SortedVector<String16>& getCanAddEntries() const { return mCanAddEntries; } 452 453 const SourcePos& getPos() const { return mPos; } 454 private: 455 String16 mName; 456 SourcePos* mFirstPublicSourcePos; 457 DefaultKeyedVector<String16, Public> mPublic; 458 SortedVector<ConfigDescription> mUniqueConfigs; 459 DefaultKeyedVector<String16, sp<ConfigList> > mConfigs; 460 Vector<sp<ConfigList> > mOrderedConfigs; 461 SortedVector<String16> mCanAddEntries; 462 int32_t mPublicIndex; 463 int32_t mIndex; 464 SourcePos mPos; 465 }; 466 467 class Package : public RefBase { 468 public: 469 Package(const String16& name, ssize_t includedId=-1); 470 virtual ~Package() { } 471 472 String16 getName() const { return mName; } 473 sp<Type> getType(const String16& type, 474 const SourcePos& pos, 475 bool doSetIndex = false); 476 477 ssize_t getAssignedId() const { return mIncludedId; } 478 479 const ResStringPool& getTypeStrings() const { return mTypeStrings; } 480 uint32_t indexOfTypeString(const String16& s) const { return mTypeStringsMapping.valueFor(s); } 481 const sp<AaptFile> getTypeStringsData() const { return mTypeStringsData; } 482 status_t setTypeStrings(const sp<AaptFile>& data); 483 484 const ResStringPool& getKeyStrings() const { return mKeyStrings; } 485 uint32_t indexOfKeyString(const String16& s) const { return mKeyStringsMapping.valueFor(s); } 486 const sp<AaptFile> getKeyStringsData() const { return mKeyStringsData; } 487 status_t setKeyStrings(const sp<AaptFile>& data); 488 489 status_t applyPublicTypeOrder(); 490 491 const DefaultKeyedVector<String16, sp<Type> >& getTypes() const { return mTypes; } 492 const Vector<sp<Type> >& getOrderedTypes() const { return mOrderedTypes; } 493 494 private: 495 status_t setStrings(const sp<AaptFile>& data, 496 ResStringPool* strings, 497 DefaultKeyedVector<String16, uint32_t>* mappings); 498 499 const String16 mName; 500 const ssize_t mIncludedId; 501 DefaultKeyedVector<String16, sp<Type> > mTypes; 502 Vector<sp<Type> > mOrderedTypes; 503 sp<AaptFile> mTypeStringsData; 504 sp<AaptFile> mKeyStringsData; 505 ResStringPool mTypeStrings; 506 ResStringPool mKeyStrings; 507 DefaultKeyedVector<String16, uint32_t> mTypeStringsMapping; 508 DefaultKeyedVector<String16, uint32_t> mKeyStringsMapping; 509 }; 510 511 private: 512 void writePublicDefinitions(const String16& package, FILE* fp, bool pub); 513 sp<Package> getPackage(const String16& package); 514 sp<Type> getType(const String16& package, 515 const String16& type, 516 const SourcePos& pos, 517 bool doSetIndex = false); 518 sp<Entry> getEntry(const String16& package, 519 const String16& type, 520 const String16& name, 521 const SourcePos& pos, 522 bool overlay, 523 const ResTable_config* config = NULL, 524 bool doSetIndex = false); 525 sp<const Entry> getEntry(uint32_t resID, 526 const ResTable_config* config = NULL) const; 527 const Item* getItem(uint32_t resID, uint32_t attrID) const; 528 bool getItemValue(uint32_t resID, uint32_t attrID, 529 Res_value* outValue); 530 531 532 String16 mAssetsPackage; 533 sp<AaptAssets> mAssets; 534 DefaultKeyedVector<String16, sp<Package> > mPackages; 535 Vector<sp<Package> > mOrderedPackages; 536 uint32_t mNextPackageId; 537 bool mHaveAppPackage; 538 bool mIsAppPackage; 539 size_t mNumLocal; 540 SourcePos mCurrentXmlPos; 541 Bundle* mBundle; 542 543 // key = string resource name, value = set of locales in which that name is defined 544 map<String16, set<String8> > mLocalizations; 545 }; 546 547 class ResourceFilter 548 { 549 public: 550 ResourceFilter() : mData(), mContainsPseudo(false) {} 551 status_t parse(const char* arg); 552 bool match(int axis, uint32_t value); 553 bool match(const ResTable_config& config); 554 inline bool containsPseudo() { return mContainsPseudo; } 555 556 private: 557 KeyedVector<int,SortedVector<uint32_t> > mData; 558 bool mContainsPseudo; 559 }; 560 561 562 #endif 563