]>
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
;
774 bool AaptGroupEntry::getScreenLayoutLongName(const char* name
,
775 ResTable_config
* out
)
777 if (strcmp(name
, kWildcardName
) == 0) {
778 if (out
) out
->screenLayout
=
779 (out
->screenLayout
&~ResTable_config::MASK_SCREENLONG
)
780 | ResTable_config::SCREENLONG_ANY
;
782 } else if (strcmp(name
, "long") == 0) {
783 if (out
) out
->screenLayout
=
784 (out
->screenLayout
&~ResTable_config::MASK_SCREENLONG
)
785 | ResTable_config::SCREENLONG_YES
;
787 } else if (strcmp(name
, "notlong") == 0) {
788 if (out
) out
->screenLayout
=
789 (out
->screenLayout
&~ResTable_config::MASK_SCREENLONG
)
790 | ResTable_config::SCREENLONG_NO
;
797 bool AaptGroupEntry::getOrientationName(const char* name
,
798 ResTable_config
* out
)
800 if (strcmp(name
, kWildcardName
) == 0) {
801 if (out
) out
->orientation
= out
->ORIENTATION_ANY
;
803 } else if (strcmp(name
, "port") == 0) {
804 if (out
) out
->orientation
= out
->ORIENTATION_PORT
;
806 } else if (strcmp(name
, "land") == 0) {
807 if (out
) out
->orientation
= out
->ORIENTATION_LAND
;
809 } else if (strcmp(name
, "square") == 0) {
810 if (out
) out
->orientation
= out
->ORIENTATION_SQUARE
;
817 bool AaptGroupEntry::getUiModeTypeName(const char* name
,
818 ResTable_config
* out
)
820 if (strcmp(name
, kWildcardName
) == 0) {
821 if (out
) out
->uiMode
=
822 (out
->uiMode
&~ResTable_config::MASK_UI_MODE_TYPE
)
823 | ResTable_config::UI_MODE_TYPE_ANY
;
825 } else if (strcmp(name
, "desk") == 0) {
826 if (out
) out
->uiMode
=
827 (out
->uiMode
&~ResTable_config::MASK_UI_MODE_TYPE
)
828 | ResTable_config::UI_MODE_TYPE_DESK
;
830 } else if (strcmp(name
, "car") == 0) {
831 if (out
) out
->uiMode
=
832 (out
->uiMode
&~ResTable_config::MASK_UI_MODE_TYPE
)
833 | ResTable_config::UI_MODE_TYPE_CAR
;
840 bool AaptGroupEntry::getUiModeNightName(const char* name
,
841 ResTable_config
* out
)
843 if (strcmp(name
, kWildcardName
) == 0) {
844 if (out
) out
->uiMode
=
845 (out
->uiMode
&~ResTable_config::MASK_UI_MODE_NIGHT
)
846 | ResTable_config::UI_MODE_NIGHT_ANY
;
848 } else if (strcmp(name
, "night") == 0) {
849 if (out
) out
->uiMode
=
850 (out
->uiMode
&~ResTable_config::MASK_UI_MODE_NIGHT
)
851 | ResTable_config::UI_MODE_NIGHT_YES
;
853 } else if (strcmp(name
, "notnight") == 0) {
854 if (out
) out
->uiMode
=
855 (out
->uiMode
&~ResTable_config::MASK_UI_MODE_NIGHT
)
856 | ResTable_config::UI_MODE_NIGHT_NO
;
863 bool AaptGroupEntry::getDensityName(const char* name
,
864 ResTable_config
* out
)
866 if (strcmp(name
, kWildcardName
) == 0) {
867 if (out
) out
->density
= ResTable_config::DENSITY_DEFAULT
;
871 if (strcmp(name
, "nodpi") == 0) {
872 if (out
) out
->density
= ResTable_config::DENSITY_NONE
;
876 if (strcmp(name
, "ldpi") == 0) {
877 if (out
) out
->density
= ResTable_config::DENSITY_LOW
;
881 if (strcmp(name
, "mdpi") == 0) {
882 if (out
) out
->density
= ResTable_config::DENSITY_MEDIUM
;
886 if (strcmp(name
, "hdpi") == 0) {
887 if (out
) out
->density
= ResTable_config::DENSITY_HIGH
;
891 if (strcmp(name
, "xhdpi") == 0) {
892 if (out
) out
->density
= ResTable_config::DENSITY_MEDIUM
*2;
896 char* c
= (char*)name
;
897 while (*c
>= '0' && *c
<= '9') {
901 // check that we have 'dpi' after the last digit.
902 if (toupper(c
[0]) != 'D' ||
903 toupper(c
[1]) != 'P' ||
904 toupper(c
[2]) != 'I' ||
909 // temporarily replace the first letter with \0 to
918 if (out
) out
->density
= d
;
925 bool AaptGroupEntry::getTouchscreenName(const char* name
,
926 ResTable_config
* out
)
928 if (strcmp(name
, kWildcardName
) == 0) {
929 if (out
) out
->touchscreen
= out
->TOUCHSCREEN_ANY
;
931 } else if (strcmp(name
, "notouch") == 0) {
932 if (out
) out
->touchscreen
= out
->TOUCHSCREEN_NOTOUCH
;
934 } else if (strcmp(name
, "stylus") == 0) {
935 if (out
) out
->touchscreen
= out
->TOUCHSCREEN_STYLUS
;
937 } else if (strcmp(name
, "finger") == 0) {
938 if (out
) out
->touchscreen
= out
->TOUCHSCREEN_FINGER
;
945 bool AaptGroupEntry::getKeysHiddenName(const char* name
,
946 ResTable_config
* out
)
950 if (strcmp(name
, kWildcardName
) == 0) {
951 mask
= ResTable_config::MASK_KEYSHIDDEN
;
952 value
= ResTable_config::KEYSHIDDEN_ANY
;
953 } else if (strcmp(name
, "keysexposed") == 0) {
954 mask
= ResTable_config::MASK_KEYSHIDDEN
;
955 value
= ResTable_config::KEYSHIDDEN_NO
;
956 } else if (strcmp(name
, "keyshidden") == 0) {
957 mask
= ResTable_config::MASK_KEYSHIDDEN
;
958 value
= ResTable_config::KEYSHIDDEN_YES
;
959 } else if (strcmp(name
, "keyssoft") == 0) {
960 mask
= ResTable_config::MASK_KEYSHIDDEN
;
961 value
= ResTable_config::KEYSHIDDEN_SOFT
;
965 if (out
) out
->inputFlags
= (out
->inputFlags
&~mask
) | value
;
972 bool AaptGroupEntry::getKeyboardName(const char* name
,
973 ResTable_config
* out
)
975 if (strcmp(name
, kWildcardName
) == 0) {
976 if (out
) out
->keyboard
= out
->KEYBOARD_ANY
;
978 } else if (strcmp(name
, "nokeys") == 0) {
979 if (out
) out
->keyboard
= out
->KEYBOARD_NOKEYS
;
981 } else if (strcmp(name
, "qwerty") == 0) {
982 if (out
) out
->keyboard
= out
->KEYBOARD_QWERTY
;
984 } else if (strcmp(name
, "12key") == 0) {
985 if (out
) out
->keyboard
= out
->KEYBOARD_12KEY
;
992 bool AaptGroupEntry::getNavHiddenName(const char* name
,
993 ResTable_config
* out
)
997 if (strcmp(name
, kWildcardName
) == 0) {
998 mask
= ResTable_config::MASK_NAVHIDDEN
;
999 value
= ResTable_config::NAVHIDDEN_ANY
;
1000 } else if (strcmp(name
, "navexposed") == 0) {
1001 mask
= ResTable_config::MASK_NAVHIDDEN
;
1002 value
= ResTable_config::NAVHIDDEN_NO
;
1003 } else if (strcmp(name
, "navhidden") == 0) {
1004 mask
= ResTable_config::MASK_NAVHIDDEN
;
1005 value
= ResTable_config::NAVHIDDEN_YES
;
1009 if (out
) out
->inputFlags
= (out
->inputFlags
&~mask
) | value
;
1016 bool AaptGroupEntry::getNavigationName(const char* name
,
1017 ResTable_config
* out
)
1019 if (strcmp(name
, kWildcardName
) == 0) {
1020 if (out
) out
->navigation
= out
->NAVIGATION_ANY
;
1022 } else if (strcmp(name
, "nonav") == 0) {
1023 if (out
) out
->navigation
= out
->NAVIGATION_NONAV
;
1025 } else if (strcmp(name
, "dpad") == 0) {
1026 if (out
) out
->navigation
= out
->NAVIGATION_DPAD
;
1028 } else if (strcmp(name
, "trackball") == 0) {
1029 if (out
) out
->navigation
= out
->NAVIGATION_TRACKBALL
;
1031 } else if (strcmp(name
, "wheel") == 0) {
1032 if (out
) out
->navigation
= out
->NAVIGATION_WHEEL
;
1039 bool AaptGroupEntry::getScreenSizeName(const char* name
,
1040 ResTable_config
* out
)
1042 if (strcmp(name
, kWildcardName
) == 0) {
1044 out
->screenWidth
= out
->SCREENWIDTH_ANY
;
1045 out
->screenHeight
= out
->SCREENHEIGHT_ANY
;
1050 const char* x
= name
;
1051 while (*x
>= '0' && *x
<= '9') x
++;
1052 if (x
== name
|| *x
!= 'x') return false;
1053 String8
xName(name
, x
-name
);
1057 while (*y
>= '0' && *y
<= '9') y
++;
1058 if (y
== name
|| *y
!= 0) return false;
1059 String8
yName(x
, y
-x
);
1061 uint16_t w
= (uint16_t)atoi(xName
.string());
1062 uint16_t h
= (uint16_t)atoi(yName
.string());
1068 out
->screenWidth
= w
;
1069 out
->screenHeight
= h
;
1075 bool AaptGroupEntry::getVersionName(const char* name
,
1076 ResTable_config
* out
)
1078 if (strcmp(name
, kWildcardName
) == 0) {
1080 out
->sdkVersion
= out
->SDKVERSION_ANY
;
1081 out
->minorVersion
= out
->MINORVERSION_ANY
;
1091 const char* s
= name
;
1092 while (*s
>= '0' && *s
<= '9') s
++;
1093 if (s
== name
|| *s
!= 0) return false;
1094 String8
sdkName(name
, s
-name
);
1097 out
->sdkVersion
= (uint16_t)atoi(sdkName
.string());
1098 out
->minorVersion
= 0;
1104 int AaptGroupEntry::compare(const AaptGroupEntry
& o
) const
1106 int v
= mcc
.compare(o
.mcc
);
1107 if (v
== 0) v
= mnc
.compare(o
.mnc
);
1108 if (v
== 0) v
= locale
.compare(o
.locale
);
1109 if (v
== 0) v
= vendor
.compare(o
.vendor
);
1110 if (v
== 0) v
= screenLayoutSize
.compare(o
.screenLayoutSize
);
1111 if (v
== 0) v
= screenLayoutLong
.compare(o
.screenLayoutLong
);
1112 if (v
== 0) v
= orientation
.compare(o
.orientation
);
1113 if (v
== 0) v
= uiModeType
.compare(o
.uiModeType
);
1114 if (v
== 0) v
= uiModeNight
.compare(o
.uiModeNight
);
1115 if (v
== 0) v
= density
.compare(o
.density
);
1116 if (v
== 0) v
= touchscreen
.compare(o
.touchscreen
);
1117 if (v
== 0) v
= keysHidden
.compare(o
.keysHidden
);
1118 if (v
== 0) v
= keyboard
.compare(o
.keyboard
);
1119 if (v
== 0) v
= navHidden
.compare(o
.navHidden
);
1120 if (v
== 0) v
= navigation
.compare(o
.navigation
);
1121 if (v
== 0) v
= screenSize
.compare(o
.screenSize
);
1122 if (v
== 0) v
= version
.compare(o
.version
);
1126 ResTable_config
AaptGroupEntry::toParams() const
1128 ResTable_config params
;
1129 memset(¶ms
, 0, sizeof(params
));
1130 getMccName(mcc
.string(), ¶ms
);
1131 getMncName(mnc
.string(), ¶ms
);
1132 getLocaleName(locale
.string(), ¶ms
);
1133 getScreenLayoutSizeName(screenLayoutSize
.string(), ¶ms
);
1134 getScreenLayoutLongName(screenLayoutLong
.string(), ¶ms
);
1135 getOrientationName(orientation
.string(), ¶ms
);
1136 getUiModeTypeName(uiModeType
.string(), ¶ms
);
1137 getUiModeNightName(uiModeNight
.string(), ¶ms
);
1138 getDensityName(density
.string(), ¶ms
);
1139 getTouchscreenName(touchscreen
.string(), ¶ms
);
1140 getKeysHiddenName(keysHidden
.string(), ¶ms
);
1141 getKeyboardName(keyboard
.string(), ¶ms
);
1142 getNavHiddenName(navHidden
.string(), ¶ms
);
1143 getNavigationName(navigation
.string(), ¶ms
);
1144 getScreenSizeName(screenSize
.string(), ¶ms
);
1145 getVersionName(version
.string(), ¶ms
);
1147 // Fix up version number based on specified parameters.
1149 if ((params
.uiMode
&ResTable_config::MASK_UI_MODE_TYPE
)
1150 != ResTable_config::UI_MODE_TYPE_ANY
1151 || (params
.uiMode
&ResTable_config::MASK_UI_MODE_NIGHT
)
1152 != ResTable_config::UI_MODE_NIGHT_ANY
) {
1154 } else if ((params
.screenLayout
&ResTable_config::MASK_SCREENSIZE
)
1155 != ResTable_config::SCREENSIZE_ANY
1156 || (params
.screenLayout
&ResTable_config::MASK_SCREENLONG
)
1157 != ResTable_config::SCREENLONG_ANY
1158 || params
.density
!= ResTable_config::DENSITY_DEFAULT
) {
1162 if (minSdk
> params
.sdkVersion
) {
1163 params
.sdkVersion
= minSdk
;
1169 // =========================================================================
1170 // =========================================================================
1171 // =========================================================================
1173 void* AaptFile::editData(size_t size
)
1175 if (size
<= mBufferSize
) {
1179 size_t allocSize
= (size
*3)/2;
1180 void* buf
= realloc(mData
, allocSize
);
1186 mBufferSize
= allocSize
;
1190 void* AaptFile::editData(size_t* outSize
)
1193 *outSize
= mDataSize
;
1198 void* AaptFile::padData(size_t wordSize
)
1200 const size_t extra
= mDataSize%wordSize
;
1205 size_t initial
= mDataSize
;
1206 void* data
= editData(initial
+(wordSize
-extra
));
1208 memset(((uint8_t*)data
) + initial
, 0, wordSize
-extra
);
1213 status_t
AaptFile::writeData(const void* data
, size_t size
)
1215 size_t end
= mDataSize
;
1216 size_t total
= size
+ end
;
1217 void* buf
= editData(total
);
1219 return UNKNOWN_ERROR
;
1221 memcpy(((char*)buf
)+end
, data
, size
);
1225 void AaptFile::clearData()
1227 if (mData
!= NULL
) free(mData
);
1233 String8
AaptFile::getPrintableSource() const
1236 String8
name(mGroupEntry
.locale
.string());
1237 name
.appendPath(mGroupEntry
.vendor
.string());
1238 name
.appendPath(mPath
);
1239 name
.append(" #generated");
1245 // =========================================================================
1246 // =========================================================================
1247 // =========================================================================
1249 status_t
AaptGroup::addFile(const sp
<AaptFile
>& file
)
1251 if (mFiles
.indexOfKey(file
->getGroupEntry()) < 0) {
1252 file
->mPath
= mPath
;
1253 mFiles
.add(file
->getGroupEntry(), file
);
1257 SourcePos(file
->getSourceFile(), -1).error("Duplicate file.\n%s: Original is here.",
1258 getPrintableSource().string());
1259 return UNKNOWN_ERROR
;
1262 void AaptGroup::removeFile(size_t index
)
1264 mFiles
.removeItemsAt(index
);
1267 void AaptGroup::print() const
1269 printf(" %s\n", getPath().string());
1270 const size_t N
=mFiles
.size();
1272 for (i
=0; i
<N
; i
++) {
1273 sp
<AaptFile
> file
= mFiles
.valueAt(i
);
1274 const AaptGroupEntry
& e
= file
->getGroupEntry();
1275 if (file
->hasData()) {
1276 printf(" Gen: (%s) %d bytes\n", e
.toString().string(),
1277 (int)file
->getSize());
1279 printf(" Src: %s\n", file
->getPrintableSource().string());
1284 String8
AaptGroup::getPrintableSource() const
1286 if (mFiles
.size() > 0) {
1287 // Arbitrarily pull the first source file out of the list.
1288 return mFiles
.valueAt(0)->getPrintableSource();
1291 // Should never hit this case, but to be safe...
1296 // =========================================================================
1297 // =========================================================================
1298 // =========================================================================
1300 status_t
AaptDir::addFile(const String8
& name
, const sp
<AaptGroup
>& file
)
1302 if (mFiles
.indexOfKey(name
) >= 0) {
1303 return ALREADY_EXISTS
;
1305 mFiles
.add(name
, file
);
1309 status_t
AaptDir::addDir(const String8
& name
, const sp
<AaptDir
>& dir
)
1311 if (mDirs
.indexOfKey(name
) >= 0) {
1312 return ALREADY_EXISTS
;
1314 mDirs
.add(name
, dir
);
1318 sp
<AaptDir
> AaptDir::makeDir(const String8
& path
)
1321 String8 remain
= path
;
1323 sp
<AaptDir
> subdir
= this;
1324 while (name
= remain
.walkPath(&remain
), remain
!= "") {
1325 subdir
= subdir
->makeDir(name
);
1328 ssize_t i
= subdir
->mDirs
.indexOfKey(name
);
1330 return subdir
->mDirs
.valueAt(i
);
1332 sp
<AaptDir
> dir
= new AaptDir(name
, subdir
->mPath
.appendPathCopy(name
));
1333 subdir
->mDirs
.add(name
, dir
);
1337 void AaptDir::removeFile(const String8
& name
)
1339 mFiles
.removeItem(name
);
1342 void AaptDir::removeDir(const String8
& name
)
1344 mDirs
.removeItem(name
);
1347 status_t
AaptDir::renameFile(const sp
<AaptFile
>& file
, const String8
& newName
)
1349 sp
<AaptGroup
> origGroup
;
1351 // Find and remove the given file with shear, brute force!
1352 const size_t NG
= mFiles
.size();
1354 for (i
=0; origGroup
== NULL
&& i
<NG
; i
++) {
1355 sp
<AaptGroup
> g
= mFiles
.valueAt(i
);
1356 const size_t NF
= g
->getFiles().size();
1357 for (size_t j
=0; j
<NF
; j
++) {
1358 if (g
->getFiles().valueAt(j
) == file
) {
1362 mFiles
.removeItemsAt(i
);
1369 //printf("Renaming %s to %s\n", file->getPath().getPathName(), newName.string());
1371 // Place the file under its new name.
1372 if (origGroup
!= NULL
) {
1373 return addLeafFile(newName
, file
);
1379 status_t
AaptDir::addLeafFile(const String8
& leafName
, const sp
<AaptFile
>& file
)
1381 sp
<AaptGroup
> group
;
1382 if (mFiles
.indexOfKey(leafName
) >= 0) {
1383 group
= mFiles
.valueFor(leafName
);
1385 group
= new AaptGroup(leafName
, mPath
.appendPathCopy(leafName
));
1386 mFiles
.add(leafName
, group
);
1389 return group
->addFile(file
);
1392 ssize_t
AaptDir::slurpFullTree(Bundle
* bundle
, const String8
& srcDir
,
1393 const AaptGroupEntry
& kind
, const String8
& resType
)
1395 Vector
<String8
> fileNames
;
1400 dir
= opendir(srcDir
.string());
1402 fprintf(stderr
, "ERROR: opendir(%s): %s\n", srcDir
.string(), strerror(errno
));
1403 return UNKNOWN_ERROR
;
1407 * Slurp the filenames out of the directory.
1410 struct dirent
* entry
;
1412 entry
= readdir(dir
);
1416 if (isHidden(srcDir
.string(), entry
->d_name
))
1419 fileNames
.add(String8(entry
->d_name
));
1428 * Stash away the files and recursively descend into subdirectories.
1430 const size_t N
= fileNames
.size();
1432 for (i
= 0; i
< N
; i
++) {
1433 String8
pathName(srcDir
);
1436 pathName
.appendPath(fileNames
[i
].string());
1437 type
= getFileType(pathName
.string());
1438 if (type
== kFileTypeDirectory
) {
1440 bool notAdded
= false;
1441 if (mDirs
.indexOfKey(fileNames
[i
]) >= 0) {
1442 subdir
= mDirs
.valueFor(fileNames
[i
]);
1444 subdir
= new AaptDir(fileNames
[i
], mPath
.appendPathCopy(fileNames
[i
]));
1447 ssize_t res
= subdir
->slurpFullTree(bundle
, pathName
, kind
,
1449 if (res
< NO_ERROR
) {
1452 if (res
> 0 && notAdded
) {
1453 mDirs
.add(fileNames
[i
], subdir
);
1456 } else if (type
== kFileTypeRegular
) {
1457 sp
<AaptFile
> file
= new AaptFile(pathName
, kind
, resType
);
1458 status_t err
= addLeafFile(fileNames
[i
], file
);
1459 if (err
!= NO_ERROR
) {
1466 if (bundle
->getVerbose())
1467 printf(" (ignoring non-file/dir '%s')\n", pathName
.string());
1474 status_t
AaptDir::validate() const
1476 const size_t NF
= mFiles
.size();
1477 const size_t ND
= mDirs
.size();
1479 for (i
= 0; i
< NF
; i
++) {
1480 if (!validateFileName(mFiles
.valueAt(i
)->getLeaf().string())) {
1481 SourcePos(mFiles
.valueAt(i
)->getPrintableSource(), -1).error(
1482 "Invalid filename. Unable to add.");
1483 return UNKNOWN_ERROR
;
1487 for (j
= i
+1; j
< NF
; j
++) {
1488 if (strcasecmp(mFiles
.valueAt(i
)->getLeaf().string(),
1489 mFiles
.valueAt(j
)->getLeaf().string()) == 0) {
1490 SourcePos(mFiles
.valueAt(i
)->getPrintableSource(), -1).error(
1491 "File is case-insensitive equivalent to: %s",
1492 mFiles
.valueAt(j
)->getPrintableSource().string());
1493 return UNKNOWN_ERROR
;
1496 // TODO: if ".gz", check for non-.gz; if non-, check for ".gz"
1497 // (this is mostly caught by the "marked" stuff, below)
1500 for (j
= 0; j
< ND
; j
++) {
1501 if (strcasecmp(mFiles
.valueAt(i
)->getLeaf().string(),
1502 mDirs
.valueAt(j
)->getLeaf().string()) == 0) {
1503 SourcePos(mFiles
.valueAt(i
)->getPrintableSource(), -1).error(
1504 "File conflicts with dir from: %s",
1505 mDirs
.valueAt(j
)->getPrintableSource().string());
1506 return UNKNOWN_ERROR
;
1511 for (i
= 0; i
< ND
; i
++) {
1512 if (!validateFileName(mDirs
.valueAt(i
)->getLeaf().string())) {
1513 SourcePos(mDirs
.valueAt(i
)->getPrintableSource(), -1).error(
1514 "Invalid directory name, unable to add.");
1515 return UNKNOWN_ERROR
;
1519 for (j
= i
+1; j
< ND
; j
++) {
1520 if (strcasecmp(mDirs
.valueAt(i
)->getLeaf().string(),
1521 mDirs
.valueAt(j
)->getLeaf().string()) == 0) {
1522 SourcePos(mDirs
.valueAt(i
)->getPrintableSource(), -1).error(
1523 "Directory is case-insensitive equivalent to: %s",
1524 mDirs
.valueAt(j
)->getPrintableSource().string());
1525 return UNKNOWN_ERROR
;
1529 status_t err
= mDirs
.valueAt(i
)->validate();
1530 if (err
!= NO_ERROR
) {
1538 void AaptDir::print() const
1540 const size_t ND
=getDirs().size();
1542 for (i
=0; i
<ND
; i
++) {
1543 getDirs().valueAt(i
)->print();
1546 const size_t NF
=getFiles().size();
1547 for (i
=0; i
<NF
; i
++) {
1548 getFiles().valueAt(i
)->print();
1552 String8
AaptDir::getPrintableSource() const
1554 if (mFiles
.size() > 0) {
1555 // Arbitrarily pull the first file out of the list as the source dir.
1556 return mFiles
.valueAt(0)->getPrintableSource().getPathDir();
1558 if (mDirs
.size() > 0) {
1559 // Or arbitrarily pull the first dir out of the list as the source dir.
1560 return mDirs
.valueAt(0)->getPrintableSource().getPathDir();
1563 // Should never hit this case, but to be safe...
1568 // =========================================================================
1569 // =========================================================================
1570 // =========================================================================
1572 sp
<AaptFile
> AaptAssets::addFile(
1573 const String8
& filePath
, const AaptGroupEntry
& entry
,
1574 const String8
& srcDir
, sp
<AaptGroup
>* outGroup
,
1575 const String8
& resType
)
1577 sp
<AaptDir
> dir
= this;
1578 sp
<AaptGroup
> group
;
1580 String8 root
, remain(filePath
), partialPath
;
1581 while (remain
.length() > 0) {
1582 root
= remain
.walkPath(&remain
);
1583 partialPath
.appendPath(root
);
1585 const String8
rootStr(root
);
1587 if (remain
.length() == 0) {
1588 ssize_t i
= dir
->getFiles().indexOfKey(rootStr
);
1590 group
= dir
->getFiles().valueAt(i
);
1592 group
= new AaptGroup(rootStr
, filePath
);
1593 status_t res
= dir
->addFile(rootStr
, group
);
1594 if (res
!= NO_ERROR
) {
1598 file
= new AaptFile(srcDir
.appendPathCopy(filePath
), entry
, resType
);
1599 status_t res
= group
->addFile(file
);
1600 if (res
!= NO_ERROR
) {
1606 ssize_t i
= dir
->getDirs().indexOfKey(rootStr
);
1608 dir
= dir
->getDirs().valueAt(i
);
1610 sp
<AaptDir
> subdir
= new AaptDir(rootStr
, partialPath
);
1611 status_t res
= dir
->addDir(rootStr
, subdir
);
1612 if (res
!= NO_ERROR
) {
1620 mGroupEntries
.add(entry
);
1621 if (outGroup
) *outGroup
= group
;
1625 void AaptAssets::addResource(const String8
& leafName
, const String8
& path
,
1626 const sp
<AaptFile
>& file
, const String8
& resType
)
1628 sp
<AaptDir
> res
= AaptDir::makeDir(kResString
);
1629 String8 dirname
= file
->getGroupEntry().toDirName(resType
);
1630 sp
<AaptDir
> subdir
= res
->makeDir(dirname
);
1631 sp
<AaptGroup
> grr
= new AaptGroup(leafName
, path
);
1634 subdir
->addFile(leafName
, grr
);
1638 ssize_t
AaptAssets::slurpFromArgs(Bundle
* bundle
)
1643 const Vector
<const char *>& resDirs
= bundle
->getResourceSourceDirs();
1644 const size_t dirCount
=resDirs
.size();
1645 sp
<AaptAssets
> current
= this;
1647 const int N
= bundle
->getFileSpecCount();
1650 * If a package manifest was specified, include that first.
1652 if (bundle
->getAndroidManifestFile() != NULL
) {
1653 // place at root of zip.
1654 String8
srcFile(bundle
->getAndroidManifestFile());
1655 addFile(srcFile
.getPathLeaf(), AaptGroupEntry(), srcFile
.getPathDir(),
1661 * If a directory of custom assets was supplied, slurp 'em up.
1663 if (bundle
->getAssetSourceDir()) {
1664 const char* assetDir
= bundle
->getAssetSourceDir();
1666 FileType type
= getFileType(assetDir
);
1667 if (type
== kFileTypeNonexistent
) {
1668 fprintf(stderr
, "ERROR: asset directory '%s' does not exist\n", assetDir
);
1669 return UNKNOWN_ERROR
;
1671 if (type
!= kFileTypeDirectory
) {
1672 fprintf(stderr
, "ERROR: '%s' is not a directory\n", assetDir
);
1673 return UNKNOWN_ERROR
;
1676 String8
assetRoot(assetDir
);
1677 sp
<AaptDir
> assetAaptDir
= makeDir(String8(kAssetDir
));
1678 AaptGroupEntry group
;
1679 count
= assetAaptDir
->slurpFullTree(bundle
, assetRoot
, group
,
1686 mGroupEntries
.add(group
);
1688 totalCount
+= count
;
1690 if (bundle
->getVerbose())
1691 printf("Found %d custom asset file%s in %s\n",
1692 count
, (count
==1) ? "" : "s", assetDir
);
1696 * If a directory of resource-specific assets was supplied, slurp 'em up.
1698 for (size_t i
=0; i
<dirCount
; i
++) {
1699 const char *res
= resDirs
[i
];
1701 type
= getFileType(res
);
1702 if (type
== kFileTypeNonexistent
) {
1703 fprintf(stderr
, "ERROR: resource directory '%s' does not exist\n", res
);
1704 return UNKNOWN_ERROR
;
1706 if (type
== kFileTypeDirectory
) {
1708 sp
<AaptAssets
> nextOverlay
= new AaptAssets();
1709 current
->setOverlay(nextOverlay
);
1710 current
= nextOverlay
;
1712 count
= current
->slurpResourceTree(bundle
, String8(res
));
1718 totalCount
+= count
;
1721 fprintf(stderr
, "ERROR: '%s' is not a directory\n", res
);
1722 return UNKNOWN_ERROR
;
1728 * Now do any additional raw files.
1730 for (int arg
=0; arg
<N
; arg
++) {
1731 const char* assetDir
= bundle
->getFileSpecEntry(arg
);
1733 FileType type
= getFileType(assetDir
);
1734 if (type
== kFileTypeNonexistent
) {
1735 fprintf(stderr
, "ERROR: input directory '%s' does not exist\n", assetDir
);
1736 return UNKNOWN_ERROR
;
1738 if (type
!= kFileTypeDirectory
) {
1739 fprintf(stderr
, "ERROR: '%s' is not a directory\n", assetDir
);
1740 return UNKNOWN_ERROR
;
1743 String8
assetRoot(assetDir
);
1745 if (bundle
->getVerbose())
1746 printf("Processing raw dir '%s'\n", (const char*) assetDir
);
1749 * Do a recursive traversal of subdir tree. We don't make any
1750 * guarantees about ordering, so we're okay with an inorder search
1751 * using whatever order the OS happens to hand back to us.
1753 count
= slurpFullTree(bundle
, assetRoot
, AaptGroupEntry(), String8());
1755 /* failure; report error and remove archive */
1759 totalCount
+= count
;
1761 if (bundle
->getVerbose())
1762 printf("Found %d asset file%s in %s\n",
1763 count
, (count
==1) ? "" : "s", assetDir
);
1767 if (count
!= NO_ERROR
) {
1777 ssize_t
AaptAssets::slurpFullTree(Bundle
* bundle
, const String8
& srcDir
,
1778 const AaptGroupEntry
& kind
,
1779 const String8
& resType
)
1781 ssize_t res
= AaptDir::slurpFullTree(bundle
, srcDir
, kind
, resType
);
1783 mGroupEntries
.add(kind
);
1789 ssize_t
AaptAssets::slurpResourceTree(Bundle
* bundle
, const String8
& srcDir
)
1793 DIR* dir
= opendir(srcDir
.string());
1795 fprintf(stderr
, "ERROR: opendir(%s): %s\n", srcDir
.string(), strerror(errno
));
1796 return UNKNOWN_ERROR
;
1802 * Run through the directory, looking for dirs that match the
1806 struct dirent
* entry
= readdir(dir
);
1807 if (entry
== NULL
) {
1811 if (isHidden(srcDir
.string(), entry
->d_name
)) {
1815 String8
subdirName(srcDir
);
1816 subdirName
.appendPath(entry
->d_name
);
1818 AaptGroupEntry group
;
1820 bool b
= group
.initFromDirName(entry
->d_name
, &resType
);
1822 fprintf(stderr
, "invalid resource directory name: %s/%s\n", srcDir
.string(),
1828 FileType type
= getFileType(subdirName
.string());
1830 if (type
== kFileTypeDirectory
) {
1831 sp
<AaptDir
> dir
= makeDir(String8(entry
->d_name
));
1832 ssize_t res
= dir
->slurpFullTree(bundle
, subdirName
, group
,
1839 mGroupEntries
.add(group
);
1845 if (bundle
->getVerbose()) {
1846 fprintf(stderr
, " (ignoring file '%s')\n", subdirName
.string());
1862 AaptAssets::slurpResourceZip(Bundle
* bundle
, const char* filename
)
1865 SortedVector
<AaptGroupEntry
> entries
;
1867 ZipFile
* zip
= new ZipFile
;
1868 status_t err
= zip
->open(filename
, ZipFile::kOpenReadOnly
);
1869 if (err
!= NO_ERROR
) {
1870 fprintf(stderr
, "error opening zip file %s\n", filename
);
1876 const int N
= zip
->getNumEntries();
1877 for (int i
=0; i
<N
; i
++) {
1878 ZipEntry
* entry
= zip
->getEntryByIndex(i
);
1879 if (entry
->getDeleted()) {
1883 String8
entryName(entry
->getFileName());
1885 String8 dirName
= entryName
.getPathDir();
1886 sp
<AaptDir
> dir
= dirName
== "" ? this : makeDir(dirName
);
1889 AaptGroupEntry kind
;
1892 if (entryName
.walkPath(&remain
) == kResourceDir
) {
1893 // these are the resources, pull their type out of the directory name
1894 kind
.initFromDirName(remain
.walkPath().string(), &resType
);
1896 // these are untyped and don't have an AaptGroupEntry
1898 if (entries
.indexOf(kind
) < 0) {
1900 mGroupEntries
.add(kind
);
1903 // use the one from the zip file if they both exist.
1904 dir
->removeFile(entryName
.getPathLeaf());
1906 sp
<AaptFile
> file
= new AaptFile(entryName
, kind
, resType
);
1907 status_t err
= dir
->addLeafFile(entryName
.getPathLeaf(), file
);
1908 if (err
!= NO_ERROR
) {
1909 fprintf(stderr
, "err=%s entryName=%s\n", strerror(err
), entryName
.string());
1913 file
->setCompressionMethod(entry
->getCompressionMethod());
1916 if (entryName
== "AndroidManifest.xml") {
1917 printf("AndroidManifest.xml\n");
1919 printf("\n\nfile: %s\n", entryName
.string());
1922 size_t len
= entry
->getUncompressedLen();
1923 void* data
= zip
->uncompress(entry
);
1924 void* buf
= file
->editData(len
);
1925 memcpy(buf
, data
, len
);
1929 const unsigned char* p
= (unsigned char*)data
;
1930 const unsigned char* end
= p
+len
;
1932 for (int i
=0; i
<32 && p
< end
; i
++) {
1933 printf("0x%03x ", i
*0x10 + OFF
);
1934 for (int j
=0; j
<0x10 && p
< end
; j
++) {
1935 printf(" %02x", *p
);
1952 sp
<AaptSymbols
> AaptAssets::getSymbolsFor(const String8
& name
)
1954 sp
<AaptSymbols
> sym
= mSymbols
.valueFor(name
);
1956 sym
= new AaptSymbols();
1957 mSymbols
.add(name
, sym
);
1962 status_t
AaptAssets::buildIncludedResources(Bundle
* bundle
)
1964 if (!mHaveIncludedAssets
) {
1965 // Add in all includes.
1966 const Vector
<const char*>& incl
= bundle
->getPackageIncludes();
1967 const size_t N
=incl
.size();
1968 for (size_t i
=0; i
<N
; i
++) {
1969 if (bundle
->getVerbose())
1970 printf("Including resources from package: %s\n", incl
[i
]);
1971 if (!mIncludedAssets
.addAssetPath(String8(incl
[i
]), NULL
)) {
1972 fprintf(stderr
, "ERROR: Asset package include '%s' not found.\n",
1974 return UNKNOWN_ERROR
;
1977 mHaveIncludedAssets
= true;
1983 status_t
AaptAssets::addIncludedResources(const sp
<AaptFile
>& file
)
1985 const ResTable
& res
= getIncludedResources();
1987 return const_cast<ResTable
&>(res
).add(file
->getData(), file
->getSize(), NULL
);
1990 const ResTable
& AaptAssets::getIncludedResources() const
1992 return mIncludedAssets
.getResources(false);
1995 void AaptAssets::print() const
1997 printf("Locale/Vendor pairs:\n");
1998 const size_t N
=mGroupEntries
.size();
1999 for (size_t i
=0; i
<N
; i
++) {
2001 mGroupEntries
.itemAt(i
).locale
.string(),
2002 mGroupEntries
.itemAt(i
).vendor
.string());
2005 printf("\nFiles:\n");
2009 sp
<AaptDir
> AaptAssets::resDir(const String8
& name
)
2011 const Vector
<sp
<AaptDir
> >& dirs
= mDirs
;
2012 const size_t N
= dirs
.size();
2013 for (size_t i
=0; i
<N
; i
++) {
2014 const sp
<AaptDir
>& d
= dirs
.itemAt(i
);
2015 if (d
->getLeaf() == name
) {
2023 valid_symbol_name(const String8
& symbol
)
2025 static char const * const KEYWORDS
[] = {
2026 "abstract", "assert", "boolean", "break",
2027 "byte", "case", "catch", "char", "class", "const", "continue",
2028 "default", "do", "double", "else", "enum", "extends", "final",
2029 "finally", "float", "for", "goto", "if", "implements", "import",
2030 "instanceof", "int", "interface", "long", "native", "new", "package",
2031 "private", "protected", "public", "return", "short", "static",
2032 "strictfp", "super", "switch", "synchronized", "this", "throw",
2033 "throws", "transient", "try", "void", "volatile", "while",
2034 "true", "false", "null",
2037 const char*const* k
= KEYWORDS
;
2038 const char*const s
= symbol
.string();
2040 if (0 == strcmp(s
, *k
)) {