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