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