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