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