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