]>
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;
690 if (out
) out
->mnc
= d
;
698 * Does this directory name fit the pattern of a locale dir ("en-rUS" or
701 * TODO: Should insist that the first two letters are lower case, and the
702 * second two are upper.
704 bool AaptGroupEntry::getLocaleName(const char* fileName
,
705 ResTable_config
* out
)
707 if (strcmp(fileName
, kWildcardName
) == 0
708 || strcmp(fileName
, kDefaultLocale
) == 0) {
710 out
->language
[0] = 0;
711 out
->language
[1] = 0;
718 if (strlen(fileName
) == 2 && isalpha(fileName
[0]) && isalpha(fileName
[1])) {
720 out
->language
[0] = fileName
[0];
721 out
->language
[1] = fileName
[1];
728 if (strlen(fileName
) == 5 &&
729 isalpha(fileName
[0]) &&
730 isalpha(fileName
[1]) &&
731 fileName
[2] == '-' &&
732 isalpha(fileName
[3]) &&
733 isalpha(fileName
[4])) {
735 out
->language
[0] = fileName
[0];
736 out
->language
[1] = fileName
[1];
737 out
->country
[0] = fileName
[3];
738 out
->country
[1] = fileName
[4];
746 bool AaptGroupEntry::getScreenLayoutSizeName(const char* name
,
747 ResTable_config
* out
)
749 if (strcmp(name
, kWildcardName
) == 0) {
750 if (out
) out
->screenLayout
=
751 (out
->screenLayout
&~ResTable_config::MASK_SCREENSIZE
)
752 | ResTable_config::SCREENSIZE_ANY
;
754 } else if (strcmp(name
, "small") == 0) {
755 if (out
) out
->screenLayout
=
756 (out
->screenLayout
&~ResTable_config::MASK_SCREENSIZE
)
757 | ResTable_config::SCREENSIZE_SMALL
;
759 } else if (strcmp(name
, "normal") == 0) {
760 if (out
) out
->screenLayout
=
761 (out
->screenLayout
&~ResTable_config::MASK_SCREENSIZE
)
762 | ResTable_config::SCREENSIZE_NORMAL
;
764 } else if (strcmp(name
, "large") == 0) {
765 if (out
) out
->screenLayout
=
766 (out
->screenLayout
&~ResTable_config::MASK_SCREENSIZE
)
767 | ResTable_config::SCREENSIZE_LARGE
;
769 } else if (strcmp(name
, "xlarge") == 0) {
770 if (out
) out
->screenLayout
=
771 (out
->screenLayout
&~ResTable_config::MASK_SCREENSIZE
)
772 | ResTable_config::SCREENSIZE_XLARGE
;
779 bool AaptGroupEntry::getScreenLayoutLongName(const char* name
,
780 ResTable_config
* out
)
782 if (strcmp(name
, kWildcardName
) == 0) {
783 if (out
) out
->screenLayout
=
784 (out
->screenLayout
&~ResTable_config::MASK_SCREENLONG
)
785 | ResTable_config::SCREENLONG_ANY
;
787 } else if (strcmp(name
, "long") == 0) {
788 if (out
) out
->screenLayout
=
789 (out
->screenLayout
&~ResTable_config::MASK_SCREENLONG
)
790 | ResTable_config::SCREENLONG_YES
;
792 } else if (strcmp(name
, "notlong") == 0) {
793 if (out
) out
->screenLayout
=
794 (out
->screenLayout
&~ResTable_config::MASK_SCREENLONG
)
795 | ResTable_config::SCREENLONG_NO
;
802 bool AaptGroupEntry::getOrientationName(const char* name
,
803 ResTable_config
* out
)
805 if (strcmp(name
, kWildcardName
) == 0) {
806 if (out
) out
->orientation
= out
->ORIENTATION_ANY
;
808 } else if (strcmp(name
, "port") == 0) {
809 if (out
) out
->orientation
= out
->ORIENTATION_PORT
;
811 } else if (strcmp(name
, "land") == 0) {
812 if (out
) out
->orientation
= out
->ORIENTATION_LAND
;
814 } else if (strcmp(name
, "square") == 0) {
815 if (out
) out
->orientation
= out
->ORIENTATION_SQUARE
;
822 bool AaptGroupEntry::getUiModeTypeName(const char* name
,
823 ResTable_config
* out
)
825 if (strcmp(name
, kWildcardName
) == 0) {
826 if (out
) out
->uiMode
=
827 (out
->uiMode
&~ResTable_config::MASK_UI_MODE_TYPE
)
828 | ResTable_config::UI_MODE_TYPE_ANY
;
830 } else if (strcmp(name
, "desk") == 0) {
831 if (out
) out
->uiMode
=
832 (out
->uiMode
&~ResTable_config::MASK_UI_MODE_TYPE
)
833 | ResTable_config::UI_MODE_TYPE_DESK
;
835 } else if (strcmp(name
, "car") == 0) {
836 if (out
) out
->uiMode
=
837 (out
->uiMode
&~ResTable_config::MASK_UI_MODE_TYPE
)
838 | ResTable_config::UI_MODE_TYPE_CAR
;
845 bool AaptGroupEntry::getUiModeNightName(const char* name
,
846 ResTable_config
* out
)
848 if (strcmp(name
, kWildcardName
) == 0) {
849 if (out
) out
->uiMode
=
850 (out
->uiMode
&~ResTable_config::MASK_UI_MODE_NIGHT
)
851 | ResTable_config::UI_MODE_NIGHT_ANY
;
853 } else if (strcmp(name
, "night") == 0) {
854 if (out
) out
->uiMode
=
855 (out
->uiMode
&~ResTable_config::MASK_UI_MODE_NIGHT
)
856 | ResTable_config::UI_MODE_NIGHT_YES
;
858 } else if (strcmp(name
, "notnight") == 0) {
859 if (out
) out
->uiMode
=
860 (out
->uiMode
&~ResTable_config::MASK_UI_MODE_NIGHT
)
861 | ResTable_config::UI_MODE_NIGHT_NO
;
868 bool AaptGroupEntry::getDensityName(const char* name
,
869 ResTable_config
* out
)
871 if (strcmp(name
, kWildcardName
) == 0) {
872 if (out
) out
->density
= ResTable_config::DENSITY_DEFAULT
;
876 if (strcmp(name
, "nodpi") == 0) {
877 if (out
) out
->density
= ResTable_config::DENSITY_NONE
;
881 if (strcmp(name
, "ldpi") == 0) {
882 if (out
) out
->density
= ResTable_config::DENSITY_LOW
;
886 if (strcmp(name
, "mdpi") == 0) {
887 if (out
) out
->density
= ResTable_config::DENSITY_MEDIUM
;
891 if (strcmp(name
, "hdpi") == 0) {
892 if (out
) out
->density
= ResTable_config::DENSITY_HIGH
;
896 if (strcmp(name
, "xhdpi") == 0) {
897 if (out
) out
->density
= ResTable_config::DENSITY_MEDIUM
*2;
901 char* c
= (char*)name
;
902 while (*c
>= '0' && *c
<= '9') {
906 // check that we have 'dpi' after the last digit.
907 if (toupper(c
[0]) != 'D' ||
908 toupper(c
[1]) != 'P' ||
909 toupper(c
[2]) != 'I' ||
914 // temporarily replace the first letter with \0 to
923 if (out
) out
->density
= d
;
930 bool AaptGroupEntry::getTouchscreenName(const char* name
,
931 ResTable_config
* out
)
933 if (strcmp(name
, kWildcardName
) == 0) {
934 if (out
) out
->touchscreen
= out
->TOUCHSCREEN_ANY
;
936 } else if (strcmp(name
, "notouch") == 0) {
937 if (out
) out
->touchscreen
= out
->TOUCHSCREEN_NOTOUCH
;
939 } else if (strcmp(name
, "stylus") == 0) {
940 if (out
) out
->touchscreen
= out
->TOUCHSCREEN_STYLUS
;
942 } else if (strcmp(name
, "finger") == 0) {
943 if (out
) out
->touchscreen
= out
->TOUCHSCREEN_FINGER
;
950 bool AaptGroupEntry::getKeysHiddenName(const char* name
,
951 ResTable_config
* out
)
955 if (strcmp(name
, kWildcardName
) == 0) {
956 mask
= ResTable_config::MASK_KEYSHIDDEN
;
957 value
= ResTable_config::KEYSHIDDEN_ANY
;
958 } else if (strcmp(name
, "keysexposed") == 0) {
959 mask
= ResTable_config::MASK_KEYSHIDDEN
;
960 value
= ResTable_config::KEYSHIDDEN_NO
;
961 } else if (strcmp(name
, "keyshidden") == 0) {
962 mask
= ResTable_config::MASK_KEYSHIDDEN
;
963 value
= ResTable_config::KEYSHIDDEN_YES
;
964 } else if (strcmp(name
, "keyssoft") == 0) {
965 mask
= ResTable_config::MASK_KEYSHIDDEN
;
966 value
= ResTable_config::KEYSHIDDEN_SOFT
;
970 if (out
) out
->inputFlags
= (out
->inputFlags
&~mask
) | value
;
977 bool AaptGroupEntry::getKeyboardName(const char* name
,
978 ResTable_config
* out
)
980 if (strcmp(name
, kWildcardName
) == 0) {
981 if (out
) out
->keyboard
= out
->KEYBOARD_ANY
;
983 } else if (strcmp(name
, "nokeys") == 0) {
984 if (out
) out
->keyboard
= out
->KEYBOARD_NOKEYS
;
986 } else if (strcmp(name
, "qwerty") == 0) {
987 if (out
) out
->keyboard
= out
->KEYBOARD_QWERTY
;
989 } else if (strcmp(name
, "12key") == 0) {
990 if (out
) out
->keyboard
= out
->KEYBOARD_12KEY
;
997 bool AaptGroupEntry::getNavHiddenName(const char* name
,
998 ResTable_config
* out
)
1002 if (strcmp(name
, kWildcardName
) == 0) {
1003 mask
= ResTable_config::MASK_NAVHIDDEN
;
1004 value
= ResTable_config::NAVHIDDEN_ANY
;
1005 } else if (strcmp(name
, "navexposed") == 0) {
1006 mask
= ResTable_config::MASK_NAVHIDDEN
;
1007 value
= ResTable_config::NAVHIDDEN_NO
;
1008 } else if (strcmp(name
, "navhidden") == 0) {
1009 mask
= ResTable_config::MASK_NAVHIDDEN
;
1010 value
= ResTable_config::NAVHIDDEN_YES
;
1014 if (out
) out
->inputFlags
= (out
->inputFlags
&~mask
) | value
;
1021 bool AaptGroupEntry::getNavigationName(const char* name
,
1022 ResTable_config
* out
)
1024 if (strcmp(name
, kWildcardName
) == 0) {
1025 if (out
) out
->navigation
= out
->NAVIGATION_ANY
;
1027 } else if (strcmp(name
, "nonav") == 0) {
1028 if (out
) out
->navigation
= out
->NAVIGATION_NONAV
;
1030 } else if (strcmp(name
, "dpad") == 0) {
1031 if (out
) out
->navigation
= out
->NAVIGATION_DPAD
;
1033 } else if (strcmp(name
, "trackball") == 0) {
1034 if (out
) out
->navigation
= out
->NAVIGATION_TRACKBALL
;
1036 } else if (strcmp(name
, "wheel") == 0) {
1037 if (out
) out
->navigation
= out
->NAVIGATION_WHEEL
;
1044 bool AaptGroupEntry::getScreenSizeName(const char* name
,
1045 ResTable_config
* out
)
1047 if (strcmp(name
, kWildcardName
) == 0) {
1049 out
->screenWidth
= out
->SCREENWIDTH_ANY
;
1050 out
->screenHeight
= out
->SCREENHEIGHT_ANY
;
1055 const char* x
= name
;
1056 while (*x
>= '0' && *x
<= '9') x
++;
1057 if (x
== name
|| *x
!= 'x') return false;
1058 String8
xName(name
, x
-name
);
1062 while (*y
>= '0' && *y
<= '9') y
++;
1063 if (y
== name
|| *y
!= 0) return false;
1064 String8
yName(x
, y
-x
);
1066 uint16_t w
= (uint16_t)atoi(xName
.string());
1067 uint16_t h
= (uint16_t)atoi(yName
.string());
1073 out
->screenWidth
= w
;
1074 out
->screenHeight
= h
;
1080 bool AaptGroupEntry::getVersionName(const char* name
,
1081 ResTable_config
* out
)
1083 if (strcmp(name
, kWildcardName
) == 0) {
1085 out
->sdkVersion
= out
->SDKVERSION_ANY
;
1086 out
->minorVersion
= out
->MINORVERSION_ANY
;
1096 const char* s
= name
;
1097 while (*s
>= '0' && *s
<= '9') s
++;
1098 if (s
== name
|| *s
!= 0) return false;
1099 String8
sdkName(name
, s
-name
);
1102 out
->sdkVersion
= (uint16_t)atoi(sdkName
.string());
1103 out
->minorVersion
= 0;
1109 int AaptGroupEntry::compare(const AaptGroupEntry
& o
) const
1111 int v
= mcc
.compare(o
.mcc
);
1112 if (v
== 0) v
= mnc
.compare(o
.mnc
);
1113 if (v
== 0) v
= locale
.compare(o
.locale
);
1114 if (v
== 0) v
= vendor
.compare(o
.vendor
);
1115 if (v
== 0) v
= screenLayoutSize
.compare(o
.screenLayoutSize
);
1116 if (v
== 0) v
= screenLayoutLong
.compare(o
.screenLayoutLong
);
1117 if (v
== 0) v
= orientation
.compare(o
.orientation
);
1118 if (v
== 0) v
= uiModeType
.compare(o
.uiModeType
);
1119 if (v
== 0) v
= uiModeNight
.compare(o
.uiModeNight
);
1120 if (v
== 0) v
= density
.compare(o
.density
);
1121 if (v
== 0) v
= touchscreen
.compare(o
.touchscreen
);
1122 if (v
== 0) v
= keysHidden
.compare(o
.keysHidden
);
1123 if (v
== 0) v
= keyboard
.compare(o
.keyboard
);
1124 if (v
== 0) v
= navHidden
.compare(o
.navHidden
);
1125 if (v
== 0) v
= navigation
.compare(o
.navigation
);
1126 if (v
== 0) v
= screenSize
.compare(o
.screenSize
);
1127 if (v
== 0) v
= version
.compare(o
.version
);
1131 ResTable_config
AaptGroupEntry::toParams() const
1133 ResTable_config params
;
1134 memset(¶ms
, 0, sizeof(params
));
1135 getMccName(mcc
.string(), ¶ms
);
1136 getMncName(mnc
.string(), ¶ms
);
1137 getLocaleName(locale
.string(), ¶ms
);
1138 getScreenLayoutSizeName(screenLayoutSize
.string(), ¶ms
);
1139 getScreenLayoutLongName(screenLayoutLong
.string(), ¶ms
);
1140 getOrientationName(orientation
.string(), ¶ms
);
1141 getUiModeTypeName(uiModeType
.string(), ¶ms
);
1142 getUiModeNightName(uiModeNight
.string(), ¶ms
);
1143 getDensityName(density
.string(), ¶ms
);
1144 getTouchscreenName(touchscreen
.string(), ¶ms
);
1145 getKeysHiddenName(keysHidden
.string(), ¶ms
);
1146 getKeyboardName(keyboard
.string(), ¶ms
);
1147 getNavHiddenName(navHidden
.string(), ¶ms
);
1148 getNavigationName(navigation
.string(), ¶ms
);
1149 getScreenSizeName(screenSize
.string(), ¶ms
);
1150 getVersionName(version
.string(), ¶ms
);
1152 // Fix up version number based on specified parameters.
1154 if ((params
.uiMode
&ResTable_config::MASK_UI_MODE_TYPE
)
1155 != ResTable_config::UI_MODE_TYPE_ANY
1156 || (params
.uiMode
&ResTable_config::MASK_UI_MODE_NIGHT
)
1157 != ResTable_config::UI_MODE_NIGHT_ANY
) {
1159 } else if ((params
.screenLayout
&ResTable_config::MASK_SCREENSIZE
)
1160 != ResTable_config::SCREENSIZE_ANY
1161 || (params
.screenLayout
&ResTable_config::MASK_SCREENLONG
)
1162 != ResTable_config::SCREENLONG_ANY
1163 || params
.density
!= ResTable_config::DENSITY_DEFAULT
) {
1167 if (minSdk
> params
.sdkVersion
) {
1168 params
.sdkVersion
= minSdk
;
1174 // =========================================================================
1175 // =========================================================================
1176 // =========================================================================
1178 void* AaptFile::editData(size_t size
)
1180 if (size
<= mBufferSize
) {
1184 size_t allocSize
= (size
*3)/2;
1185 void* buf
= realloc(mData
, allocSize
);
1191 mBufferSize
= allocSize
;
1195 void* AaptFile::editData(size_t* outSize
)
1198 *outSize
= mDataSize
;
1203 void* AaptFile::padData(size_t wordSize
)
1205 const size_t extra
= mDataSize%wordSize
;
1210 size_t initial
= mDataSize
;
1211 void* data
= editData(initial
+(wordSize
-extra
));
1213 memset(((uint8_t*)data
) + initial
, 0, wordSize
-extra
);
1218 status_t
AaptFile::writeData(const void* data
, size_t size
)
1220 size_t end
= mDataSize
;
1221 size_t total
= size
+ end
;
1222 void* buf
= editData(total
);
1224 return UNKNOWN_ERROR
;
1226 memcpy(((char*)buf
)+end
, data
, size
);
1230 void AaptFile::clearData()
1232 if (mData
!= NULL
) free(mData
);
1238 String8
AaptFile::getPrintableSource() const
1241 String8
name(mGroupEntry
.locale
.string());
1242 name
.appendPath(mGroupEntry
.vendor
.string());
1243 name
.appendPath(mPath
);
1244 name
.append(" #generated");
1250 // =========================================================================
1251 // =========================================================================
1252 // =========================================================================
1254 status_t
AaptGroup::addFile(const sp
<AaptFile
>& file
)
1256 if (mFiles
.indexOfKey(file
->getGroupEntry()) < 0) {
1257 file
->mPath
= mPath
;
1258 mFiles
.add(file
->getGroupEntry(), file
);
1262 SourcePos(file
->getSourceFile(), -1).error("Duplicate file.\n%s: Original is here.",
1263 getPrintableSource().string());
1264 return UNKNOWN_ERROR
;
1267 void AaptGroup::removeFile(size_t index
)
1269 mFiles
.removeItemsAt(index
);
1272 void AaptGroup::print() const
1274 printf(" %s\n", getPath().string());
1275 const size_t N
=mFiles
.size();
1277 for (i
=0; i
<N
; i
++) {
1278 sp
<AaptFile
> file
= mFiles
.valueAt(i
);
1279 const AaptGroupEntry
& e
= file
->getGroupEntry();
1280 if (file
->hasData()) {
1281 printf(" Gen: (%s) %d bytes\n", e
.toString().string(),
1282 (int)file
->getSize());
1284 printf(" Src: %s\n", file
->getPrintableSource().string());
1289 String8
AaptGroup::getPrintableSource() const
1291 if (mFiles
.size() > 0) {
1292 // Arbitrarily pull the first source file out of the list.
1293 return mFiles
.valueAt(0)->getPrintableSource();
1296 // Should never hit this case, but to be safe...
1301 // =========================================================================
1302 // =========================================================================
1303 // =========================================================================
1305 status_t
AaptDir::addFile(const String8
& name
, const sp
<AaptGroup
>& file
)
1307 if (mFiles
.indexOfKey(name
) >= 0) {
1308 return ALREADY_EXISTS
;
1310 mFiles
.add(name
, file
);
1314 status_t
AaptDir::addDir(const String8
& name
, const sp
<AaptDir
>& dir
)
1316 if (mDirs
.indexOfKey(name
) >= 0) {
1317 return ALREADY_EXISTS
;
1319 mDirs
.add(name
, dir
);
1323 sp
<AaptDir
> AaptDir::makeDir(const String8
& path
)
1326 String8 remain
= path
;
1328 sp
<AaptDir
> subdir
= this;
1329 while (name
= remain
.walkPath(&remain
), remain
!= "") {
1330 subdir
= subdir
->makeDir(name
);
1333 ssize_t i
= subdir
->mDirs
.indexOfKey(name
);
1335 return subdir
->mDirs
.valueAt(i
);
1337 sp
<AaptDir
> dir
= new AaptDir(name
, subdir
->mPath
.appendPathCopy(name
));
1338 subdir
->mDirs
.add(name
, dir
);
1342 void AaptDir::removeFile(const String8
& name
)
1344 mFiles
.removeItem(name
);
1347 void AaptDir::removeDir(const String8
& name
)
1349 mDirs
.removeItem(name
);
1352 status_t
AaptDir::renameFile(const sp
<AaptFile
>& file
, const String8
& newName
)
1354 sp
<AaptGroup
> origGroup
;
1356 // Find and remove the given file with shear, brute force!
1357 const size_t NG
= mFiles
.size();
1359 for (i
=0; origGroup
== NULL
&& i
<NG
; i
++) {
1360 sp
<AaptGroup
> g
= mFiles
.valueAt(i
);
1361 const size_t NF
= g
->getFiles().size();
1362 for (size_t j
=0; j
<NF
; j
++) {
1363 if (g
->getFiles().valueAt(j
) == file
) {
1367 mFiles
.removeItemsAt(i
);
1374 //printf("Renaming %s to %s\n", file->getPath().getPathName(), newName.string());
1376 // Place the file under its new name.
1377 if (origGroup
!= NULL
) {
1378 return addLeafFile(newName
, file
);
1384 status_t
AaptDir::addLeafFile(const String8
& leafName
, const sp
<AaptFile
>& file
)
1386 sp
<AaptGroup
> group
;
1387 if (mFiles
.indexOfKey(leafName
) >= 0) {
1388 group
= mFiles
.valueFor(leafName
);
1390 group
= new AaptGroup(leafName
, mPath
.appendPathCopy(leafName
));
1391 mFiles
.add(leafName
, group
);
1394 return group
->addFile(file
);
1397 ssize_t
AaptDir::slurpFullTree(Bundle
* bundle
, const String8
& srcDir
,
1398 const AaptGroupEntry
& kind
, const String8
& resType
)
1400 Vector
<String8
> fileNames
;
1405 dir
= opendir(srcDir
.string());
1407 fprintf(stderr
, "ERROR: opendir(%s): %s\n", srcDir
.string(), strerror(errno
));
1408 return UNKNOWN_ERROR
;
1412 * Slurp the filenames out of the directory.
1415 struct dirent
* entry
;
1417 entry
= readdir(dir
);
1421 if (isHidden(srcDir
.string(), entry
->d_name
))
1424 fileNames
.add(String8(entry
->d_name
));
1433 * Stash away the files and recursively descend into subdirectories.
1435 const size_t N
= fileNames
.size();
1437 for (i
= 0; i
< N
; i
++) {
1438 String8
pathName(srcDir
);
1441 pathName
.appendPath(fileNames
[i
].string());
1442 type
= getFileType(pathName
.string());
1443 if (type
== kFileTypeDirectory
) {
1445 bool notAdded
= false;
1446 if (mDirs
.indexOfKey(fileNames
[i
]) >= 0) {
1447 subdir
= mDirs
.valueFor(fileNames
[i
]);
1449 subdir
= new AaptDir(fileNames
[i
], mPath
.appendPathCopy(fileNames
[i
]));
1452 ssize_t res
= subdir
->slurpFullTree(bundle
, pathName
, kind
,
1454 if (res
< NO_ERROR
) {
1457 if (res
> 0 && notAdded
) {
1458 mDirs
.add(fileNames
[i
], subdir
);
1461 } else if (type
== kFileTypeRegular
) {
1462 sp
<AaptFile
> file
= new AaptFile(pathName
, kind
, resType
);
1463 status_t err
= addLeafFile(fileNames
[i
], file
);
1464 if (err
!= NO_ERROR
) {
1471 if (bundle
->getVerbose())
1472 printf(" (ignoring non-file/dir '%s')\n", pathName
.string());
1479 status_t
AaptDir::validate() const
1481 const size_t NF
= mFiles
.size();
1482 const size_t ND
= mDirs
.size();
1484 for (i
= 0; i
< NF
; i
++) {
1485 if (!validateFileName(mFiles
.valueAt(i
)->getLeaf().string())) {
1486 SourcePos(mFiles
.valueAt(i
)->getPrintableSource(), -1).error(
1487 "Invalid filename. Unable to add.");
1488 return UNKNOWN_ERROR
;
1492 for (j
= i
+1; j
< NF
; j
++) {
1493 if (strcasecmp(mFiles
.valueAt(i
)->getLeaf().string(),
1494 mFiles
.valueAt(j
)->getLeaf().string()) == 0) {
1495 SourcePos(mFiles
.valueAt(i
)->getPrintableSource(), -1).error(
1496 "File is case-insensitive equivalent to: %s",
1497 mFiles
.valueAt(j
)->getPrintableSource().string());
1498 return UNKNOWN_ERROR
;
1501 // TODO: if ".gz", check for non-.gz; if non-, check for ".gz"
1502 // (this is mostly caught by the "marked" stuff, below)
1505 for (j
= 0; j
< ND
; j
++) {
1506 if (strcasecmp(mFiles
.valueAt(i
)->getLeaf().string(),
1507 mDirs
.valueAt(j
)->getLeaf().string()) == 0) {
1508 SourcePos(mFiles
.valueAt(i
)->getPrintableSource(), -1).error(
1509 "File conflicts with dir from: %s",
1510 mDirs
.valueAt(j
)->getPrintableSource().string());
1511 return UNKNOWN_ERROR
;
1516 for (i
= 0; i
< ND
; i
++) {
1517 if (!validateFileName(mDirs
.valueAt(i
)->getLeaf().string())) {
1518 SourcePos(mDirs
.valueAt(i
)->getPrintableSource(), -1).error(
1519 "Invalid directory name, unable to add.");
1520 return UNKNOWN_ERROR
;
1524 for (j
= i
+1; j
< ND
; j
++) {
1525 if (strcasecmp(mDirs
.valueAt(i
)->getLeaf().string(),
1526 mDirs
.valueAt(j
)->getLeaf().string()) == 0) {
1527 SourcePos(mDirs
.valueAt(i
)->getPrintableSource(), -1).error(
1528 "Directory is case-insensitive equivalent to: %s",
1529 mDirs
.valueAt(j
)->getPrintableSource().string());
1530 return UNKNOWN_ERROR
;
1534 status_t err
= mDirs
.valueAt(i
)->validate();
1535 if (err
!= NO_ERROR
) {
1543 void AaptDir::print() const
1545 const size_t ND
=getDirs().size();
1547 for (i
=0; i
<ND
; i
++) {
1548 getDirs().valueAt(i
)->print();
1551 const size_t NF
=getFiles().size();
1552 for (i
=0; i
<NF
; i
++) {
1553 getFiles().valueAt(i
)->print();
1557 String8
AaptDir::getPrintableSource() const
1559 if (mFiles
.size() > 0) {
1560 // Arbitrarily pull the first file out of the list as the source dir.
1561 return mFiles
.valueAt(0)->getPrintableSource().getPathDir();
1563 if (mDirs
.size() > 0) {
1564 // Or arbitrarily pull the first dir out of the list as the source dir.
1565 return mDirs
.valueAt(0)->getPrintableSource().getPathDir();
1568 // Should never hit this case, but to be safe...
1573 // =========================================================================
1574 // =========================================================================
1575 // =========================================================================
1577 sp
<AaptFile
> AaptAssets::addFile(
1578 const String8
& filePath
, const AaptGroupEntry
& entry
,
1579 const String8
& srcDir
, sp
<AaptGroup
>* outGroup
,
1580 const String8
& resType
)
1582 sp
<AaptDir
> dir
= this;
1583 sp
<AaptGroup
> group
;
1585 String8 root
, remain(filePath
), partialPath
;
1586 while (remain
.length() > 0) {
1587 root
= remain
.walkPath(&remain
);
1588 partialPath
.appendPath(root
);
1590 const String8
rootStr(root
);
1592 if (remain
.length() == 0) {
1593 ssize_t i
= dir
->getFiles().indexOfKey(rootStr
);
1595 group
= dir
->getFiles().valueAt(i
);
1597 group
= new AaptGroup(rootStr
, filePath
);
1598 status_t res
= dir
->addFile(rootStr
, group
);
1599 if (res
!= NO_ERROR
) {
1603 file
= new AaptFile(srcDir
.appendPathCopy(filePath
), entry
, resType
);
1604 status_t res
= group
->addFile(file
);
1605 if (res
!= NO_ERROR
) {
1611 ssize_t i
= dir
->getDirs().indexOfKey(rootStr
);
1613 dir
= dir
->getDirs().valueAt(i
);
1615 sp
<AaptDir
> subdir
= new AaptDir(rootStr
, partialPath
);
1616 status_t res
= dir
->addDir(rootStr
, subdir
);
1617 if (res
!= NO_ERROR
) {
1625 mGroupEntries
.add(entry
);
1626 if (outGroup
) *outGroup
= group
;
1630 void AaptAssets::addResource(const String8
& leafName
, const String8
& path
,
1631 const sp
<AaptFile
>& file
, const String8
& resType
)
1633 sp
<AaptDir
> res
= AaptDir::makeDir(kResString
);
1634 String8 dirname
= file
->getGroupEntry().toDirName(resType
);
1635 sp
<AaptDir
> subdir
= res
->makeDir(dirname
);
1636 sp
<AaptGroup
> grr
= new AaptGroup(leafName
, path
);
1639 subdir
->addFile(leafName
, grr
);
1643 ssize_t
AaptAssets::slurpFromArgs(Bundle
* bundle
)
1648 const Vector
<const char *>& resDirs
= bundle
->getResourceSourceDirs();
1649 const size_t dirCount
=resDirs
.size();
1650 sp
<AaptAssets
> current
= this;
1652 const int N
= bundle
->getFileSpecCount();
1655 * If a package manifest was specified, include that first.
1657 if (bundle
->getAndroidManifestFile() != NULL
) {
1658 // place at root of zip.
1659 String8
srcFile(bundle
->getAndroidManifestFile());
1660 addFile(srcFile
.getPathLeaf(), AaptGroupEntry(), srcFile
.getPathDir(),
1666 * If a directory of custom assets was supplied, slurp 'em up.
1668 if (bundle
->getAssetSourceDir()) {
1669 const char* assetDir
= bundle
->getAssetSourceDir();
1671 FileType type
= getFileType(assetDir
);
1672 if (type
== kFileTypeNonexistent
) {
1673 fprintf(stderr
, "ERROR: asset directory '%s' does not exist\n", assetDir
);
1674 return UNKNOWN_ERROR
;
1676 if (type
!= kFileTypeDirectory
) {
1677 fprintf(stderr
, "ERROR: '%s' is not a directory\n", assetDir
);
1678 return UNKNOWN_ERROR
;
1681 String8
assetRoot(assetDir
);
1682 sp
<AaptDir
> assetAaptDir
= makeDir(String8(kAssetDir
));
1683 AaptGroupEntry group
;
1684 count
= assetAaptDir
->slurpFullTree(bundle
, assetRoot
, group
,
1691 mGroupEntries
.add(group
);
1693 totalCount
+= count
;
1695 if (bundle
->getVerbose())
1696 printf("Found %d custom asset file%s in %s\n",
1697 count
, (count
==1) ? "" : "s", assetDir
);
1701 * If a directory of resource-specific assets was supplied, slurp 'em up.
1703 for (size_t i
=0; i
<dirCount
; i
++) {
1704 const char *res
= resDirs
[i
];
1706 type
= getFileType(res
);
1707 if (type
== kFileTypeNonexistent
) {
1708 fprintf(stderr
, "ERROR: resource directory '%s' does not exist\n", res
);
1709 return UNKNOWN_ERROR
;
1711 if (type
== kFileTypeDirectory
) {
1713 sp
<AaptAssets
> nextOverlay
= new AaptAssets();
1714 current
->setOverlay(nextOverlay
);
1715 current
= nextOverlay
;
1717 count
= current
->slurpResourceTree(bundle
, String8(res
));
1723 totalCount
+= count
;
1726 fprintf(stderr
, "ERROR: '%s' is not a directory\n", res
);
1727 return UNKNOWN_ERROR
;
1733 * Now do any additional raw files.
1735 for (int arg
=0; arg
<N
; arg
++) {
1736 const char* assetDir
= bundle
->getFileSpecEntry(arg
);
1738 FileType type
= getFileType(assetDir
);
1739 if (type
== kFileTypeNonexistent
) {
1740 fprintf(stderr
, "ERROR: input directory '%s' does not exist\n", assetDir
);
1741 return UNKNOWN_ERROR
;
1743 if (type
!= kFileTypeDirectory
) {
1744 fprintf(stderr
, "ERROR: '%s' is not a directory\n", assetDir
);
1745 return UNKNOWN_ERROR
;
1748 String8
assetRoot(assetDir
);
1750 if (bundle
->getVerbose())
1751 printf("Processing raw dir '%s'\n", (const char*) assetDir
);
1754 * Do a recursive traversal of subdir tree. We don't make any
1755 * guarantees about ordering, so we're okay with an inorder search
1756 * using whatever order the OS happens to hand back to us.
1758 count
= slurpFullTree(bundle
, assetRoot
, AaptGroupEntry(), String8());
1760 /* failure; report error and remove archive */
1764 totalCount
+= count
;
1766 if (bundle
->getVerbose())
1767 printf("Found %d asset file%s in %s\n",
1768 count
, (count
==1) ? "" : "s", assetDir
);
1772 if (count
!= NO_ERROR
) {
1782 ssize_t
AaptAssets::slurpFullTree(Bundle
* bundle
, const String8
& srcDir
,
1783 const AaptGroupEntry
& kind
,
1784 const String8
& resType
)
1786 ssize_t res
= AaptDir::slurpFullTree(bundle
, srcDir
, kind
, resType
);
1788 mGroupEntries
.add(kind
);
1794 ssize_t
AaptAssets::slurpResourceTree(Bundle
* bundle
, const String8
& srcDir
)
1798 DIR* dir
= opendir(srcDir
.string());
1800 fprintf(stderr
, "ERROR: opendir(%s): %s\n", srcDir
.string(), strerror(errno
));
1801 return UNKNOWN_ERROR
;
1807 * Run through the directory, looking for dirs that match the
1811 struct dirent
* entry
= readdir(dir
);
1812 if (entry
== NULL
) {
1816 if (isHidden(srcDir
.string(), entry
->d_name
)) {
1820 String8
subdirName(srcDir
);
1821 subdirName
.appendPath(entry
->d_name
);
1823 AaptGroupEntry group
;
1825 bool b
= group
.initFromDirName(entry
->d_name
, &resType
);
1827 fprintf(stderr
, "invalid resource directory name: %s/%s\n", srcDir
.string(),
1833 FileType type
= getFileType(subdirName
.string());
1835 if (type
== kFileTypeDirectory
) {
1836 sp
<AaptDir
> dir
= makeDir(String8(entry
->d_name
));
1837 ssize_t res
= dir
->slurpFullTree(bundle
, subdirName
, group
,
1844 mGroupEntries
.add(group
);
1850 if (bundle
->getVerbose()) {
1851 fprintf(stderr
, " (ignoring file '%s')\n", subdirName
.string());
1867 AaptAssets::slurpResourceZip(Bundle
* bundle
, const char* filename
)
1870 SortedVector
<AaptGroupEntry
> entries
;
1872 ZipFile
* zip
= new ZipFile
;
1873 status_t err
= zip
->open(filename
, ZipFile::kOpenReadOnly
);
1874 if (err
!= NO_ERROR
) {
1875 fprintf(stderr
, "error opening zip file %s\n", filename
);
1881 const int N
= zip
->getNumEntries();
1882 for (int i
=0; i
<N
; i
++) {
1883 ZipEntry
* entry
= zip
->getEntryByIndex(i
);
1884 if (entry
->getDeleted()) {
1888 String8
entryName(entry
->getFileName());
1890 String8 dirName
= entryName
.getPathDir();
1891 sp
<AaptDir
> dir
= dirName
== "" ? this : makeDir(dirName
);
1894 AaptGroupEntry kind
;
1897 if (entryName
.walkPath(&remain
) == kResourceDir
) {
1898 // these are the resources, pull their type out of the directory name
1899 kind
.initFromDirName(remain
.walkPath().string(), &resType
);
1901 // these are untyped and don't have an AaptGroupEntry
1903 if (entries
.indexOf(kind
) < 0) {
1905 mGroupEntries
.add(kind
);
1908 // use the one from the zip file if they both exist.
1909 dir
->removeFile(entryName
.getPathLeaf());
1911 sp
<AaptFile
> file
= new AaptFile(entryName
, kind
, resType
);
1912 status_t err
= dir
->addLeafFile(entryName
.getPathLeaf(), file
);
1913 if (err
!= NO_ERROR
) {
1914 fprintf(stderr
, "err=%s entryName=%s\n", strerror(err
), entryName
.string());
1918 file
->setCompressionMethod(entry
->getCompressionMethod());
1921 if (entryName
== "AndroidManifest.xml") {
1922 printf("AndroidManifest.xml\n");
1924 printf("\n\nfile: %s\n", entryName
.string());
1927 size_t len
= entry
->getUncompressedLen();
1928 void* data
= zip
->uncompress(entry
);
1929 void* buf
= file
->editData(len
);
1930 memcpy(buf
, data
, len
);
1934 const unsigned char* p
= (unsigned char*)data
;
1935 const unsigned char* end
= p
+len
;
1937 for (int i
=0; i
<32 && p
< end
; i
++) {
1938 printf("0x%03x ", i
*0x10 + OFF
);
1939 for (int j
=0; j
<0x10 && p
< end
; j
++) {
1940 printf(" %02x", *p
);
1957 sp
<AaptSymbols
> AaptAssets::getSymbolsFor(const String8
& name
)
1959 sp
<AaptSymbols
> sym
= mSymbols
.valueFor(name
);
1961 sym
= new AaptSymbols();
1962 mSymbols
.add(name
, sym
);
1967 status_t
AaptAssets::buildIncludedResources(Bundle
* bundle
)
1969 if (!mHaveIncludedAssets
) {
1970 // Add in all includes.
1971 const Vector
<const char*>& incl
= bundle
->getPackageIncludes();
1972 const size_t N
=incl
.size();
1973 for (size_t i
=0; i
<N
; i
++) {
1974 if (bundle
->getVerbose())
1975 printf("Including resources from package: %s\n", incl
[i
]);
1976 if (!mIncludedAssets
.addAssetPath(String8(incl
[i
]), NULL
)) {
1977 fprintf(stderr
, "ERROR: Asset package include '%s' not found.\n",
1979 return UNKNOWN_ERROR
;
1982 mHaveIncludedAssets
= true;
1988 status_t
AaptAssets::addIncludedResources(const sp
<AaptFile
>& file
)
1990 const ResTable
& res
= getIncludedResources();
1992 return const_cast<ResTable
&>(res
).add(file
->getData(), file
->getSize(), NULL
);
1995 const ResTable
& AaptAssets::getIncludedResources() const
1997 return mIncludedAssets
.getResources(false);
2000 void AaptAssets::print() const
2002 printf("Locale/Vendor pairs:\n");
2003 const size_t N
=mGroupEntries
.size();
2004 for (size_t i
=0; i
<N
; i
++) {
2006 mGroupEntries
.itemAt(i
).locale
.string(),
2007 mGroupEntries
.itemAt(i
).vendor
.string());
2010 printf("\nFiles:\n");
2014 sp
<AaptDir
> AaptAssets::resDir(const String8
& name
)
2016 const Vector
<sp
<AaptDir
> >& dirs
= mDirs
;
2017 const size_t N
= dirs
.size();
2018 for (size_t i
=0; i
<N
; i
++) {
2019 const sp
<AaptDir
>& d
= dirs
.itemAt(i
);
2020 if (d
->getLeaf() == name
) {
2028 valid_symbol_name(const String8
& symbol
)
2030 static char const * const KEYWORDS
[] = {
2031 "abstract", "assert", "boolean", "break",
2032 "byte", "case", "catch", "char", "class", "const", "continue",
2033 "default", "do", "double", "else", "enum", "extends", "final",
2034 "finally", "float", "for", "goto", "if", "implements", "import",
2035 "instanceof", "int", "interface", "long", "native", "new", "package",
2036 "private", "protected", "public", "return", "short", "static",
2037 "strictfp", "super", "switch", "synchronized", "this", "throw",
2038 "throws", "transient", "try", "void", "volatile", "while",
2039 "true", "false", "null",
2042 const char*const* k
= KEYWORDS
;
2043 const char*const s
= symbol
.string();
2045 if (0 == strcmp(s
, *k
)) {