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