]>
git.saurik.com Git - android/aapt.git/blob - AaptAssets.cpp
2 // Copyright 2006 The Android Open Source Project
5 #include "AaptAssets.h"
8 #include <utils/misc.h>
9 #include <utils/SortedVector.h>
15 static const char* kDefaultLocale
= "default";
16 static const char* kWildcardName
= "any";
17 static const char* kAssetDir
= "assets";
18 static const char* kResourceDir
= "res";
19 static const char* kInvalidChars
= "/\\:";
20 static const size_t kMaxAssetFileName
= 100;
22 static const String8
kResString(kResourceDir
);
25 * Names of asset files must meet the following criteria:
27 * - the filename length must be less than kMaxAssetFileName bytes long
28 * (and can't be empty)
29 * - all characters must be 7-bit printable ASCII
30 * - none of { '/' '\\' ':' }
32 * Pass in just the filename, not the full path.
34 static bool validateFileName(const char* fileName
)
36 const char* cp
= fileName
;
40 if ((*cp
& 0x80) != 0)
41 return false; // reject high ASCII
42 if (*cp
< 0x20 || *cp
>= 0x7f)
43 return false; // reject control chars and 0x7f
44 if (strchr(kInvalidChars
, *cp
) != NULL
)
45 return false; // reject path sep chars
50 if (len
< 1 || len
> kMaxAssetFileName
)
51 return false; // reject empty or too long
56 static bool isHidden(const char *root
, const char *path
)
58 const char *ext
= NULL
;
59 const char *type
= NULL
;
61 // Skip all hidden files.
63 // Skip ., .. and .svn but don't chatter about it.
64 if (strcmp(path
, ".") == 0
65 || strcmp(path
, "..") == 0
66 || strcmp(path
, ".svn") == 0) {
70 } else if (path
[0] == '_') {
71 // skip directories starting with _ (don't chatter about it)
72 String8
subdirName(root
);
73 subdirName
.appendPath(path
);
74 if (getFileType(subdirName
.string()) == kFileTypeDirectory
) {
77 } else if (strcmp(path
, "CVS") == 0) {
78 // Skip CVS but don't chatter about it.
80 } else if (strcasecmp(path
, "thumbs.db") == 0
81 || strcasecmp(path
, "picasa.ini") == 0) {
82 // Skip suspected image indexes files.
84 } else if (path
[strlen(path
)-1] == '~') {
85 // Skip suspected emacs backup files.
87 } else if ((ext
= strrchr(path
, '.')) != NULL
&& strcmp(ext
, ".scc") == 0) {
88 // Skip VisualSourceSafe files and don't chatter about it
91 // Let everything else through.
95 /* If we get this far, "type" should be set and the file
98 String8
subdirName(root
);
99 subdirName
.appendPath(path
);
100 fprintf(stderr
, " (skipping %s %s '%s')\n", type
,
101 getFileType(subdirName
.string())==kFileTypeDirectory
? "dir":"file",
102 subdirName
.string());
107 // =========================================================================
108 // =========================================================================
109 // =========================================================================
112 AaptGroupEntry::parseNamePart(const String8
& part
, int* axis
, uint32_t* value
)
114 ResTable_config config
;
117 if (getMccName(part
.string(), &config
)) {
124 if (getMncName(part
.string(), &config
)) {
131 if (part
.length() == 2 && isalpha(part
[0]) && isalpha(part
[1])) {
132 *axis
= AXIS_LANGUAGE
;
133 *value
= part
[1] << 8 | part
[0];
137 // locale - language_REGION
138 if (part
.length() == 5 && isalpha(part
[0]) && isalpha(part
[1])
139 && part
[2] == '_' && isalpha(part
[3]) && isalpha(part
[4])) {
140 *axis
= AXIS_LANGUAGE
;
141 *value
= (part
[4] << 24) | (part
[3] << 16) | (part
[1] << 8) | (part
[0]);
145 // screen layout size
146 if (getScreenLayoutSizeName(part
.string(), &config
)) {
147 *axis
= AXIS_SCREENLAYOUTSIZE
;
148 *value
= (config
.screenLayout
&ResTable_config::MASK_SCREENSIZE
);
152 // screen layout long
153 if (getScreenLayoutLongName(part
.string(), &config
)) {
154 *axis
= AXIS_SCREENLAYOUTLONG
;
155 *value
= (config
.screenLayout
&ResTable_config::MASK_SCREENLONG
);
160 if (getOrientationName(part
.string(), &config
)) {
161 *axis
= AXIS_ORIENTATION
;
162 *value
= config
.orientation
;
167 if (getUiModeTypeName(part
.string(), &config
)) {
168 *axis
= AXIS_UIMODETYPE
;
169 *value
= (config
.uiMode
&ResTable_config::MASK_UI_MODE_TYPE
);
174 if (getUiModeNightName(part
.string(), &config
)) {
175 *axis
= AXIS_UIMODENIGHT
;
176 *value
= (config
.uiMode
&ResTable_config::MASK_UI_MODE_NIGHT
);
181 if (getDensityName(part
.string(), &config
)) {
182 *axis
= AXIS_DENSITY
;
183 *value
= config
.density
;
188 if (getTouchscreenName(part
.string(), &config
)) {
189 *axis
= AXIS_TOUCHSCREEN
;
190 *value
= config
.touchscreen
;
195 if (getKeysHiddenName(part
.string(), &config
)) {
196 *axis
= AXIS_KEYSHIDDEN
;
197 *value
= config
.inputFlags
;
202 if (getKeyboardName(part
.string(), &config
)) {
203 *axis
= AXIS_KEYBOARD
;
204 *value
= config
.keyboard
;
209 if (getNavHiddenName(part
.string(), &config
)) {
210 *axis
= AXIS_NAVHIDDEN
;
211 *value
= config
.inputFlags
;
216 if (getNavigationName(part
.string(), &config
)) {
217 *axis
= AXIS_NAVIGATION
;
218 *value
= config
.navigation
;
223 if (getScreenSizeName(part
.string(), &config
)) {
224 *axis
= AXIS_SCREENSIZE
;
225 *value
= config
.screenSize
;
230 if (getVersionName(part
.string(), &config
)) {
231 *axis
= AXIS_VERSION
;
232 *value
= config
.version
;
240 AaptGroupEntry::initFromDirName(const char* dir
, String8
* resType
)
242 Vector
<String8
> parts
;
244 String8 mcc
, mnc
, loc
, layoutsize
, layoutlong
, orient
, den
;
245 String8 touch
, key
, keysHidden
, nav
, navHidden
, size
, vers
;
246 String8 uiModeType
, uiModeNight
;
250 while (NULL
!= (q
= strchr(p
, '-'))) {
254 //printf("part: %s\n", parts[parts.size()-1].string());
260 //printf("part: %s\n", parts[parts.size()-1].string());
262 const int N
= parts
.size();
264 String8 part
= parts
[index
];
267 if (!isValidResourceType(part
)) {
279 if (getMccName(part
.string())) {
288 //printf("not mcc: %s\n", part.string());
292 if (getMncName(part
.string())) {
301 //printf("not mcc: %s\n", part.string());
305 if (part
.length() == 2 && isalpha(part
[0]) && isalpha(part
[1])) {
314 //printf("not language: %s\n", part.string());
319 && part
.length() == 3 && part
[0] == 'r' && part
[0] && part
[1]) {
322 loc
+= part
.string() + 1;
330 //printf("not region: %s\n", part.string());
333 if (getScreenLayoutSizeName(part
.string())) {
342 //printf("not screen layout size: %s\n", part.string());
345 if (getScreenLayoutLongName(part
.string())) {
354 //printf("not screen layout long: %s\n", part.string());
358 if (getOrientationName(part
.string())) {
367 //printf("not orientation: %s\n", part.string());
371 if (getUiModeTypeName(part
.string())) {
380 //printf("not ui mode type: %s\n", part.string());
384 if (getUiModeNightName(part
.string())) {
393 //printf("not ui mode night: %s\n", part.string());
397 if (getDensityName(part
.string())) {
406 //printf("not density: %s\n", part.string());
410 if (getTouchscreenName(part
.string())) {
419 //printf("not touchscreen: %s\n", part.string());
423 if (getKeysHiddenName(part
.string())) {
432 //printf("not keysHidden: %s\n", part.string());
436 if (getKeyboardName(part
.string())) {
445 //printf("not keyboard: %s\n", part.string());
449 if (getNavHiddenName(part
.string())) {
458 //printf("not navHidden: %s\n", part.string());
461 if (getNavigationName(part
.string())) {
470 //printf("not navigation: %s\n", part.string());
473 if (getScreenSizeName(part
.string())) {
482 //printf("not screen size: %s\n", part.string());
485 if (getVersionName(part
.string())) {
494 //printf("not version: %s\n", part.string());
497 // if there are extra parts, it doesn't match
504 this->screenLayoutSize
= layoutsize
;
505 this->screenLayoutLong
= layoutlong
;
506 this->orientation
= orient
;
507 this->uiModeType
= uiModeType
;
508 this->uiModeNight
= uiModeNight
;
510 this->touchscreen
= touch
;
511 this->keysHidden
= keysHidden
;
512 this->keyboard
= key
;
513 this->navHidden
= navHidden
;
514 this->navigation
= nav
;
515 this->screenSize
= size
;
516 this->version
= vers
;
518 // what is this anyway?
525 AaptGroupEntry::toString() const
527 String8 s
= this->mcc
;
533 s
+= screenLayoutSize
;
535 s
+= screenLayoutLong
;
537 s
+= this->orientation
;
562 AaptGroupEntry::toDirName(const String8
& resType
) const
565 if (this->mcc
!= "") {
569 if (this->mnc
!= "") {
573 if (this->locale
!= "") {
577 if (this->screenLayoutSize
!= "") {
579 s
+= screenLayoutSize
;
581 if (this->screenLayoutLong
!= "") {
583 s
+= screenLayoutLong
;
585 if (this->orientation
!= "") {
589 if (this->uiModeType
!= "") {
593 if (this->uiModeNight
!= "") {
597 if (this->density
!= "") {
601 if (this->touchscreen
!= "") {
605 if (this->keysHidden
!= "") {
609 if (this->keyboard
!= "") {
613 if (this->navHidden
!= "") {
617 if (this->navigation
!= "") {
621 if (this->screenSize
!= "") {
625 if (this->version
!= "") {
633 bool AaptGroupEntry::getMccName(const char* name
,
634 ResTable_config
* out
)
636 if (strcmp(name
, kWildcardName
) == 0) {
637 if (out
) out
->mcc
= 0;
640 const char* c
= name
;
641 if (tolower(*c
) != 'm') return false;
643 if (tolower(*c
) != 'c') return false;
645 if (tolower(*c
) != 'c') return false;
650 while (*c
>= '0' && *c
<= '9') {
653 if (*c
!= 0) return false;
654 if (c
-val
!= 3) return false;
658 if (out
) out
->mcc
= d
;
665 bool AaptGroupEntry::getMncName(const char* name
,
666 ResTable_config
* out
)
668 if (strcmp(name
, kWildcardName
) == 0) {
669 if (out
) out
->mcc
= 0;
672 const char* c
= name
;
673 if (tolower(*c
) != 'm') return false;
675 if (tolower(*c
) != 'n') return false;
677 if (tolower(*c
) != 'c') return false;
682 while (*c
>= '0' && *c
<= '9') {
685 if (*c
!= 0) return false;
686 if (c
-val
== 0 || c
-val
> 3) return false;
689 out
->mnc
= atoi(val
);
696 * Does this directory name fit the pattern of a locale dir ("en-rUS" or
699 * TODO: Should insist that the first two letters are lower case, and the
700 * second two are upper.
702 bool AaptGroupEntry::getLocaleName(const char* fileName
,
703 ResTable_config
* out
)
705 if (strcmp(fileName
, kWildcardName
) == 0
706 || strcmp(fileName
, kDefaultLocale
) == 0) {
708 out
->language
[0] = 0;
709 out
->language
[1] = 0;
716 if (strlen(fileName
) == 2 && isalpha(fileName
[0]) && isalpha(fileName
[1])) {
718 out
->language
[0] = fileName
[0];
719 out
->language
[1] = fileName
[1];
726 if (strlen(fileName
) == 5 &&
727 isalpha(fileName
[0]) &&
728 isalpha(fileName
[1]) &&
729 fileName
[2] == '-' &&
730 isalpha(fileName
[3]) &&
731 isalpha(fileName
[4])) {
733 out
->language
[0] = fileName
[0];
734 out
->language
[1] = fileName
[1];
735 out
->country
[0] = fileName
[3];
736 out
->country
[1] = fileName
[4];
744 bool AaptGroupEntry::getScreenLayoutSizeName(const char* name
,
745 ResTable_config
* out
)
747 if (strcmp(name
, kWildcardName
) == 0) {
748 if (out
) out
->screenLayout
=
749 (out
->screenLayout
&~ResTable_config::MASK_SCREENSIZE
)
750 | ResTable_config::SCREENSIZE_ANY
;
752 } else if (strcmp(name
, "small") == 0) {
753 if (out
) out
->screenLayout
=
754 (out
->screenLayout
&~ResTable_config::MASK_SCREENSIZE
)
755 | ResTable_config::SCREENSIZE_SMALL
;
757 } else if (strcmp(name
, "normal") == 0) {
758 if (out
) out
->screenLayout
=
759 (out
->screenLayout
&~ResTable_config::MASK_SCREENSIZE
)
760 | ResTable_config::SCREENSIZE_NORMAL
;
762 } else if (strcmp(name
, "large") == 0) {
763 if (out
) out
->screenLayout
=
764 (out
->screenLayout
&~ResTable_config::MASK_SCREENSIZE
)
765 | ResTable_config::SCREENSIZE_LARGE
;
767 } else if (strcmp(name
, "xlarge") == 0) {
768 if (out
) out
->screenLayout
=
769 (out
->screenLayout
&~ResTable_config::MASK_SCREENSIZE
)
770 | ResTable_config::SCREENSIZE_XLARGE
;
777 bool AaptGroupEntry::getScreenLayoutLongName(const char* name
,
778 ResTable_config
* out
)
780 if (strcmp(name
, kWildcardName
) == 0) {
781 if (out
) out
->screenLayout
=
782 (out
->screenLayout
&~ResTable_config::MASK_SCREENLONG
)
783 | ResTable_config::SCREENLONG_ANY
;
785 } else if (strcmp(name
, "long") == 0) {
786 if (out
) out
->screenLayout
=
787 (out
->screenLayout
&~ResTable_config::MASK_SCREENLONG
)
788 | ResTable_config::SCREENLONG_YES
;
790 } else if (strcmp(name
, "notlong") == 0) {
791 if (out
) out
->screenLayout
=
792 (out
->screenLayout
&~ResTable_config::MASK_SCREENLONG
)
793 | ResTable_config::SCREENLONG_NO
;
800 bool AaptGroupEntry::getOrientationName(const char* name
,
801 ResTable_config
* out
)
803 if (strcmp(name
, kWildcardName
) == 0) {
804 if (out
) out
->orientation
= out
->ORIENTATION_ANY
;
806 } else if (strcmp(name
, "port") == 0) {
807 if (out
) out
->orientation
= out
->ORIENTATION_PORT
;
809 } else if (strcmp(name
, "land") == 0) {
810 if (out
) out
->orientation
= out
->ORIENTATION_LAND
;
812 } else if (strcmp(name
, "square") == 0) {
813 if (out
) out
->orientation
= out
->ORIENTATION_SQUARE
;
820 bool AaptGroupEntry::getUiModeTypeName(const char* name
,
821 ResTable_config
* out
)
823 if (strcmp(name
, kWildcardName
) == 0) {
824 if (out
) out
->uiMode
=
825 (out
->uiMode
&~ResTable_config::MASK_UI_MODE_TYPE
)
826 | ResTable_config::UI_MODE_TYPE_ANY
;
828 } else if (strcmp(name
, "desk") == 0) {
829 if (out
) out
->uiMode
=
830 (out
->uiMode
&~ResTable_config::MASK_UI_MODE_TYPE
)
831 | ResTable_config::UI_MODE_TYPE_DESK
;
833 } else if (strcmp(name
, "car") == 0) {
834 if (out
) out
->uiMode
=
835 (out
->uiMode
&~ResTable_config::MASK_UI_MODE_TYPE
)
836 | ResTable_config::UI_MODE_TYPE_CAR
;
843 bool AaptGroupEntry::getUiModeNightName(const char* name
,
844 ResTable_config
* out
)
846 if (strcmp(name
, kWildcardName
) == 0) {
847 if (out
) out
->uiMode
=
848 (out
->uiMode
&~ResTable_config::MASK_UI_MODE_NIGHT
)
849 | ResTable_config::UI_MODE_NIGHT_ANY
;
851 } else if (strcmp(name
, "night") == 0) {
852 if (out
) out
->uiMode
=
853 (out
->uiMode
&~ResTable_config::MASK_UI_MODE_NIGHT
)
854 | ResTable_config::UI_MODE_NIGHT_YES
;
856 } else if (strcmp(name
, "notnight") == 0) {
857 if (out
) out
->uiMode
=
858 (out
->uiMode
&~ResTable_config::MASK_UI_MODE_NIGHT
)
859 | ResTable_config::UI_MODE_NIGHT_NO
;
866 bool AaptGroupEntry::getDensityName(const char* name
,
867 ResTable_config
* out
)
869 if (strcmp(name
, kWildcardName
) == 0) {
870 if (out
) out
->density
= ResTable_config::DENSITY_DEFAULT
;
874 if (strcmp(name
, "nodpi") == 0) {
875 if (out
) out
->density
= ResTable_config::DENSITY_NONE
;
879 if (strcmp(name
, "ldpi") == 0) {
880 if (out
) out
->density
= ResTable_config::DENSITY_LOW
;
884 if (strcmp(name
, "mdpi") == 0) {
885 if (out
) out
->density
= ResTable_config::DENSITY_MEDIUM
;
889 if (strcmp(name
, "hdpi") == 0) {
890 if (out
) out
->density
= ResTable_config::DENSITY_HIGH
;
894 if (strcmp(name
, "xhdpi") == 0) {
895 if (out
) out
->density
= ResTable_config::DENSITY_MEDIUM
*2;
899 char* c
= (char*)name
;
900 while (*c
>= '0' && *c
<= '9') {
904 // check that we have 'dpi' after the last digit.
905 if (toupper(c
[0]) != 'D' ||
906 toupper(c
[1]) != 'P' ||
907 toupper(c
[2]) != 'I' ||
912 // temporarily replace the first letter with \0 to
921 if (out
) out
->density
= d
;
928 bool AaptGroupEntry::getTouchscreenName(const char* name
,
929 ResTable_config
* out
)
931 if (strcmp(name
, kWildcardName
) == 0) {
932 if (out
) out
->touchscreen
= out
->TOUCHSCREEN_ANY
;
934 } else if (strcmp(name
, "notouch") == 0) {
935 if (out
) out
->touchscreen
= out
->TOUCHSCREEN_NOTOUCH
;
937 } else if (strcmp(name
, "stylus") == 0) {
938 if (out
) out
->touchscreen
= out
->TOUCHSCREEN_STYLUS
;
940 } else if (strcmp(name
, "finger") == 0) {
941 if (out
) out
->touchscreen
= out
->TOUCHSCREEN_FINGER
;
948 bool AaptGroupEntry::getKeysHiddenName(const char* name
,
949 ResTable_config
* out
)
953 if (strcmp(name
, kWildcardName
) == 0) {
954 mask
= ResTable_config::MASK_KEYSHIDDEN
;
955 value
= ResTable_config::KEYSHIDDEN_ANY
;
956 } else if (strcmp(name
, "keysexposed") == 0) {
957 mask
= ResTable_config::MASK_KEYSHIDDEN
;
958 value
= ResTable_config::KEYSHIDDEN_NO
;
959 } else if (strcmp(name
, "keyshidden") == 0) {
960 mask
= ResTable_config::MASK_KEYSHIDDEN
;
961 value
= ResTable_config::KEYSHIDDEN_YES
;
962 } else if (strcmp(name
, "keyssoft") == 0) {
963 mask
= ResTable_config::MASK_KEYSHIDDEN
;
964 value
= ResTable_config::KEYSHIDDEN_SOFT
;
968 if (out
) out
->inputFlags
= (out
->inputFlags
&~mask
) | value
;
975 bool AaptGroupEntry::getKeyboardName(const char* name
,
976 ResTable_config
* out
)
978 if (strcmp(name
, kWildcardName
) == 0) {
979 if (out
) out
->keyboard
= out
->KEYBOARD_ANY
;
981 } else if (strcmp(name
, "nokeys") == 0) {
982 if (out
) out
->keyboard
= out
->KEYBOARD_NOKEYS
;
984 } else if (strcmp(name
, "qwerty") == 0) {
985 if (out
) out
->keyboard
= out
->KEYBOARD_QWERTY
;
987 } else if (strcmp(name
, "12key") == 0) {
988 if (out
) out
->keyboard
= out
->KEYBOARD_12KEY
;
995 bool AaptGroupEntry::getNavHiddenName(const char* name
,
996 ResTable_config
* out
)
1000 if (strcmp(name
, kWildcardName
) == 0) {
1001 mask
= ResTable_config::MASK_NAVHIDDEN
;
1002 value
= ResTable_config::NAVHIDDEN_ANY
;
1003 } else if (strcmp(name
, "navexposed") == 0) {
1004 mask
= ResTable_config::MASK_NAVHIDDEN
;
1005 value
= ResTable_config::NAVHIDDEN_NO
;
1006 } else if (strcmp(name
, "navhidden") == 0) {
1007 mask
= ResTable_config::MASK_NAVHIDDEN
;
1008 value
= ResTable_config::NAVHIDDEN_YES
;
1012 if (out
) out
->inputFlags
= (out
->inputFlags
&~mask
) | value
;
1019 bool AaptGroupEntry::getNavigationName(const char* name
,
1020 ResTable_config
* out
)
1022 if (strcmp(name
, kWildcardName
) == 0) {
1023 if (out
) out
->navigation
= out
->NAVIGATION_ANY
;
1025 } else if (strcmp(name
, "nonav") == 0) {
1026 if (out
) out
->navigation
= out
->NAVIGATION_NONAV
;
1028 } else if (strcmp(name
, "dpad") == 0) {
1029 if (out
) out
->navigation
= out
->NAVIGATION_DPAD
;
1031 } else if (strcmp(name
, "trackball") == 0) {
1032 if (out
) out
->navigation
= out
->NAVIGATION_TRACKBALL
;
1034 } else if (strcmp(name
, "wheel") == 0) {
1035 if (out
) out
->navigation
= out
->NAVIGATION_WHEEL
;
1042 bool AaptGroupEntry::getScreenSizeName(const char* name
,
1043 ResTable_config
* out
)
1045 if (strcmp(name
, kWildcardName
) == 0) {
1047 out
->screenWidth
= out
->SCREENWIDTH_ANY
;
1048 out
->screenHeight
= out
->SCREENHEIGHT_ANY
;
1053 const char* x
= name
;
1054 while (*x
>= '0' && *x
<= '9') x
++;
1055 if (x
== name
|| *x
!= 'x') return false;
1056 String8
xName(name
, x
-name
);
1060 while (*y
>= '0' && *y
<= '9') y
++;
1061 if (y
== name
|| *y
!= 0) return false;
1062 String8
yName(x
, y
-x
);
1064 uint16_t w
= (uint16_t)atoi(xName
.string());
1065 uint16_t h
= (uint16_t)atoi(yName
.string());
1071 out
->screenWidth
= w
;
1072 out
->screenHeight
= h
;
1078 bool AaptGroupEntry::getVersionName(const char* name
,
1079 ResTable_config
* out
)
1081 if (strcmp(name
, kWildcardName
) == 0) {
1083 out
->sdkVersion
= out
->SDKVERSION_ANY
;
1084 out
->minorVersion
= out
->MINORVERSION_ANY
;
1094 const char* s
= name
;
1095 while (*s
>= '0' && *s
<= '9') s
++;
1096 if (s
== name
|| *s
!= 0) return false;
1097 String8
sdkName(name
, s
-name
);
1100 out
->sdkVersion
= (uint16_t)atoi(sdkName
.string());
1101 out
->minorVersion
= 0;
1107 int AaptGroupEntry::compare(const AaptGroupEntry
& o
) const
1109 int v
= mcc
.compare(o
.mcc
);
1110 if (v
== 0) v
= mnc
.compare(o
.mnc
);
1111 if (v
== 0) v
= locale
.compare(o
.locale
);
1112 if (v
== 0) v
= vendor
.compare(o
.vendor
);
1113 if (v
== 0) v
= screenLayoutSize
.compare(o
.screenLayoutSize
);
1114 if (v
== 0) v
= screenLayoutLong
.compare(o
.screenLayoutLong
);
1115 if (v
== 0) v
= orientation
.compare(o
.orientation
);
1116 if (v
== 0) v
= uiModeType
.compare(o
.uiModeType
);
1117 if (v
== 0) v
= uiModeNight
.compare(o
.uiModeNight
);
1118 if (v
== 0) v
= density
.compare(o
.density
);
1119 if (v
== 0) v
= touchscreen
.compare(o
.touchscreen
);
1120 if (v
== 0) v
= keysHidden
.compare(o
.keysHidden
);
1121 if (v
== 0) v
= keyboard
.compare(o
.keyboard
);
1122 if (v
== 0) v
= navHidden
.compare(o
.navHidden
);
1123 if (v
== 0) v
= navigation
.compare(o
.navigation
);
1124 if (v
== 0) v
= screenSize
.compare(o
.screenSize
);
1125 if (v
== 0) v
= version
.compare(o
.version
);
1129 ResTable_config
AaptGroupEntry::toParams() const
1131 ResTable_config params
;
1132 memset(¶ms
, 0, sizeof(params
));
1133 getMccName(mcc
.string(), ¶ms
);
1134 getMncName(mnc
.string(), ¶ms
);
1135 getLocaleName(locale
.string(), ¶ms
);
1136 getScreenLayoutSizeName(screenLayoutSize
.string(), ¶ms
);
1137 getScreenLayoutLongName(screenLayoutLong
.string(), ¶ms
);
1138 getOrientationName(orientation
.string(), ¶ms
);
1139 getUiModeTypeName(uiModeType
.string(), ¶ms
);
1140 getUiModeNightName(uiModeNight
.string(), ¶ms
);
1141 getDensityName(density
.string(), ¶ms
);
1142 getTouchscreenName(touchscreen
.string(), ¶ms
);
1143 getKeysHiddenName(keysHidden
.string(), ¶ms
);
1144 getKeyboardName(keyboard
.string(), ¶ms
);
1145 getNavHiddenName(navHidden
.string(), ¶ms
);
1146 getNavigationName(navigation
.string(), ¶ms
);
1147 getScreenSizeName(screenSize
.string(), ¶ms
);
1148 getVersionName(version
.string(), ¶ms
);
1150 // Fix up version number based on specified parameters.
1152 if ((params
.uiMode
&ResTable_config::MASK_UI_MODE_TYPE
)
1153 != ResTable_config::UI_MODE_TYPE_ANY
1154 || (params
.uiMode
&ResTable_config::MASK_UI_MODE_NIGHT
)
1155 != ResTable_config::UI_MODE_NIGHT_ANY
) {
1157 } else if ((params
.screenLayout
&ResTable_config::MASK_SCREENSIZE
)
1158 != ResTable_config::SCREENSIZE_ANY
1159 || (params
.screenLayout
&ResTable_config::MASK_SCREENLONG
)
1160 != ResTable_config::SCREENLONG_ANY
1161 || params
.density
!= ResTable_config::DENSITY_DEFAULT
) {
1165 if (minSdk
> params
.sdkVersion
) {
1166 params
.sdkVersion
= minSdk
;
1172 // =========================================================================
1173 // =========================================================================
1174 // =========================================================================
1176 void* AaptFile::editData(size_t size
)
1178 if (size
<= mBufferSize
) {
1182 size_t allocSize
= (size
*3)/2;
1183 void* buf
= realloc(mData
, allocSize
);
1189 mBufferSize
= allocSize
;
1193 void* AaptFile::editData(size_t* outSize
)
1196 *outSize
= mDataSize
;
1201 void* AaptFile::padData(size_t wordSize
)
1203 const size_t extra
= mDataSize%wordSize
;
1208 size_t initial
= mDataSize
;
1209 void* data
= editData(initial
+(wordSize
-extra
));
1211 memset(((uint8_t*)data
) + initial
, 0, wordSize
-extra
);
1216 status_t
AaptFile::writeData(const void* data
, size_t size
)
1218 size_t end
= mDataSize
;
1219 size_t total
= size
+ end
;
1220 void* buf
= editData(total
);
1222 return UNKNOWN_ERROR
;
1224 memcpy(((char*)buf
)+end
, data
, size
);
1228 void AaptFile::clearData()
1230 if (mData
!= NULL
) free(mData
);
1236 String8
AaptFile::getPrintableSource() const
1239 String8
name(mGroupEntry
.locale
.string());
1240 name
.appendPath(mGroupEntry
.vendor
.string());
1241 name
.appendPath(mPath
);
1242 name
.append(" #generated");
1248 // =========================================================================
1249 // =========================================================================
1250 // =========================================================================
1252 status_t
AaptGroup::addFile(const sp
<AaptFile
>& file
)
1254 if (mFiles
.indexOfKey(file
->getGroupEntry()) < 0) {
1255 file
->mPath
= mPath
;
1256 mFiles
.add(file
->getGroupEntry(), file
);
1260 SourcePos(file
->getSourceFile(), -1).error("Duplicate file.\n%s: Original is here.",
1261 getPrintableSource().string());
1262 return UNKNOWN_ERROR
;
1265 void AaptGroup::removeFile(size_t index
)
1267 mFiles
.removeItemsAt(index
);
1270 void AaptGroup::print() const
1272 printf(" %s\n", getPath().string());
1273 const size_t N
=mFiles
.size();
1275 for (i
=0; i
<N
; i
++) {
1276 sp
<AaptFile
> file
= mFiles
.valueAt(i
);
1277 const AaptGroupEntry
& e
= file
->getGroupEntry();
1278 if (file
->hasData()) {
1279 printf(" Gen: (%s) %d bytes\n", e
.toString().string(),
1280 (int)file
->getSize());
1282 printf(" Src: %s\n", file
->getPrintableSource().string());
1287 String8
AaptGroup::getPrintableSource() const
1289 if (mFiles
.size() > 0) {
1290 // Arbitrarily pull the first source file out of the list.
1291 return mFiles
.valueAt(0)->getPrintableSource();
1294 // Should never hit this case, but to be safe...
1299 // =========================================================================
1300 // =========================================================================
1301 // =========================================================================
1303 status_t
AaptDir::addFile(const String8
& name
, const sp
<AaptGroup
>& file
)
1305 if (mFiles
.indexOfKey(name
) >= 0) {
1306 return ALREADY_EXISTS
;
1308 mFiles
.add(name
, file
);
1312 status_t
AaptDir::addDir(const String8
& name
, const sp
<AaptDir
>& dir
)
1314 if (mDirs
.indexOfKey(name
) >= 0) {
1315 return ALREADY_EXISTS
;
1317 mDirs
.add(name
, dir
);
1321 sp
<AaptDir
> AaptDir::makeDir(const String8
& path
)
1324 String8 remain
= path
;
1326 sp
<AaptDir
> subdir
= this;
1327 while (name
= remain
.walkPath(&remain
), remain
!= "") {
1328 subdir
= subdir
->makeDir(name
);
1331 ssize_t i
= subdir
->mDirs
.indexOfKey(name
);
1333 return subdir
->mDirs
.valueAt(i
);
1335 sp
<AaptDir
> dir
= new AaptDir(name
, subdir
->mPath
.appendPathCopy(name
));
1336 subdir
->mDirs
.add(name
, dir
);
1340 void AaptDir::removeFile(const String8
& name
)
1342 mFiles
.removeItem(name
);
1345 void AaptDir::removeDir(const String8
& name
)
1347 mDirs
.removeItem(name
);
1350 status_t
AaptDir::renameFile(const sp
<AaptFile
>& file
, const String8
& newName
)
1352 sp
<AaptGroup
> origGroup
;
1354 // Find and remove the given file with shear, brute force!
1355 const size_t NG
= mFiles
.size();
1357 for (i
=0; origGroup
== NULL
&& i
<NG
; i
++) {
1358 sp
<AaptGroup
> g
= mFiles
.valueAt(i
);
1359 const size_t NF
= g
->getFiles().size();
1360 for (size_t j
=0; j
<NF
; j
++) {
1361 if (g
->getFiles().valueAt(j
) == file
) {
1365 mFiles
.removeItemsAt(i
);
1372 //printf("Renaming %s to %s\n", file->getPath().getPathName(), newName.string());
1374 // Place the file under its new name.
1375 if (origGroup
!= NULL
) {
1376 return addLeafFile(newName
, file
);
1382 status_t
AaptDir::addLeafFile(const String8
& leafName
, const sp
<AaptFile
>& file
)
1384 sp
<AaptGroup
> group
;
1385 if (mFiles
.indexOfKey(leafName
) >= 0) {
1386 group
= mFiles
.valueFor(leafName
);
1388 group
= new AaptGroup(leafName
, mPath
.appendPathCopy(leafName
));
1389 mFiles
.add(leafName
, group
);
1392 return group
->addFile(file
);
1395 ssize_t
AaptDir::slurpFullTree(Bundle
* bundle
, const String8
& srcDir
,
1396 const AaptGroupEntry
& kind
, const String8
& resType
)
1398 Vector
<String8
> fileNames
;
1403 dir
= opendir(srcDir
.string());
1405 fprintf(stderr
, "ERROR: opendir(%s): %s\n", srcDir
.string(), strerror(errno
));
1406 return UNKNOWN_ERROR
;
1410 * Slurp the filenames out of the directory.
1413 struct dirent
* entry
;
1415 entry
= readdir(dir
);
1419 if (isHidden(srcDir
.string(), entry
->d_name
))
1422 fileNames
.add(String8(entry
->d_name
));
1431 * Stash away the files and recursively descend into subdirectories.
1433 const size_t N
= fileNames
.size();
1435 for (i
= 0; i
< N
; i
++) {
1436 String8
pathName(srcDir
);
1439 pathName
.appendPath(fileNames
[i
].string());
1440 type
= getFileType(pathName
.string());
1441 if (type
== kFileTypeDirectory
) {
1443 bool notAdded
= false;
1444 if (mDirs
.indexOfKey(fileNames
[i
]) >= 0) {
1445 subdir
= mDirs
.valueFor(fileNames
[i
]);
1447 subdir
= new AaptDir(fileNames
[i
], mPath
.appendPathCopy(fileNames
[i
]));
1450 ssize_t res
= subdir
->slurpFullTree(bundle
, pathName
, kind
,
1452 if (res
< NO_ERROR
) {
1455 if (res
> 0 && notAdded
) {
1456 mDirs
.add(fileNames
[i
], subdir
);
1459 } else if (type
== kFileTypeRegular
) {
1460 sp
<AaptFile
> file
= new AaptFile(pathName
, kind
, resType
);
1461 status_t err
= addLeafFile(fileNames
[i
], file
);
1462 if (err
!= NO_ERROR
) {
1469 if (bundle
->getVerbose())
1470 printf(" (ignoring non-file/dir '%s')\n", pathName
.string());
1477 status_t
AaptDir::validate() const
1479 const size_t NF
= mFiles
.size();
1480 const size_t ND
= mDirs
.size();
1482 for (i
= 0; i
< NF
; i
++) {
1483 if (!validateFileName(mFiles
.valueAt(i
)->getLeaf().string())) {
1484 SourcePos(mFiles
.valueAt(i
)->getPrintableSource(), -1).error(
1485 "Invalid filename. Unable to add.");
1486 return UNKNOWN_ERROR
;
1490 for (j
= i
+1; j
< NF
; j
++) {
1491 if (strcasecmp(mFiles
.valueAt(i
)->getLeaf().string(),
1492 mFiles
.valueAt(j
)->getLeaf().string()) == 0) {
1493 SourcePos(mFiles
.valueAt(i
)->getPrintableSource(), -1).error(
1494 "File is case-insensitive equivalent to: %s",
1495 mFiles
.valueAt(j
)->getPrintableSource().string());
1496 return UNKNOWN_ERROR
;
1499 // TODO: if ".gz", check for non-.gz; if non-, check for ".gz"
1500 // (this is mostly caught by the "marked" stuff, below)
1503 for (j
= 0; j
< ND
; j
++) {
1504 if (strcasecmp(mFiles
.valueAt(i
)->getLeaf().string(),
1505 mDirs
.valueAt(j
)->getLeaf().string()) == 0) {
1506 SourcePos(mFiles
.valueAt(i
)->getPrintableSource(), -1).error(
1507 "File conflicts with dir from: %s",
1508 mDirs
.valueAt(j
)->getPrintableSource().string());
1509 return UNKNOWN_ERROR
;
1514 for (i
= 0; i
< ND
; i
++) {
1515 if (!validateFileName(mDirs
.valueAt(i
)->getLeaf().string())) {
1516 SourcePos(mDirs
.valueAt(i
)->getPrintableSource(), -1).error(
1517 "Invalid directory name, unable to add.");
1518 return UNKNOWN_ERROR
;
1522 for (j
= i
+1; j
< ND
; j
++) {
1523 if (strcasecmp(mDirs
.valueAt(i
)->getLeaf().string(),
1524 mDirs
.valueAt(j
)->getLeaf().string()) == 0) {
1525 SourcePos(mDirs
.valueAt(i
)->getPrintableSource(), -1).error(
1526 "Directory is case-insensitive equivalent to: %s",
1527 mDirs
.valueAt(j
)->getPrintableSource().string());
1528 return UNKNOWN_ERROR
;
1532 status_t err
= mDirs
.valueAt(i
)->validate();
1533 if (err
!= NO_ERROR
) {
1541 void AaptDir::print() const
1543 const size_t ND
=getDirs().size();
1545 for (i
=0; i
<ND
; i
++) {
1546 getDirs().valueAt(i
)->print();
1549 const size_t NF
=getFiles().size();
1550 for (i
=0; i
<NF
; i
++) {
1551 getFiles().valueAt(i
)->print();
1555 String8
AaptDir::getPrintableSource() const
1557 if (mFiles
.size() > 0) {
1558 // Arbitrarily pull the first file out of the list as the source dir.
1559 return mFiles
.valueAt(0)->getPrintableSource().getPathDir();
1561 if (mDirs
.size() > 0) {
1562 // Or arbitrarily pull the first dir out of the list as the source dir.
1563 return mDirs
.valueAt(0)->getPrintableSource().getPathDir();
1566 // Should never hit this case, but to be safe...
1571 // =========================================================================
1572 // =========================================================================
1573 // =========================================================================
1575 sp
<AaptFile
> AaptAssets::addFile(
1576 const String8
& filePath
, const AaptGroupEntry
& entry
,
1577 const String8
& srcDir
, sp
<AaptGroup
>* outGroup
,
1578 const String8
& resType
)
1580 sp
<AaptDir
> dir
= this;
1581 sp
<AaptGroup
> group
;
1583 String8 root
, remain(filePath
), partialPath
;
1584 while (remain
.length() > 0) {
1585 root
= remain
.walkPath(&remain
);
1586 partialPath
.appendPath(root
);
1588 const String8
rootStr(root
);
1590 if (remain
.length() == 0) {
1591 ssize_t i
= dir
->getFiles().indexOfKey(rootStr
);
1593 group
= dir
->getFiles().valueAt(i
);
1595 group
= new AaptGroup(rootStr
, filePath
);
1596 status_t res
= dir
->addFile(rootStr
, group
);
1597 if (res
!= NO_ERROR
) {
1601 file
= new AaptFile(srcDir
.appendPathCopy(filePath
), entry
, resType
);
1602 status_t res
= group
->addFile(file
);
1603 if (res
!= NO_ERROR
) {
1609 ssize_t i
= dir
->getDirs().indexOfKey(rootStr
);
1611 dir
= dir
->getDirs().valueAt(i
);
1613 sp
<AaptDir
> subdir
= new AaptDir(rootStr
, partialPath
);
1614 status_t res
= dir
->addDir(rootStr
, subdir
);
1615 if (res
!= NO_ERROR
) {
1623 mGroupEntries
.add(entry
);
1624 if (outGroup
) *outGroup
= group
;
1628 void AaptAssets::addResource(const String8
& leafName
, const String8
& path
,
1629 const sp
<AaptFile
>& file
, const String8
& resType
)
1631 sp
<AaptDir
> res
= AaptDir::makeDir(kResString
);
1632 String8 dirname
= file
->getGroupEntry().toDirName(resType
);
1633 sp
<AaptDir
> subdir
= res
->makeDir(dirname
);
1634 sp
<AaptGroup
> grr
= new AaptGroup(leafName
, path
);
1637 subdir
->addFile(leafName
, grr
);
1641 ssize_t
AaptAssets::slurpFromArgs(Bundle
* bundle
)
1646 const Vector
<const char *>& resDirs
= bundle
->getResourceSourceDirs();
1647 const size_t dirCount
=resDirs
.size();
1648 sp
<AaptAssets
> current
= this;
1650 const int N
= bundle
->getFileSpecCount();
1653 * If a package manifest was specified, include that first.
1655 if (bundle
->getAndroidManifestFile() != NULL
) {
1656 // place at root of zip.
1657 String8
srcFile(bundle
->getAndroidManifestFile());
1658 addFile(srcFile
.getPathLeaf(), AaptGroupEntry(), srcFile
.getPathDir(),
1664 * If a directory of custom assets was supplied, slurp 'em up.
1666 if (bundle
->getAssetSourceDir()) {
1667 const char* assetDir
= bundle
->getAssetSourceDir();
1669 FileType type
= getFileType(assetDir
);
1670 if (type
== kFileTypeNonexistent
) {
1671 fprintf(stderr
, "ERROR: asset directory '%s' does not exist\n", assetDir
);
1672 return UNKNOWN_ERROR
;
1674 if (type
!= kFileTypeDirectory
) {
1675 fprintf(stderr
, "ERROR: '%s' is not a directory\n", assetDir
);
1676 return UNKNOWN_ERROR
;
1679 String8
assetRoot(assetDir
);
1680 sp
<AaptDir
> assetAaptDir
= makeDir(String8(kAssetDir
));
1681 AaptGroupEntry group
;
1682 count
= assetAaptDir
->slurpFullTree(bundle
, assetRoot
, group
,
1689 mGroupEntries
.add(group
);
1691 totalCount
+= count
;
1693 if (bundle
->getVerbose())
1694 printf("Found %d custom asset file%s in %s\n",
1695 count
, (count
==1) ? "" : "s", assetDir
);
1699 * If a directory of resource-specific assets was supplied, slurp 'em up.
1701 for (size_t i
=0; i
<dirCount
; i
++) {
1702 const char *res
= resDirs
[i
];
1704 type
= getFileType(res
);
1705 if (type
== kFileTypeNonexistent
) {
1706 fprintf(stderr
, "ERROR: resource directory '%s' does not exist\n", res
);
1707 return UNKNOWN_ERROR
;
1709 if (type
== kFileTypeDirectory
) {
1711 sp
<AaptAssets
> nextOverlay
= new AaptAssets();
1712 current
->setOverlay(nextOverlay
);
1713 current
= nextOverlay
;
1715 count
= current
->slurpResourceTree(bundle
, String8(res
));
1721 totalCount
+= count
;
1724 fprintf(stderr
, "ERROR: '%s' is not a directory\n", res
);
1725 return UNKNOWN_ERROR
;
1731 * Now do any additional raw files.
1733 for (int arg
=0; arg
<N
; arg
++) {
1734 const char* assetDir
= bundle
->getFileSpecEntry(arg
);
1736 FileType type
= getFileType(assetDir
);
1737 if (type
== kFileTypeNonexistent
) {
1738 fprintf(stderr
, "ERROR: input directory '%s' does not exist\n", assetDir
);
1739 return UNKNOWN_ERROR
;
1741 if (type
!= kFileTypeDirectory
) {
1742 fprintf(stderr
, "ERROR: '%s' is not a directory\n", assetDir
);
1743 return UNKNOWN_ERROR
;
1746 String8
assetRoot(assetDir
);
1748 if (bundle
->getVerbose())
1749 printf("Processing raw dir '%s'\n", (const char*) assetDir
);
1752 * Do a recursive traversal of subdir tree. We don't make any
1753 * guarantees about ordering, so we're okay with an inorder search
1754 * using whatever order the OS happens to hand back to us.
1756 count
= slurpFullTree(bundle
, assetRoot
, AaptGroupEntry(), String8());
1758 /* failure; report error and remove archive */
1762 totalCount
+= count
;
1764 if (bundle
->getVerbose())
1765 printf("Found %d asset file%s in %s\n",
1766 count
, (count
==1) ? "" : "s", assetDir
);
1770 if (count
!= NO_ERROR
) {
1780 ssize_t
AaptAssets::slurpFullTree(Bundle
* bundle
, const String8
& srcDir
,
1781 const AaptGroupEntry
& kind
,
1782 const String8
& resType
)
1784 ssize_t res
= AaptDir::slurpFullTree(bundle
, srcDir
, kind
, resType
);
1786 mGroupEntries
.add(kind
);
1792 ssize_t
AaptAssets::slurpResourceTree(Bundle
* bundle
, const String8
& srcDir
)
1796 DIR* dir
= opendir(srcDir
.string());
1798 fprintf(stderr
, "ERROR: opendir(%s): %s\n", srcDir
.string(), strerror(errno
));
1799 return UNKNOWN_ERROR
;
1805 * Run through the directory, looking for dirs that match the
1809 struct dirent
* entry
= readdir(dir
);
1810 if (entry
== NULL
) {
1814 if (isHidden(srcDir
.string(), entry
->d_name
)) {
1818 String8
subdirName(srcDir
);
1819 subdirName
.appendPath(entry
->d_name
);
1821 AaptGroupEntry group
;
1823 bool b
= group
.initFromDirName(entry
->d_name
, &resType
);
1825 fprintf(stderr
, "invalid resource directory name: %s/%s\n", srcDir
.string(),
1831 if (bundle
->getMaxResVersion() != NULL
&& group
.version
.length() != 0) {
1832 int maxResInt
= atoi(bundle
->getMaxResVersion());
1833 const char *verString
= group
.version
.string();
1834 int dirVersionInt
= atoi(verString
+ 1); // skip 'v' in version name
1835 if (dirVersionInt
> maxResInt
) {
1836 fprintf(stderr
, "max res %d, skipping %s\n", maxResInt
, entry
->d_name
);
1841 FileType type
= getFileType(subdirName
.string());
1843 if (type
== kFileTypeDirectory
) {
1844 sp
<AaptDir
> dir
= makeDir(String8(entry
->d_name
));
1845 ssize_t res
= dir
->slurpFullTree(bundle
, subdirName
, group
,
1852 mGroupEntries
.add(group
);
1858 if (bundle
->getVerbose()) {
1859 fprintf(stderr
, " (ignoring file '%s')\n", subdirName
.string());
1875 AaptAssets::slurpResourceZip(Bundle
* bundle
, const char* filename
)
1878 SortedVector
<AaptGroupEntry
> entries
;
1880 ZipFile
* zip
= new ZipFile
;
1881 status_t err
= zip
->open(filename
, ZipFile::kOpenReadOnly
);
1882 if (err
!= NO_ERROR
) {
1883 fprintf(stderr
, "error opening zip file %s\n", filename
);
1889 const int N
= zip
->getNumEntries();
1890 for (int i
=0; i
<N
; i
++) {
1891 ZipEntry
* entry
= zip
->getEntryByIndex(i
);
1892 if (entry
->getDeleted()) {
1896 String8
entryName(entry
->getFileName());
1898 String8 dirName
= entryName
.getPathDir();
1899 sp
<AaptDir
> dir
= dirName
== "" ? this : makeDir(dirName
);
1902 AaptGroupEntry kind
;
1905 if (entryName
.walkPath(&remain
) == kResourceDir
) {
1906 // these are the resources, pull their type out of the directory name
1907 kind
.initFromDirName(remain
.walkPath().string(), &resType
);
1909 // these are untyped and don't have an AaptGroupEntry
1911 if (entries
.indexOf(kind
) < 0) {
1913 mGroupEntries
.add(kind
);
1916 // use the one from the zip file if they both exist.
1917 dir
->removeFile(entryName
.getPathLeaf());
1919 sp
<AaptFile
> file
= new AaptFile(entryName
, kind
, resType
);
1920 status_t err
= dir
->addLeafFile(entryName
.getPathLeaf(), file
);
1921 if (err
!= NO_ERROR
) {
1922 fprintf(stderr
, "err=%s entryName=%s\n", strerror(err
), entryName
.string());
1926 file
->setCompressionMethod(entry
->getCompressionMethod());
1929 if (entryName
== "AndroidManifest.xml") {
1930 printf("AndroidManifest.xml\n");
1932 printf("\n\nfile: %s\n", entryName
.string());
1935 size_t len
= entry
->getUncompressedLen();
1936 void* data
= zip
->uncompress(entry
);
1937 void* buf
= file
->editData(len
);
1938 memcpy(buf
, data
, len
);
1942 const unsigned char* p
= (unsigned char*)data
;
1943 const unsigned char* end
= p
+len
;
1945 for (int i
=0; i
<32 && p
< end
; i
++) {
1946 printf("0x%03x ", i
*0x10 + OFF
);
1947 for (int j
=0; j
<0x10 && p
< end
; j
++) {
1948 printf(" %02x", *p
);
1965 sp
<AaptSymbols
> AaptAssets::getSymbolsFor(const String8
& name
)
1967 sp
<AaptSymbols
> sym
= mSymbols
.valueFor(name
);
1969 sym
= new AaptSymbols();
1970 mSymbols
.add(name
, sym
);
1975 status_t
AaptAssets::buildIncludedResources(Bundle
* bundle
)
1977 if (!mHaveIncludedAssets
) {
1978 // Add in all includes.
1979 const Vector
<const char*>& incl
= bundle
->getPackageIncludes();
1980 const size_t N
=incl
.size();
1981 for (size_t i
=0; i
<N
; i
++) {
1982 if (bundle
->getVerbose())
1983 printf("Including resources from package: %s\n", incl
[i
]);
1984 if (!mIncludedAssets
.addAssetPath(String8(incl
[i
]), NULL
)) {
1985 fprintf(stderr
, "ERROR: Asset package include '%s' not found.\n",
1987 return UNKNOWN_ERROR
;
1990 mHaveIncludedAssets
= true;
1996 status_t
AaptAssets::addIncludedResources(const sp
<AaptFile
>& file
)
1998 const ResTable
& res
= getIncludedResources();
2000 return const_cast<ResTable
&>(res
).add(file
->getData(), file
->getSize(), NULL
);
2003 const ResTable
& AaptAssets::getIncludedResources() const
2005 return mIncludedAssets
.getResources(false);
2008 void AaptAssets::print() const
2010 printf("Locale/Vendor pairs:\n");
2011 const size_t N
=mGroupEntries
.size();
2012 for (size_t i
=0; i
<N
; i
++) {
2014 mGroupEntries
.itemAt(i
).locale
.string(),
2015 mGroupEntries
.itemAt(i
).vendor
.string());
2018 printf("\nFiles:\n");
2022 sp
<AaptDir
> AaptAssets::resDir(const String8
& name
)
2024 const Vector
<sp
<AaptDir
> >& dirs
= mDirs
;
2025 const size_t N
= dirs
.size();
2026 for (size_t i
=0; i
<N
; i
++) {
2027 const sp
<AaptDir
>& d
= dirs
.itemAt(i
);
2028 if (d
->getLeaf() == name
) {
2036 valid_symbol_name(const String8
& symbol
)
2038 static char const * const KEYWORDS
[] = {
2039 "abstract", "assert", "boolean", "break",
2040 "byte", "case", "catch", "char", "class", "const", "continue",
2041 "default", "do", "double", "else", "enum", "extends", "final",
2042 "finally", "float", "for", "goto", "if", "implements", "import",
2043 "instanceof", "int", "interface", "long", "native", "new", "package",
2044 "private", "protected", "public", "return", "short", "static",
2045 "strictfp", "super", "switch", "synchronized", "this", "throw",
2046 "throws", "transient", "try", "void", "volatile", "while",
2047 "true", "false", "null",
2050 const char*const* k
= KEYWORDS
;
2051 const char*const s
= symbol
.string();
2053 if (0 == strcmp(s
, *k
)) {