]>
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_NORMAL
;
825 } else if (strcmp(name
, "car") == 0) {
826 if (out
) out
->uiMode
=
827 (out
->uiMode
&~ResTable_config::MASK_UI_MODE_TYPE
)
828 | ResTable_config::UI_MODE_TYPE_CAR
;
835 bool AaptGroupEntry::getUiModeNightName(const char* name
,
836 ResTable_config
* out
)
838 if (strcmp(name
, kWildcardName
) == 0) {
839 if (out
) out
->uiMode
=
840 (out
->uiMode
&~ResTable_config::MASK_UI_MODE_NIGHT
)
841 | ResTable_config::UI_MODE_NIGHT_ANY
;
843 } else if (strcmp(name
, "night") == 0) {
844 if (out
) out
->uiMode
=
845 (out
->uiMode
&~ResTable_config::MASK_UI_MODE_NIGHT
)
846 | ResTable_config::UI_MODE_NIGHT_YES
;
848 } else if (strcmp(name
, "notnight") == 0) {
849 if (out
) out
->uiMode
=
850 (out
->uiMode
&~ResTable_config::MASK_UI_MODE_NIGHT
)
851 | ResTable_config::UI_MODE_NIGHT_NO
;
858 bool AaptGroupEntry::getDensityName(const char* name
,
859 ResTable_config
* out
)
861 if (strcmp(name
, kWildcardName
) == 0) {
862 if (out
) out
->density
= ResTable_config::DENSITY_DEFAULT
;
866 if (strcmp(name
, "nodpi") == 0) {
867 if (out
) out
->density
= ResTable_config::DENSITY_NONE
;
871 if (strcmp(name
, "ldpi") == 0) {
872 if (out
) out
->density
= ResTable_config::DENSITY_LOW
;
876 if (strcmp(name
, "mdpi") == 0) {
877 if (out
) out
->density
= ResTable_config::DENSITY_MEDIUM
;
881 if (strcmp(name
, "hdpi") == 0) {
882 if (out
) out
->density
= ResTable_config::DENSITY_HIGH
;
886 char* c
= (char*)name
;
887 while (*c
>= '0' && *c
<= '9') {
891 // check that we have 'dpi' after the last digit.
892 if (toupper(c
[0]) != 'D' ||
893 toupper(c
[1]) != 'P' ||
894 toupper(c
[2]) != 'I' ||
899 // temporarily replace the first letter with \0 to
908 if (out
) out
->density
= d
;
915 bool AaptGroupEntry::getTouchscreenName(const char* name
,
916 ResTable_config
* out
)
918 if (strcmp(name
, kWildcardName
) == 0) {
919 if (out
) out
->touchscreen
= out
->TOUCHSCREEN_ANY
;
921 } else if (strcmp(name
, "notouch") == 0) {
922 if (out
) out
->touchscreen
= out
->TOUCHSCREEN_NOTOUCH
;
924 } else if (strcmp(name
, "stylus") == 0) {
925 if (out
) out
->touchscreen
= out
->TOUCHSCREEN_STYLUS
;
927 } else if (strcmp(name
, "finger") == 0) {
928 if (out
) out
->touchscreen
= out
->TOUCHSCREEN_FINGER
;
935 bool AaptGroupEntry::getKeysHiddenName(const char* name
,
936 ResTable_config
* out
)
940 if (strcmp(name
, kWildcardName
) == 0) {
941 mask
= ResTable_config::MASK_KEYSHIDDEN
;
942 value
= ResTable_config::KEYSHIDDEN_ANY
;
943 } else if (strcmp(name
, "keysexposed") == 0) {
944 mask
= ResTable_config::MASK_KEYSHIDDEN
;
945 value
= ResTable_config::KEYSHIDDEN_NO
;
946 } else if (strcmp(name
, "keyshidden") == 0) {
947 mask
= ResTable_config::MASK_KEYSHIDDEN
;
948 value
= ResTable_config::KEYSHIDDEN_YES
;
949 } else if (strcmp(name
, "keyssoft") == 0) {
950 mask
= ResTable_config::MASK_KEYSHIDDEN
;
951 value
= ResTable_config::KEYSHIDDEN_SOFT
;
955 if (out
) out
->inputFlags
= (out
->inputFlags
&~mask
) | value
;
962 bool AaptGroupEntry::getKeyboardName(const char* name
,
963 ResTable_config
* out
)
965 if (strcmp(name
, kWildcardName
) == 0) {
966 if (out
) out
->keyboard
= out
->KEYBOARD_ANY
;
968 } else if (strcmp(name
, "nokeys") == 0) {
969 if (out
) out
->keyboard
= out
->KEYBOARD_NOKEYS
;
971 } else if (strcmp(name
, "qwerty") == 0) {
972 if (out
) out
->keyboard
= out
->KEYBOARD_QWERTY
;
974 } else if (strcmp(name
, "12key") == 0) {
975 if (out
) out
->keyboard
= out
->KEYBOARD_12KEY
;
982 bool AaptGroupEntry::getNavHiddenName(const char* name
,
983 ResTable_config
* out
)
987 if (strcmp(name
, kWildcardName
) == 0) {
988 mask
= ResTable_config::MASK_NAVHIDDEN
;
989 value
= ResTable_config::NAVHIDDEN_ANY
;
990 } else if (strcmp(name
, "navexposed") == 0) {
991 mask
= ResTable_config::MASK_NAVHIDDEN
;
992 value
= ResTable_config::NAVHIDDEN_NO
;
993 } else if (strcmp(name
, "navhidden") == 0) {
994 mask
= ResTable_config::MASK_NAVHIDDEN
;
995 value
= ResTable_config::NAVHIDDEN_YES
;
999 if (out
) out
->inputFlags
= (out
->inputFlags
&~mask
) | value
;
1006 bool AaptGroupEntry::getNavigationName(const char* name
,
1007 ResTable_config
* out
)
1009 if (strcmp(name
, kWildcardName
) == 0) {
1010 if (out
) out
->navigation
= out
->NAVIGATION_ANY
;
1012 } else if (strcmp(name
, "nonav") == 0) {
1013 if (out
) out
->navigation
= out
->NAVIGATION_NONAV
;
1015 } else if (strcmp(name
, "dpad") == 0) {
1016 if (out
) out
->navigation
= out
->NAVIGATION_DPAD
;
1018 } else if (strcmp(name
, "trackball") == 0) {
1019 if (out
) out
->navigation
= out
->NAVIGATION_TRACKBALL
;
1021 } else if (strcmp(name
, "wheel") == 0) {
1022 if (out
) out
->navigation
= out
->NAVIGATION_WHEEL
;
1029 bool AaptGroupEntry::getScreenSizeName(const char* name
,
1030 ResTable_config
* out
)
1032 if (strcmp(name
, kWildcardName
) == 0) {
1034 out
->screenWidth
= out
->SCREENWIDTH_ANY
;
1035 out
->screenHeight
= out
->SCREENHEIGHT_ANY
;
1040 const char* x
= name
;
1041 while (*x
>= '0' && *x
<= '9') x
++;
1042 if (x
== name
|| *x
!= 'x') return false;
1043 String8
xName(name
, x
-name
);
1047 while (*y
>= '0' && *y
<= '9') y
++;
1048 if (y
== name
|| *y
!= 0) return false;
1049 String8
yName(x
, y
-x
);
1051 uint16_t w
= (uint16_t)atoi(xName
.string());
1052 uint16_t h
= (uint16_t)atoi(yName
.string());
1058 out
->screenWidth
= w
;
1059 out
->screenHeight
= h
;
1065 bool AaptGroupEntry::getVersionName(const char* name
,
1066 ResTable_config
* out
)
1068 if (strcmp(name
, kWildcardName
) == 0) {
1070 out
->sdkVersion
= out
->SDKVERSION_ANY
;
1071 out
->minorVersion
= out
->MINORVERSION_ANY
;
1081 const char* s
= name
;
1082 while (*s
>= '0' && *s
<= '9') s
++;
1083 if (s
== name
|| *s
!= 0) return false;
1084 String8
sdkName(name
, s
-name
);
1087 out
->sdkVersion
= (uint16_t)atoi(sdkName
.string());
1088 out
->minorVersion
= 0;
1094 int AaptGroupEntry::compare(const AaptGroupEntry
& o
) const
1096 int v
= mcc
.compare(o
.mcc
);
1097 if (v
== 0) v
= mnc
.compare(o
.mnc
);
1098 if (v
== 0) v
= locale
.compare(o
.locale
);
1099 if (v
== 0) v
= vendor
.compare(o
.vendor
);
1100 if (v
== 0) v
= screenLayoutSize
.compare(o
.screenLayoutSize
);
1101 if (v
== 0) v
= screenLayoutLong
.compare(o
.screenLayoutLong
);
1102 if (v
== 0) v
= orientation
.compare(o
.orientation
);
1103 if (v
== 0) v
= uiModeType
.compare(o
.uiModeType
);
1104 if (v
== 0) v
= uiModeNight
.compare(o
.uiModeNight
);
1105 if (v
== 0) v
= density
.compare(o
.density
);
1106 if (v
== 0) v
= touchscreen
.compare(o
.touchscreen
);
1107 if (v
== 0) v
= keysHidden
.compare(o
.keysHidden
);
1108 if (v
== 0) v
= keyboard
.compare(o
.keyboard
);
1109 if (v
== 0) v
= navHidden
.compare(o
.navHidden
);
1110 if (v
== 0) v
= navigation
.compare(o
.navigation
);
1111 if (v
== 0) v
= screenSize
.compare(o
.screenSize
);
1112 if (v
== 0) v
= version
.compare(o
.version
);
1116 ResTable_config
AaptGroupEntry::toParams() const
1118 ResTable_config params
;
1119 memset(¶ms
, 0, sizeof(params
));
1120 getMccName(mcc
.string(), ¶ms
);
1121 getMncName(mnc
.string(), ¶ms
);
1122 getLocaleName(locale
.string(), ¶ms
);
1123 getScreenLayoutSizeName(screenLayoutSize
.string(), ¶ms
);
1124 getScreenLayoutLongName(screenLayoutLong
.string(), ¶ms
);
1125 getOrientationName(orientation
.string(), ¶ms
);
1126 getUiModeTypeName(uiModeType
.string(), ¶ms
);
1127 getUiModeNightName(uiModeNight
.string(), ¶ms
);
1128 getDensityName(density
.string(), ¶ms
);
1129 getTouchscreenName(touchscreen
.string(), ¶ms
);
1130 getKeysHiddenName(keysHidden
.string(), ¶ms
);
1131 getKeyboardName(keyboard
.string(), ¶ms
);
1132 getNavHiddenName(navHidden
.string(), ¶ms
);
1133 getNavigationName(navigation
.string(), ¶ms
);
1134 getScreenSizeName(screenSize
.string(), ¶ms
);
1135 getVersionName(version
.string(), ¶ms
);
1137 // Fix up version number based on specified parameters.
1139 if ((params
.uiMode
&ResTable_config::MASK_UI_MODE_TYPE
)
1140 != ResTable_config::UI_MODE_TYPE_ANY
1141 || (params
.uiMode
&ResTable_config::MASK_UI_MODE_NIGHT
)
1142 != ResTable_config::UI_MODE_NIGHT_ANY
) {
1144 } else if ((params
.screenLayout
&ResTable_config::MASK_SCREENSIZE
)
1145 != ResTable_config::SCREENSIZE_ANY
1146 || (params
.screenLayout
&ResTable_config::MASK_SCREENLONG
)
1147 != ResTable_config::SCREENLONG_ANY
1148 || params
.density
!= ResTable_config::DENSITY_DEFAULT
) {
1152 if (minSdk
> params
.sdkVersion
) {
1153 params
.sdkVersion
= minSdk
;
1159 // =========================================================================
1160 // =========================================================================
1161 // =========================================================================
1163 void* AaptFile::editData(size_t size
)
1165 if (size
<= mBufferSize
) {
1169 size_t allocSize
= (size
*3)/2;
1170 void* buf
= realloc(mData
, allocSize
);
1176 mBufferSize
= allocSize
;
1180 void* AaptFile::editData(size_t* outSize
)
1183 *outSize
= mDataSize
;
1188 void* AaptFile::padData(size_t wordSize
)
1190 const size_t extra
= mDataSize%wordSize
;
1195 size_t initial
= mDataSize
;
1196 void* data
= editData(initial
+(wordSize
-extra
));
1198 memset(((uint8_t*)data
) + initial
, 0, wordSize
-extra
);
1203 status_t
AaptFile::writeData(const void* data
, size_t size
)
1205 size_t end
= mDataSize
;
1206 size_t total
= size
+ end
;
1207 void* buf
= editData(total
);
1209 return UNKNOWN_ERROR
;
1211 memcpy(((char*)buf
)+end
, data
, size
);
1215 void AaptFile::clearData()
1217 if (mData
!= NULL
) free(mData
);
1223 String8
AaptFile::getPrintableSource() const
1226 String8
name(mGroupEntry
.locale
.string());
1227 name
.appendPath(mGroupEntry
.vendor
.string());
1228 name
.appendPath(mPath
);
1229 name
.append(" #generated");
1235 // =========================================================================
1236 // =========================================================================
1237 // =========================================================================
1239 status_t
AaptGroup::addFile(const sp
<AaptFile
>& file
)
1241 if (mFiles
.indexOfKey(file
->getGroupEntry()) < 0) {
1242 file
->mPath
= mPath
;
1243 mFiles
.add(file
->getGroupEntry(), file
);
1247 SourcePos(file
->getSourceFile(), -1).error("Duplicate file.\n%s: Original is here.",
1248 getPrintableSource().string());
1249 return UNKNOWN_ERROR
;
1252 void AaptGroup::removeFile(size_t index
)
1254 mFiles
.removeItemsAt(index
);
1257 void AaptGroup::print() const
1259 printf(" %s\n", getPath().string());
1260 const size_t N
=mFiles
.size();
1262 for (i
=0; i
<N
; i
++) {
1263 sp
<AaptFile
> file
= mFiles
.valueAt(i
);
1264 const AaptGroupEntry
& e
= file
->getGroupEntry();
1265 if (file
->hasData()) {
1266 printf(" Gen: (%s) %d bytes\n", e
.toString().string(),
1267 (int)file
->getSize());
1269 printf(" Src: %s\n", file
->getPrintableSource().string());
1274 String8
AaptGroup::getPrintableSource() const
1276 if (mFiles
.size() > 0) {
1277 // Arbitrarily pull the first source file out of the list.
1278 return mFiles
.valueAt(0)->getPrintableSource();
1281 // Should never hit this case, but to be safe...
1286 // =========================================================================
1287 // =========================================================================
1288 // =========================================================================
1290 status_t
AaptDir::addFile(const String8
& name
, const sp
<AaptGroup
>& file
)
1292 if (mFiles
.indexOfKey(name
) >= 0) {
1293 return ALREADY_EXISTS
;
1295 mFiles
.add(name
, file
);
1299 status_t
AaptDir::addDir(const String8
& name
, const sp
<AaptDir
>& dir
)
1301 if (mDirs
.indexOfKey(name
) >= 0) {
1302 return ALREADY_EXISTS
;
1304 mDirs
.add(name
, dir
);
1308 sp
<AaptDir
> AaptDir::makeDir(const String8
& path
)
1311 String8 remain
= path
;
1313 sp
<AaptDir
> subdir
= this;
1314 while (name
= remain
.walkPath(&remain
), remain
!= "") {
1315 subdir
= subdir
->makeDir(name
);
1318 ssize_t i
= subdir
->mDirs
.indexOfKey(name
);
1320 return subdir
->mDirs
.valueAt(i
);
1322 sp
<AaptDir
> dir
= new AaptDir(name
, subdir
->mPath
.appendPathCopy(name
));
1323 subdir
->mDirs
.add(name
, dir
);
1327 void AaptDir::removeFile(const String8
& name
)
1329 mFiles
.removeItem(name
);
1332 void AaptDir::removeDir(const String8
& name
)
1334 mDirs
.removeItem(name
);
1337 status_t
AaptDir::renameFile(const sp
<AaptFile
>& file
, const String8
& newName
)
1339 sp
<AaptGroup
> origGroup
;
1341 // Find and remove the given file with shear, brute force!
1342 const size_t NG
= mFiles
.size();
1344 for (i
=0; origGroup
== NULL
&& i
<NG
; i
++) {
1345 sp
<AaptGroup
> g
= mFiles
.valueAt(i
);
1346 const size_t NF
= g
->getFiles().size();
1347 for (size_t j
=0; j
<NF
; j
++) {
1348 if (g
->getFiles().valueAt(j
) == file
) {
1352 mFiles
.removeItemsAt(i
);
1359 //printf("Renaming %s to %s\n", file->getPath().getPathName(), newName.string());
1361 // Place the file under its new name.
1362 if (origGroup
!= NULL
) {
1363 return addLeafFile(newName
, file
);
1369 status_t
AaptDir::addLeafFile(const String8
& leafName
, const sp
<AaptFile
>& file
)
1371 sp
<AaptGroup
> group
;
1372 if (mFiles
.indexOfKey(leafName
) >= 0) {
1373 group
= mFiles
.valueFor(leafName
);
1375 group
= new AaptGroup(leafName
, mPath
.appendPathCopy(leafName
));
1376 mFiles
.add(leafName
, group
);
1379 return group
->addFile(file
);
1382 ssize_t
AaptDir::slurpFullTree(Bundle
* bundle
, const String8
& srcDir
,
1383 const AaptGroupEntry
& kind
, const String8
& resType
)
1385 Vector
<String8
> fileNames
;
1390 dir
= opendir(srcDir
.string());
1392 fprintf(stderr
, "ERROR: opendir(%s): %s\n", srcDir
.string(), strerror(errno
));
1393 return UNKNOWN_ERROR
;
1397 * Slurp the filenames out of the directory.
1400 struct dirent
* entry
;
1402 entry
= readdir(dir
);
1406 if (isHidden(srcDir
.string(), entry
->d_name
))
1409 fileNames
.add(String8(entry
->d_name
));
1418 * Stash away the files and recursively descend into subdirectories.
1420 const size_t N
= fileNames
.size();
1422 for (i
= 0; i
< N
; i
++) {
1423 String8
pathName(srcDir
);
1426 pathName
.appendPath(fileNames
[i
].string());
1427 type
= getFileType(pathName
.string());
1428 if (type
== kFileTypeDirectory
) {
1430 bool notAdded
= false;
1431 if (mDirs
.indexOfKey(fileNames
[i
]) >= 0) {
1432 subdir
= mDirs
.valueFor(fileNames
[i
]);
1434 subdir
= new AaptDir(fileNames
[i
], mPath
.appendPathCopy(fileNames
[i
]));
1437 ssize_t res
= subdir
->slurpFullTree(bundle
, pathName
, kind
,
1439 if (res
< NO_ERROR
) {
1442 if (res
> 0 && notAdded
) {
1443 mDirs
.add(fileNames
[i
], subdir
);
1446 } else if (type
== kFileTypeRegular
) {
1447 sp
<AaptFile
> file
= new AaptFile(pathName
, kind
, resType
);
1448 status_t err
= addLeafFile(fileNames
[i
], file
);
1449 if (err
!= NO_ERROR
) {
1456 if (bundle
->getVerbose())
1457 printf(" (ignoring non-file/dir '%s')\n", pathName
.string());
1464 status_t
AaptDir::validate() const
1466 const size_t NF
= mFiles
.size();
1467 const size_t ND
= mDirs
.size();
1469 for (i
= 0; i
< NF
; i
++) {
1470 if (!validateFileName(mFiles
.valueAt(i
)->getLeaf().string())) {
1471 SourcePos(mFiles
.valueAt(i
)->getPrintableSource(), -1).error(
1472 "Invalid filename. Unable to add.");
1473 return UNKNOWN_ERROR
;
1477 for (j
= i
+1; j
< NF
; j
++) {
1478 if (strcasecmp(mFiles
.valueAt(i
)->getLeaf().string(),
1479 mFiles
.valueAt(j
)->getLeaf().string()) == 0) {
1480 SourcePos(mFiles
.valueAt(i
)->getPrintableSource(), -1).error(
1481 "File is case-insensitive equivalent to: %s",
1482 mFiles
.valueAt(j
)->getPrintableSource().string());
1483 return UNKNOWN_ERROR
;
1486 // TODO: if ".gz", check for non-.gz; if non-, check for ".gz"
1487 // (this is mostly caught by the "marked" stuff, below)
1490 for (j
= 0; j
< ND
; j
++) {
1491 if (strcasecmp(mFiles
.valueAt(i
)->getLeaf().string(),
1492 mDirs
.valueAt(j
)->getLeaf().string()) == 0) {
1493 SourcePos(mFiles
.valueAt(i
)->getPrintableSource(), -1).error(
1494 "File conflicts with dir from: %s",
1495 mDirs
.valueAt(j
)->getPrintableSource().string());
1496 return UNKNOWN_ERROR
;
1501 for (i
= 0; i
< ND
; i
++) {
1502 if (!validateFileName(mDirs
.valueAt(i
)->getLeaf().string())) {
1503 SourcePos(mDirs
.valueAt(i
)->getPrintableSource(), -1).error(
1504 "Invalid directory name, unable to add.");
1505 return UNKNOWN_ERROR
;
1509 for (j
= i
+1; j
< ND
; j
++) {
1510 if (strcasecmp(mDirs
.valueAt(i
)->getLeaf().string(),
1511 mDirs
.valueAt(j
)->getLeaf().string()) == 0) {
1512 SourcePos(mDirs
.valueAt(i
)->getPrintableSource(), -1).error(
1513 "Directory is case-insensitive equivalent to: %s",
1514 mDirs
.valueAt(j
)->getPrintableSource().string());
1515 return UNKNOWN_ERROR
;
1519 status_t err
= mDirs
.valueAt(i
)->validate();
1520 if (err
!= NO_ERROR
) {
1528 void AaptDir::print() const
1530 const size_t ND
=getDirs().size();
1532 for (i
=0; i
<ND
; i
++) {
1533 getDirs().valueAt(i
)->print();
1536 const size_t NF
=getFiles().size();
1537 for (i
=0; i
<NF
; i
++) {
1538 getFiles().valueAt(i
)->print();
1542 String8
AaptDir::getPrintableSource() const
1544 if (mFiles
.size() > 0) {
1545 // Arbitrarily pull the first file out of the list as the source dir.
1546 return mFiles
.valueAt(0)->getPrintableSource().getPathDir();
1548 if (mDirs
.size() > 0) {
1549 // Or arbitrarily pull the first dir out of the list as the source dir.
1550 return mDirs
.valueAt(0)->getPrintableSource().getPathDir();
1553 // Should never hit this case, but to be safe...
1558 // =========================================================================
1559 // =========================================================================
1560 // =========================================================================
1562 sp
<AaptFile
> AaptAssets::addFile(
1563 const String8
& filePath
, const AaptGroupEntry
& entry
,
1564 const String8
& srcDir
, sp
<AaptGroup
>* outGroup
,
1565 const String8
& resType
)
1567 sp
<AaptDir
> dir
= this;
1568 sp
<AaptGroup
> group
;
1570 String8 root
, remain(filePath
), partialPath
;
1571 while (remain
.length() > 0) {
1572 root
= remain
.walkPath(&remain
);
1573 partialPath
.appendPath(root
);
1575 const String8
rootStr(root
);
1577 if (remain
.length() == 0) {
1578 ssize_t i
= dir
->getFiles().indexOfKey(rootStr
);
1580 group
= dir
->getFiles().valueAt(i
);
1582 group
= new AaptGroup(rootStr
, filePath
);
1583 status_t res
= dir
->addFile(rootStr
, group
);
1584 if (res
!= NO_ERROR
) {
1588 file
= new AaptFile(srcDir
.appendPathCopy(filePath
), entry
, resType
);
1589 status_t res
= group
->addFile(file
);
1590 if (res
!= NO_ERROR
) {
1596 ssize_t i
= dir
->getDirs().indexOfKey(rootStr
);
1598 dir
= dir
->getDirs().valueAt(i
);
1600 sp
<AaptDir
> subdir
= new AaptDir(rootStr
, partialPath
);
1601 status_t res
= dir
->addDir(rootStr
, subdir
);
1602 if (res
!= NO_ERROR
) {
1610 mGroupEntries
.add(entry
);
1611 if (outGroup
) *outGroup
= group
;
1615 void AaptAssets::addResource(const String8
& leafName
, const String8
& path
,
1616 const sp
<AaptFile
>& file
, const String8
& resType
)
1618 sp
<AaptDir
> res
= AaptDir::makeDir(kResString
);
1619 String8 dirname
= file
->getGroupEntry().toDirName(resType
);
1620 sp
<AaptDir
> subdir
= res
->makeDir(dirname
);
1621 sp
<AaptGroup
> grr
= new AaptGroup(leafName
, path
);
1624 subdir
->addFile(leafName
, grr
);
1628 ssize_t
AaptAssets::slurpFromArgs(Bundle
* bundle
)
1633 const Vector
<const char *>& resDirs
= bundle
->getResourceSourceDirs();
1634 const size_t dirCount
=resDirs
.size();
1635 sp
<AaptAssets
> current
= this;
1637 const int N
= bundle
->getFileSpecCount();
1640 * If a package manifest was specified, include that first.
1642 if (bundle
->getAndroidManifestFile() != NULL
) {
1643 // place at root of zip.
1644 String8
srcFile(bundle
->getAndroidManifestFile());
1645 addFile(srcFile
.getPathLeaf(), AaptGroupEntry(), srcFile
.getPathDir(),
1651 * If a directory of custom assets was supplied, slurp 'em up.
1653 if (bundle
->getAssetSourceDir()) {
1654 const char* assetDir
= bundle
->getAssetSourceDir();
1656 FileType type
= getFileType(assetDir
);
1657 if (type
== kFileTypeNonexistent
) {
1658 fprintf(stderr
, "ERROR: asset directory '%s' does not exist\n", assetDir
);
1659 return UNKNOWN_ERROR
;
1661 if (type
!= kFileTypeDirectory
) {
1662 fprintf(stderr
, "ERROR: '%s' is not a directory\n", assetDir
);
1663 return UNKNOWN_ERROR
;
1666 String8
assetRoot(assetDir
);
1667 sp
<AaptDir
> assetAaptDir
= makeDir(String8(kAssetDir
));
1668 AaptGroupEntry group
;
1669 count
= assetAaptDir
->slurpFullTree(bundle
, assetRoot
, group
,
1676 mGroupEntries
.add(group
);
1678 totalCount
+= count
;
1680 if (bundle
->getVerbose())
1681 printf("Found %d custom asset file%s in %s\n",
1682 count
, (count
==1) ? "" : "s", assetDir
);
1686 * If a directory of resource-specific assets was supplied, slurp 'em up.
1688 for (size_t i
=0; i
<dirCount
; i
++) {
1689 const char *res
= resDirs
[i
];
1691 type
= getFileType(res
);
1692 if (type
== kFileTypeNonexistent
) {
1693 fprintf(stderr
, "ERROR: resource directory '%s' does not exist\n", res
);
1694 return UNKNOWN_ERROR
;
1696 if (type
== kFileTypeDirectory
) {
1698 sp
<AaptAssets
> nextOverlay
= new AaptAssets();
1699 current
->setOverlay(nextOverlay
);
1700 current
= nextOverlay
;
1702 count
= current
->slurpResourceTree(bundle
, String8(res
));
1708 totalCount
+= count
;
1711 fprintf(stderr
, "ERROR: '%s' is not a directory\n", res
);
1712 return UNKNOWN_ERROR
;
1718 * Now do any additional raw files.
1720 for (int arg
=0; arg
<N
; arg
++) {
1721 const char* assetDir
= bundle
->getFileSpecEntry(arg
);
1723 FileType type
= getFileType(assetDir
);
1724 if (type
== kFileTypeNonexistent
) {
1725 fprintf(stderr
, "ERROR: input directory '%s' does not exist\n", assetDir
);
1726 return UNKNOWN_ERROR
;
1728 if (type
!= kFileTypeDirectory
) {
1729 fprintf(stderr
, "ERROR: '%s' is not a directory\n", assetDir
);
1730 return UNKNOWN_ERROR
;
1733 String8
assetRoot(assetDir
);
1735 if (bundle
->getVerbose())
1736 printf("Processing raw dir '%s'\n", (const char*) assetDir
);
1739 * Do a recursive traversal of subdir tree. We don't make any
1740 * guarantees about ordering, so we're okay with an inorder search
1741 * using whatever order the OS happens to hand back to us.
1743 count
= slurpFullTree(bundle
, assetRoot
, AaptGroupEntry(), String8());
1745 /* failure; report error and remove archive */
1749 totalCount
+= count
;
1751 if (bundle
->getVerbose())
1752 printf("Found %d asset file%s in %s\n",
1753 count
, (count
==1) ? "" : "s", assetDir
);
1757 if (count
!= NO_ERROR
) {
1767 ssize_t
AaptAssets::slurpFullTree(Bundle
* bundle
, const String8
& srcDir
,
1768 const AaptGroupEntry
& kind
,
1769 const String8
& resType
)
1771 ssize_t res
= AaptDir::slurpFullTree(bundle
, srcDir
, kind
, resType
);
1773 mGroupEntries
.add(kind
);
1779 ssize_t
AaptAssets::slurpResourceTree(Bundle
* bundle
, const String8
& srcDir
)
1783 DIR* dir
= opendir(srcDir
.string());
1785 fprintf(stderr
, "ERROR: opendir(%s): %s\n", srcDir
.string(), strerror(errno
));
1786 return UNKNOWN_ERROR
;
1792 * Run through the directory, looking for dirs that match the
1796 struct dirent
* entry
= readdir(dir
);
1797 if (entry
== NULL
) {
1801 if (isHidden(srcDir
.string(), entry
->d_name
)) {
1805 String8
subdirName(srcDir
);
1806 subdirName
.appendPath(entry
->d_name
);
1808 AaptGroupEntry group
;
1810 bool b
= group
.initFromDirName(entry
->d_name
, &resType
);
1812 fprintf(stderr
, "invalid resource directory name: %s/%s\n", srcDir
.string(),
1818 FileType type
= getFileType(subdirName
.string());
1820 if (type
== kFileTypeDirectory
) {
1821 sp
<AaptDir
> dir
= makeDir(String8(entry
->d_name
));
1822 ssize_t res
= dir
->slurpFullTree(bundle
, subdirName
, group
,
1829 mGroupEntries
.add(group
);
1835 if (bundle
->getVerbose()) {
1836 fprintf(stderr
, " (ignoring file '%s')\n", subdirName
.string());
1852 AaptAssets::slurpResourceZip(Bundle
* bundle
, const char* filename
)
1855 SortedVector
<AaptGroupEntry
> entries
;
1857 ZipFile
* zip
= new ZipFile
;
1858 status_t err
= zip
->open(filename
, ZipFile::kOpenReadOnly
);
1859 if (err
!= NO_ERROR
) {
1860 fprintf(stderr
, "error opening zip file %s\n", filename
);
1866 const int N
= zip
->getNumEntries();
1867 for (int i
=0; i
<N
; i
++) {
1868 ZipEntry
* entry
= zip
->getEntryByIndex(i
);
1869 if (entry
->getDeleted()) {
1873 String8
entryName(entry
->getFileName());
1875 String8 dirName
= entryName
.getPathDir();
1876 sp
<AaptDir
> dir
= dirName
== "" ? this : makeDir(dirName
);
1879 AaptGroupEntry kind
;
1882 if (entryName
.walkPath(&remain
) == kResourceDir
) {
1883 // these are the resources, pull their type out of the directory name
1884 kind
.initFromDirName(remain
.walkPath().string(), &resType
);
1886 // these are untyped and don't have an AaptGroupEntry
1888 if (entries
.indexOf(kind
) < 0) {
1890 mGroupEntries
.add(kind
);
1893 // use the one from the zip file if they both exist.
1894 dir
->removeFile(entryName
.getPathLeaf());
1896 sp
<AaptFile
> file
= new AaptFile(entryName
, kind
, resType
);
1897 status_t err
= dir
->addLeafFile(entryName
.getPathLeaf(), file
);
1898 if (err
!= NO_ERROR
) {
1899 fprintf(stderr
, "err=%s entryName=%s\n", strerror(err
), entryName
.string());
1903 file
->setCompressionMethod(entry
->getCompressionMethod());
1906 if (entryName
== "AndroidManifest.xml") {
1907 printf("AndroidManifest.xml\n");
1909 printf("\n\nfile: %s\n", entryName
.string());
1912 size_t len
= entry
->getUncompressedLen();
1913 void* data
= zip
->uncompress(entry
);
1914 void* buf
= file
->editData(len
);
1915 memcpy(buf
, data
, len
);
1919 const unsigned char* p
= (unsigned char*)data
;
1920 const unsigned char* end
= p
+len
;
1922 for (int i
=0; i
<32 && p
< end
; i
++) {
1923 printf("0x%03x ", i
*0x10 + OFF
);
1924 for (int j
=0; j
<0x10 && p
< end
; j
++) {
1925 printf(" %02x", *p
);
1942 sp
<AaptSymbols
> AaptAssets::getSymbolsFor(const String8
& name
)
1944 sp
<AaptSymbols
> sym
= mSymbols
.valueFor(name
);
1946 sym
= new AaptSymbols();
1947 mSymbols
.add(name
, sym
);
1952 status_t
AaptAssets::buildIncludedResources(Bundle
* bundle
)
1954 if (!mHaveIncludedAssets
) {
1955 // Add in all includes.
1956 const Vector
<const char*>& incl
= bundle
->getPackageIncludes();
1957 const size_t N
=incl
.size();
1958 for (size_t i
=0; i
<N
; i
++) {
1959 if (bundle
->getVerbose())
1960 printf("Including resources from package: %s\n", incl
[i
]);
1961 if (!mIncludedAssets
.addAssetPath(String8(incl
[i
]), NULL
)) {
1962 fprintf(stderr
, "ERROR: Asset package include '%s' not found.\n",
1964 return UNKNOWN_ERROR
;
1967 mHaveIncludedAssets
= true;
1973 status_t
AaptAssets::addIncludedResources(const sp
<AaptFile
>& file
)
1975 const ResTable
& res
= getIncludedResources();
1977 return const_cast<ResTable
&>(res
).add(file
->getData(), file
->getSize(), NULL
);
1980 const ResTable
& AaptAssets::getIncludedResources() const
1982 return mIncludedAssets
.getResources(false);
1985 void AaptAssets::print() const
1987 printf("Locale/Vendor pairs:\n");
1988 const size_t N
=mGroupEntries
.size();
1989 for (size_t i
=0; i
<N
; i
++) {
1991 mGroupEntries
.itemAt(i
).locale
.string(),
1992 mGroupEntries
.itemAt(i
).vendor
.string());
1995 printf("\nFiles:\n");
1999 sp
<AaptDir
> AaptAssets::resDir(const String8
& name
)
2001 const Vector
<sp
<AaptDir
> >& dirs
= mDirs
;
2002 const size_t N
= dirs
.size();
2003 for (size_t i
=0; i
<N
; i
++) {
2004 const sp
<AaptDir
>& d
= dirs
.itemAt(i
);
2005 if (d
->getLeaf() == name
) {
2013 valid_symbol_name(const String8
& symbol
)
2015 static char const * const KEYWORDS
[] = {
2016 "abstract", "assert", "boolean", "break",
2017 "byte", "case", "catch", "char", "class", "const", "continue",
2018 "default", "do", "double", "else", "enum", "extends", "final",
2019 "finally", "float", "for", "goto", "if", "implements", "import",
2020 "instanceof", "int", "interface", "long", "native", "new", "package",
2021 "private", "protected", "public", "return", "short", "static",
2022 "strictfp", "super", "switch", "synchronized", "this", "throw",
2023 "throws", "transient", "try", "void", "volatile", "while",
2024 "true", "false", "null",
2027 const char*const* k
= KEYWORDS
;
2028 const char*const s
= symbol
.string();
2030 if (0 == strcmp(s
, *k
)) {