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