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