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