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