AaptAssets.h revision 93e462b79d6896da10e15e74c5aec6beb098dddf
1// 2// Copyright 2006 The Android Open Source Project 3// 4// Information about assets being operated on. 5// 6#ifndef __AAPT_ASSETS_H 7#define __AAPT_ASSETS_H 8 9#include <stdlib.h> 10#include <utils/AssetManager.h> 11#include <utils/KeyedVector.h> 12#include <utils/String8.h> 13#include <utils/ResourceTypes.h> 14#include <utils/SortedVector.h> 15#include <utils/String8.h> 16#include <utils/Vector.h> 17#include <utils/RefBase.h> 18#include "ZipFile.h" 19 20#include "Bundle.h" 21#include "SourcePos.h" 22 23using namespace android; 24 25bool valid_symbol_name(const String8& str); 26 27enum { 28 AXIS_NONE = 0, 29 AXIS_MCC = 1, 30 AXIS_MNC, 31 AXIS_LANGUAGE, 32 AXIS_REGION, 33 AXIS_SCREENLAYOUTSIZE, 34 AXIS_SCREENLAYOUTLONG, 35 AXIS_ORIENTATION, 36 AXIS_DENSITY, 37 AXIS_TOUCHSCREEN, 38 AXIS_KEYSHIDDEN, 39 AXIS_KEYBOARD, 40 AXIS_NAVHIDDEN, 41 AXIS_NAVIGATION, 42 AXIS_SCREENSIZE, 43 AXIS_VERSION 44}; 45 46/** 47 * This structure contains a specific variation of a single file out 48 * of all the variations it can have that we can have. 49 */ 50struct AaptGroupEntry 51{ 52public: 53 AaptGroupEntry() { } 54 AaptGroupEntry(const String8& _locale, const String8& _vendor) 55 : locale(_locale), vendor(_vendor) { } 56 57 String8 mcc; 58 String8 mnc; 59 String8 locale; 60 String8 vendor; 61 String8 screenLayoutSize; 62 String8 screenLayoutLong; 63 String8 orientation; 64 String8 density; 65 String8 touchscreen; 66 String8 keysHidden; 67 String8 keyboard; 68 String8 navHidden; 69 String8 navigation; 70 String8 screenSize; 71 String8 version; 72 73 bool initFromDirName(const char* dir, String8* resType); 74 75 static status_t parseNamePart(const String8& part, int* axis, uint32_t* value); 76 77 static bool getMccName(const char* name, ResTable_config* out = NULL); 78 static bool getMncName(const char* name, ResTable_config* out = NULL); 79 static bool getLocaleName(const char* name, ResTable_config* out = NULL); 80 static bool getScreenLayoutSizeName(const char* name, ResTable_config* out = NULL); 81 static bool getScreenLayoutLongName(const char* name, ResTable_config* out = NULL); 82 static bool getOrientationName(const char* name, ResTable_config* out = NULL); 83 static bool getDensityName(const char* name, ResTable_config* out = NULL); 84 static bool getTouchscreenName(const char* name, ResTable_config* out = NULL); 85 static bool getKeysHiddenName(const char* name, ResTable_config* out = NULL); 86 static bool getKeyboardName(const char* name, ResTable_config* out = NULL); 87 static bool getNavigationName(const char* name, ResTable_config* out = NULL); 88 static bool getNavHiddenName(const char* name, ResTable_config* out = NULL); 89 static bool getScreenSizeName(const char* name, ResTable_config* out = NULL); 90 static bool getVersionName(const char* name, ResTable_config* out = NULL); 91 92 int compare(const AaptGroupEntry& o) const; 93 94 ResTable_config toParams() const; 95 96 inline bool operator<(const AaptGroupEntry& o) const { return compare(o) < 0; } 97 inline bool operator<=(const AaptGroupEntry& o) const { return compare(o) <= 0; } 98 inline bool operator==(const AaptGroupEntry& o) const { return compare(o) == 0; } 99 inline bool operator!=(const AaptGroupEntry& o) const { return compare(o) != 0; } 100 inline bool operator>=(const AaptGroupEntry& o) const { return compare(o) >= 0; } 101 inline bool operator>(const AaptGroupEntry& o) const { return compare(o) > 0; } 102 103 String8 toString() const; 104 String8 toDirName(const String8& resType) const; 105}; 106 107inline int compare_type(const AaptGroupEntry& lhs, const AaptGroupEntry& rhs) 108{ 109 return lhs.compare(rhs); 110} 111 112inline int strictly_order_type(const AaptGroupEntry& lhs, const AaptGroupEntry& rhs) 113{ 114 return compare_type(lhs, rhs) < 0; 115} 116 117class AaptGroup; 118 119/** 120 * A single asset file we know about. 121 */ 122class AaptFile : public RefBase 123{ 124public: 125 AaptFile(const String8& sourceFile, const AaptGroupEntry& groupEntry, 126 const String8& resType) 127 : mGroupEntry(groupEntry) 128 , mResourceType(resType) 129 , mSourceFile(sourceFile) 130 , mData(NULL) 131 , mDataSize(0) 132 , mBufferSize(0) 133 , mCompression(ZipEntry::kCompressStored) 134 { 135 //printf("new AaptFile created %s\n", (const char*)sourceFile); 136 } 137 virtual ~AaptFile() { 138 free(mData); 139 } 140 141 const String8& getPath() const { return mPath; } 142 const AaptGroupEntry& getGroupEntry() const { return mGroupEntry; } 143 144 // Data API. If there is data attached to the file, 145 // getSourceFile() is not used. 146 bool hasData() const { return mData != NULL; } 147 const void* getData() const { return mData; } 148 size_t getSize() const { return mDataSize; } 149 void* editData(size_t size); 150 void* editData(size_t* outSize = NULL); 151 void* padData(size_t wordSize); 152 status_t writeData(const void* data, size_t size); 153 void clearData(); 154 155 const String8& getResourceType() const { return mResourceType; } 156 157 // File API. If the file does not hold raw data, this is 158 // a full path to a file on the filesystem that holds its data. 159 const String8& getSourceFile() const { return mSourceFile; } 160 161 String8 getPrintableSource() const; 162 163 // Desired compression method, as per utils/ZipEntry.h. For example, 164 // no compression is ZipEntry::kCompressStored. 165 int getCompressionMethod() const { return mCompression; } 166 void setCompressionMethod(int c) { mCompression = c; } 167private: 168 friend class AaptGroup; 169 170 String8 mPath; 171 AaptGroupEntry mGroupEntry; 172 String8 mResourceType; 173 String8 mSourceFile; 174 void* mData; 175 size_t mDataSize; 176 size_t mBufferSize; 177 int mCompression; 178}; 179 180/** 181 * A group of related files (the same file, with different 182 * vendor/locale variations). 183 */ 184class AaptGroup : public RefBase 185{ 186public: 187 AaptGroup(const String8& leaf, const String8& path) 188 : mLeaf(leaf), mPath(path) { } 189 virtual ~AaptGroup() { } 190 191 const String8& getLeaf() const { return mLeaf; } 192 193 // Returns the relative path after the AaptGroupEntry dirs. 194 const String8& getPath() const { return mPath; } 195 196 const DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> >& getFiles() const 197 { return mFiles; } 198 199 status_t addFile(const sp<AaptFile>& file); 200 void removeFile(size_t index); 201 202 void print() const; 203 204 String8 getPrintableSource() const; 205 206private: 207 String8 mLeaf; 208 String8 mPath; 209 210 DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > mFiles; 211}; 212 213/** 214 * A single directory of assets, which can contain for files and other 215 * sub-directories. 216 */ 217class AaptDir : public RefBase 218{ 219public: 220 AaptDir(const String8& leaf, const String8& path) 221 : mLeaf(leaf), mPath(path) { } 222 virtual ~AaptDir() { } 223 224 const String8& getLeaf() const { return mLeaf; } 225 226 const String8& getPath() const { return mPath; } 227 228 const DefaultKeyedVector<String8, sp<AaptGroup> >& getFiles() const { return mFiles; } 229 const DefaultKeyedVector<String8, sp<AaptDir> >& getDirs() const { return mDirs; } 230 231 status_t addFile(const String8& name, const sp<AaptGroup>& file); 232 status_t addDir(const String8& name, const sp<AaptDir>& dir); 233 234 sp<AaptDir> makeDir(const String8& name); 235 236 void removeFile(const String8& name); 237 void removeDir(const String8& name); 238 239 status_t renameFile(const sp<AaptFile>& file, const String8& newName); 240 241 status_t addLeafFile(const String8& leafName, 242 const sp<AaptFile>& file); 243 244 virtual ssize_t slurpFullTree(Bundle* bundle, 245 const String8& srcDir, 246 const AaptGroupEntry& kind, 247 const String8& resType); 248 249 /* 250 * Perform some sanity checks on the names of files and directories here. 251 * In particular: 252 * - Check for illegal chars in filenames. 253 * - Check filename length. 254 * - Check for presence of ".gz" and non-".gz" copies of same file. 255 * - Check for multiple files whose names match in a case-insensitive 256 * fashion (problematic for some systems). 257 * 258 * Comparing names against all other names is O(n^2). We could speed 259 * it up some by sorting the entries and being smarter about what we 260 * compare against, but I'm not expecting to have enough files in a 261 * single directory to make a noticeable difference in speed. 262 * 263 * Note that sorting here is not enough to guarantee that the package 264 * contents are sorted -- subsequent updates can rearrange things. 265 */ 266 status_t validate() const; 267 268 void print() const; 269 270 String8 getPrintableSource() const; 271 272private: 273 String8 mLeaf; 274 String8 mPath; 275 276 DefaultKeyedVector<String8, sp<AaptGroup> > mFiles; 277 DefaultKeyedVector<String8, sp<AaptDir> > mDirs; 278}; 279 280/** 281 * All information we know about a particular symbol. 282 */ 283class AaptSymbolEntry 284{ 285public: 286 AaptSymbolEntry() 287 : isPublic(false), typeCode(TYPE_UNKNOWN) 288 { 289 } 290 AaptSymbolEntry(const String8& _name) 291 : name(_name), isPublic(false), typeCode(TYPE_UNKNOWN) 292 { 293 } 294 AaptSymbolEntry(const AaptSymbolEntry& o) 295 : name(o.name), sourcePos(o.sourcePos), isPublic(o.isPublic) 296 , comment(o.comment), typeComment(o.typeComment) 297 , typeCode(o.typeCode), int32Val(o.int32Val), stringVal(o.stringVal) 298 { 299 } 300 AaptSymbolEntry operator=(const AaptSymbolEntry& o) 301 { 302 sourcePos = o.sourcePos; 303 isPublic = o.isPublic; 304 comment = o.comment; 305 typeComment = o.typeComment; 306 typeCode = o.typeCode; 307 int32Val = o.int32Val; 308 stringVal = o.stringVal; 309 return *this; 310 } 311 312 const String8 name; 313 314 SourcePos sourcePos; 315 bool isPublic; 316 317 String16 comment; 318 String16 typeComment; 319 320 enum { 321 TYPE_UNKNOWN = 0, 322 TYPE_INT32, 323 TYPE_STRING 324 }; 325 326 int typeCode; 327 328 // Value. May be one of these. 329 int32_t int32Val; 330 String8 stringVal; 331}; 332 333/** 334 * A group of related symbols (such as indices into a string block) 335 * that have been generated from the assets. 336 */ 337class AaptSymbols : public RefBase 338{ 339public: 340 AaptSymbols() { } 341 virtual ~AaptSymbols() { } 342 343 status_t addSymbol(const String8& name, int32_t value, const SourcePos& pos) { 344 if (!check_valid_symbol_name(name, pos, "symbol")) { 345 return BAD_VALUE; 346 } 347 AaptSymbolEntry& sym = edit_symbol(name, &pos); 348 sym.typeCode = AaptSymbolEntry::TYPE_INT32; 349 sym.int32Val = value; 350 return NO_ERROR; 351 } 352 353 status_t addStringSymbol(const String8& name, const String8& value, 354 const SourcePos& pos) { 355 if (!check_valid_symbol_name(name, pos, "symbol")) { 356 return BAD_VALUE; 357 } 358 AaptSymbolEntry& sym = edit_symbol(name, &pos); 359 sym.typeCode = AaptSymbolEntry::TYPE_STRING; 360 sym.stringVal = value; 361 return NO_ERROR; 362 } 363 364 status_t makeSymbolPublic(const String8& name, const SourcePos& pos) { 365 if (!check_valid_symbol_name(name, pos, "symbol")) { 366 return BAD_VALUE; 367 } 368 AaptSymbolEntry& sym = edit_symbol(name, &pos); 369 sym.isPublic = true; 370 return NO_ERROR; 371 } 372 373 void appendComment(const String8& name, const String16& comment, const SourcePos& pos) { 374 if (comment.size() <= 0) { 375 return; 376 } 377 AaptSymbolEntry& sym = edit_symbol(name, &pos); 378 if (sym.comment.size() == 0) { 379 sym.comment = comment; 380 } else { 381 sym.comment.append(String16("\n")); 382 sym.comment.append(comment); 383 } 384 } 385 386 void appendTypeComment(const String8& name, const String16& comment) { 387 if (comment.size() <= 0) { 388 return; 389 } 390 AaptSymbolEntry& sym = edit_symbol(name, NULL); 391 if (sym.typeComment.size() == 0) { 392 sym.typeComment = comment; 393 } else { 394 sym.typeComment.append(String16("\n")); 395 sym.typeComment.append(comment); 396 } 397 } 398 399 sp<AaptSymbols> addNestedSymbol(const String8& name, const SourcePos& pos) { 400 if (!check_valid_symbol_name(name, pos, "nested symbol")) { 401 return NULL; 402 } 403 404 sp<AaptSymbols> sym = mNestedSymbols.valueFor(name); 405 if (sym == NULL) { 406 sym = new AaptSymbols(); 407 mNestedSymbols.add(name, sym); 408 } 409 410 return sym; 411 } 412 413 const KeyedVector<String8, AaptSymbolEntry>& getSymbols() const 414 { return mSymbols; } 415 const DefaultKeyedVector<String8, sp<AaptSymbols> >& getNestedSymbols() const 416 { return mNestedSymbols; } 417 418 const String16& getComment(const String8& name) const 419 { return get_symbol(name).comment; } 420 const String16& getTypeComment(const String8& name) const 421 { return get_symbol(name).typeComment; } 422 423private: 424 bool check_valid_symbol_name(const String8& symbol, const SourcePos& pos, const char* label) { 425 if (valid_symbol_name(symbol)) { 426 return true; 427 } 428 pos.error("invalid %s: '%s'\n", label, symbol.string()); 429 return false; 430 } 431 AaptSymbolEntry& edit_symbol(const String8& symbol, const SourcePos* pos) { 432 ssize_t i = mSymbols.indexOfKey(symbol); 433 if (i < 0) { 434 i = mSymbols.add(symbol, AaptSymbolEntry(symbol)); 435 } 436 AaptSymbolEntry& sym = mSymbols.editValueAt(i); 437 if (pos != NULL && sym.sourcePos.line < 0) { 438 sym.sourcePos = *pos; 439 } 440 return sym; 441 } 442 const AaptSymbolEntry& get_symbol(const String8& symbol) const { 443 ssize_t i = mSymbols.indexOfKey(symbol); 444 if (i >= 0) { 445 return mSymbols.valueAt(i); 446 } 447 return mDefSymbol; 448 } 449 450 KeyedVector<String8, AaptSymbolEntry> mSymbols; 451 DefaultKeyedVector<String8, sp<AaptSymbols> > mNestedSymbols; 452 AaptSymbolEntry mDefSymbol; 453}; 454 455class ResourceTypeSet : public RefBase, 456 public KeyedVector<String8,sp<AaptGroup> > 457{ 458public: 459 ResourceTypeSet(); 460}; 461 462 463/** 464 * Asset hierarchy being operated on. 465 */ 466class AaptAssets : public AaptDir 467{ 468public: 469 AaptAssets() : AaptDir(String8(), String8()), mHaveIncludedAssets(false), mRes(NULL) { } 470 virtual ~AaptAssets() { delete mRes; } 471 472 const String8& getPackage() const { return mPackage; } 473 void setPackage(const String8& package) { mPackage = package; mSymbolsPrivatePackage = package; } 474 475 const SortedVector<AaptGroupEntry>& getGroupEntries() const { return mGroupEntries; } 476 477 sp<AaptFile> addFile(const String8& filePath, 478 const AaptGroupEntry& entry, 479 const String8& srcDir, 480 sp<AaptGroup>* outGroup, 481 const String8& resType); 482 483 void addResource(const String8& leafName, 484 const String8& path, 485 const sp<AaptFile>& file, 486 const String8& resType); 487 488 void addGroupEntry(const AaptGroupEntry& entry) { mGroupEntries.add(entry); } 489 490 ssize_t slurpFromArgs(Bundle* bundle); 491 492 virtual ssize_t slurpFullTree(Bundle* bundle, 493 const String8& srcDir, 494 const AaptGroupEntry& kind, 495 const String8& resType); 496 497 ssize_t slurpResourceTree(Bundle* bundle, const String8& srcDir); 498 ssize_t slurpResourceZip(Bundle* bundle, const char* filename); 499 500 sp<AaptSymbols> getSymbolsFor(const String8& name); 501 502 const DefaultKeyedVector<String8, sp<AaptSymbols> >& getSymbols() const { return mSymbols; } 503 504 String8 getSymbolsPrivatePackage() const { return mSymbolsPrivatePackage; } 505 void setSymbolsPrivatePackage(const String8& pkg) { mSymbolsPrivatePackage = pkg; } 506 507 status_t buildIncludedResources(Bundle* bundle); 508 status_t addIncludedResources(const sp<AaptFile>& file); 509 const ResTable& getIncludedResources() const; 510 511 void print() const; 512 513 inline const Vector<sp<AaptDir> >& resDirs() { return mDirs; } 514 sp<AaptDir> resDir(const String8& name); 515 516 inline sp<AaptAssets> getOverlay() { return mOverlay; } 517 inline void setOverlay(sp<AaptAssets>& overlay) { mOverlay = overlay; } 518 519 inline KeyedVector<String8, sp<ResourceTypeSet> >* getResources() { return mRes; } 520 inline void 521 setResources(KeyedVector<String8, sp<ResourceTypeSet> >* res) { delete mRes; mRes = res; } 522 523private: 524 String8 mPackage; 525 SortedVector<AaptGroupEntry> mGroupEntries; 526 DefaultKeyedVector<String8, sp<AaptSymbols> > mSymbols; 527 String8 mSymbolsPrivatePackage; 528 529 Vector<sp<AaptDir> > mDirs; 530 531 bool mHaveIncludedAssets; 532 AssetManager mIncludedAssets; 533 534 sp<AaptAssets> mOverlay; 535 KeyedVector<String8, sp<ResourceTypeSet> >* mRes; 536}; 537 538#endif // __AAPT_ASSETS_H 539 540