ResourceTable.h revision 833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1
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 sp<AaptFile> flatten(Bundle* bundle, const sp<const ResourceFilter>& filter); 169 170 static inline uint32_t makeResId(uint32_t packageId, 171 uint32_t typeId, 172 uint32_t nameId) 173 { 174 return nameId | (typeId<<16) | (packageId<<24); 175 } 176 177 static inline uint32_t getResId(const sp<Package>& p, 178 const sp<Type>& t, 179 uint32_t nameId); 180 181 uint32_t getResId(const String16& package, 182 const String16& type, 183 const String16& name, 184 bool onlyPublic = true) const; 185 186 uint32_t getResId(const String16& ref, 187 const String16* defType = NULL, 188 const String16* defPackage = NULL, 189 const char** outErrorMsg = NULL, 190 bool onlyPublic = true) const; 191 192 static bool isValidResourceName(const String16& s); 193 194 bool stringToValue(Res_value* outValue, StringPool* pool, 195 const String16& str, 196 bool preserveSpaces, bool coerceType, 197 uint32_t attrID, 198 const Vector<StringPool::entry_style_span>* style = NULL, 199 String16* outStr = NULL, void* accessorCookie = NULL, 200 uint32_t attrType = ResTable_map::TYPE_ANY, 201 const String8* configTypeName = NULL, 202 const ConfigDescription* config = NULL); 203 204 status_t assignResourceIds(); 205 status_t addSymbols(const sp<AaptSymbols>& outSymbols = NULL); 206 void addLocalization(const String16& name, const String8& locale, const SourcePos& src); 207 status_t validateLocalizations(void); 208 209 status_t flatten(Bundle* bundle, const sp<const ResourceFilter>& filter, const sp<AaptFile>& dest); 210 status_t flattenLibraryTable(const sp<AaptFile>& dest, const Vector<sp<Package> >& libs); 211 212 void writePublicDefinitions(const String16& package, FILE* fp); 213 214 virtual uint32_t getCustomResource(const String16& package, 215 const String16& type, 216 const String16& name) const; 217 virtual uint32_t getCustomResourceWithCreation(const String16& package, 218 const String16& type, 219 const String16& name, 220 const bool createIfNeeded); 221 virtual uint32_t getRemappedPackage(uint32_t origPackage) const; 222 virtual bool getAttributeType(uint32_t attrID, uint32_t* outType); 223 virtual bool getAttributeMin(uint32_t attrID, uint32_t* outMin); 224 virtual bool getAttributeMax(uint32_t attrID, uint32_t* outMax); 225 virtual bool getAttributeKeys(uint32_t attrID, Vector<String16>* outKeys); 226 virtual bool getAttributeEnum(uint32_t attrID, 227 const char16_t* name, size_t nameLen, 228 Res_value* outValue); 229 virtual bool getAttributeFlags(uint32_t attrID, 230 const char16_t* name, size_t nameLen, 231 Res_value* outValue); 232 virtual uint32_t getAttributeL10N(uint32_t attrID); 233 234 virtual bool getLocalizationSetting(); 235 virtual void reportError(void* accessorCookie, const char* fmt, ...); 236 237 void setCurrentXmlPos(const SourcePos& pos) { mCurrentXmlPos = pos; } 238 239 class Item { 240 public: 241 Item() : isId(false), format(ResTable_map::TYPE_ANY), bagKeyId(0), evaluating(false) 242 { memset(&parsedValue, 0, sizeof(parsedValue)); } 243 Item(const SourcePos& pos, 244 bool _isId, 245 const String16& _value, 246 const Vector<StringPool::entry_style_span>* _style = NULL, 247 int32_t format = ResTable_map::TYPE_ANY); 248 Item(const Item& o) : sourcePos(o.sourcePos), 249 isId(o.isId), value(o.value), style(o.style), 250 format(o.format), bagKeyId(o.bagKeyId), evaluating(false) { 251 memset(&parsedValue, 0, sizeof(parsedValue)); 252 } 253 ~Item() { } 254 255 Item& operator=(const Item& o) { 256 sourcePos = o.sourcePos; 257 isId = o.isId; 258 value = o.value; 259 style = o.style; 260 format = o.format; 261 bagKeyId = o.bagKeyId; 262 parsedValue = o.parsedValue; 263 return *this; 264 } 265 266 SourcePos sourcePos; 267 mutable bool isId; 268 String16 value; 269 Vector<StringPool::entry_style_span> style; 270 int32_t format; 271 uint32_t bagKeyId; 272 mutable bool evaluating; 273 Res_value parsedValue; 274 }; 275 276 class Entry : public RefBase { 277 public: 278 Entry(const String16& name, const SourcePos& pos) 279 : mName(name), mType(TYPE_UNKNOWN), 280 mItemFormat(ResTable_map::TYPE_ANY), mNameIndex(-1), mPos(pos) 281 { } 282 virtual ~Entry() { } 283 284 enum type { 285 TYPE_UNKNOWN = 0, 286 TYPE_ITEM, 287 TYPE_BAG 288 }; 289 290 String16 getName() const { return mName; } 291 type getType() const { return mType; } 292 293 void setParent(const String16& parent) { mParent = parent; } 294 String16 getParent() const { return mParent; } 295 296 status_t makeItABag(const SourcePos& sourcePos); 297 298 status_t emptyBag(const SourcePos& sourcePos); 299 300 status_t setItem(const SourcePos& pos, 301 const String16& value, 302 const Vector<StringPool::entry_style_span>* style = NULL, 303 int32_t format = ResTable_map::TYPE_ANY, 304 const bool overwrite = false); 305 306 status_t addToBag(const SourcePos& pos, 307 const String16& key, const String16& value, 308 const Vector<StringPool::entry_style_span>* style = NULL, 309 bool replace=false, bool isId = false, 310 int32_t format = ResTable_map::TYPE_ANY); 311 312 // Index of the entry's name string in the key pool. 313 int32_t getNameIndex() const { return mNameIndex; } 314 void setNameIndex(int32_t index) { mNameIndex = index; } 315 316 const Item* getItem() const { return mType == TYPE_ITEM ? &mItem : NULL; } 317 const KeyedVector<String16, Item>& getBag() const { return mBag; } 318 319 status_t generateAttributes(ResourceTable* table, 320 const String16& package); 321 322 status_t assignResourceIds(ResourceTable* table, 323 const String16& package); 324 325 status_t prepareFlatten(StringPool* strings, ResourceTable* table, 326 const String8* configTypeName, const ConfigDescription* config); 327 328 status_t remapStringValue(StringPool* strings); 329 330 ssize_t flatten(Bundle*, const sp<AaptFile>& data, bool isPublic); 331 332 const SourcePos& getPos() const { return mPos; } 333 334 private: 335 String16 mName; 336 String16 mParent; 337 type mType; 338 Item mItem; 339 int32_t mItemFormat; 340 KeyedVector<String16, Item> mBag; 341 int32_t mNameIndex; 342 uint32_t mParentId; 343 SourcePos mPos; 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, size_t packageId); 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 size_t getAssignedId() const { return mPackageId; } 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 size_t mPackageId; 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 PackageType mPackageType; 528 sp<AaptAssets> mAssets; 529 uint32_t mTypeIdOffset; 530 DefaultKeyedVector<String16, sp<Package> > mPackages; 531 Vector<sp<Package> > mOrderedPackages; 532 size_t mNumLocal; 533 SourcePos mCurrentXmlPos; 534 Bundle* mBundle; 535 536 // key = string resource name, value = set of locales in which that name is defined 537 map<String16, map<String8, SourcePos> > mLocalizations; 538}; 539 540#endif 541