]>
git.saurik.com Git - android/aapt.git/blob - AaptAssets.cpp
fc655a7abbb7e966d537fe1c56e9fe10d7146943
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 char* c
= (char*)name
;
892 while (*c
>= '0' && *c
<= '9') {
896 // check that we have 'dpi' after the last digit.
897 if (toupper(c
[0]) != 'D' ||
898 toupper(c
[1]) != 'P' ||
899 toupper(c
[2]) != 'I' ||
904 // temporarily replace the first letter with \0 to
913 if (out
) out
->density
= d
;
920 bool AaptGroupEntry::getTouchscreenName(const char* name
,
921 ResTable_config
* out
)
923 if (strcmp(name
, kWildcardName
) == 0) {
924 if (out
) out
->touchscreen
= out
->TOUCHSCREEN_ANY
;
926 } else if (strcmp(name
, "notouch") == 0) {
927 if (out
) out
->touchscreen
= out
->TOUCHSCREEN_NOTOUCH
;
929 } else if (strcmp(name
, "stylus") == 0) {
930 if (out
) out
->touchscreen
= out
->TOUCHSCREEN_STYLUS
;
932 } else if (strcmp(name
, "finger") == 0) {
933 if (out
) out
->touchscreen
= out
->TOUCHSCREEN_FINGER
;
940 bool AaptGroupEntry::getKeysHiddenName(const char* name
,
941 ResTable_config
* out
)
945 if (strcmp(name
, kWildcardName
) == 0) {
946 mask
= ResTable_config::MASK_KEYSHIDDEN
;
947 value
= ResTable_config::KEYSHIDDEN_ANY
;
948 } else if (strcmp(name
, "keysexposed") == 0) {
949 mask
= ResTable_config::MASK_KEYSHIDDEN
;
950 value
= ResTable_config::KEYSHIDDEN_NO
;
951 } else if (strcmp(name
, "keyshidden") == 0) {
952 mask
= ResTable_config::MASK_KEYSHIDDEN
;
953 value
= ResTable_config::KEYSHIDDEN_YES
;
954 } else if (strcmp(name
, "keyssoft") == 0) {
955 mask
= ResTable_config::MASK_KEYSHIDDEN
;
956 value
= ResTable_config::KEYSHIDDEN_SOFT
;
960 if (out
) out
->inputFlags
= (out
->inputFlags
&~mask
) | value
;
967 bool AaptGroupEntry::getKeyboardName(const char* name
,
968 ResTable_config
* out
)
970 if (strcmp(name
, kWildcardName
) == 0) {
971 if (out
) out
->keyboard
= out
->KEYBOARD_ANY
;
973 } else if (strcmp(name
, "nokeys") == 0) {
974 if (out
) out
->keyboard
= out
->KEYBOARD_NOKEYS
;
976 } else if (strcmp(name
, "qwerty") == 0) {
977 if (out
) out
->keyboard
= out
->KEYBOARD_QWERTY
;
979 } else if (strcmp(name
, "12key") == 0) {
980 if (out
) out
->keyboard
= out
->KEYBOARD_12KEY
;
987 bool AaptGroupEntry::getNavHiddenName(const char* name
,
988 ResTable_config
* out
)
992 if (strcmp(name
, kWildcardName
) == 0) {
993 mask
= ResTable_config::MASK_NAVHIDDEN
;
994 value
= ResTable_config::NAVHIDDEN_ANY
;
995 } else if (strcmp(name
, "navexposed") == 0) {
996 mask
= ResTable_config::MASK_NAVHIDDEN
;
997 value
= ResTable_config::NAVHIDDEN_NO
;
998 } else if (strcmp(name
, "navhidden") == 0) {
999 mask
= ResTable_config::MASK_NAVHIDDEN
;
1000 value
= ResTable_config::NAVHIDDEN_YES
;
1004 if (out
) out
->inputFlags
= (out
->inputFlags
&~mask
) | value
;
1011 bool AaptGroupEntry::getNavigationName(const char* name
,
1012 ResTable_config
* out
)
1014 if (strcmp(name
, kWildcardName
) == 0) {
1015 if (out
) out
->navigation
= out
->NAVIGATION_ANY
;
1017 } else if (strcmp(name
, "nonav") == 0) {
1018 if (out
) out
->navigation
= out
->NAVIGATION_NONAV
;
1020 } else if (strcmp(name
, "dpad") == 0) {
1021 if (out
) out
->navigation
= out
->NAVIGATION_DPAD
;
1023 } else if (strcmp(name
, "trackball") == 0) {
1024 if (out
) out
->navigation
= out
->NAVIGATION_TRACKBALL
;
1026 } else if (strcmp(name
, "wheel") == 0) {
1027 if (out
) out
->navigation
= out
->NAVIGATION_WHEEL
;
1034 bool AaptGroupEntry::getScreenSizeName(const char* name
,
1035 ResTable_config
* out
)
1037 if (strcmp(name
, kWildcardName
) == 0) {
1039 out
->screenWidth
= out
->SCREENWIDTH_ANY
;
1040 out
->screenHeight
= out
->SCREENHEIGHT_ANY
;
1045 const char* x
= name
;
1046 while (*x
>= '0' && *x
<= '9') x
++;
1047 if (x
== name
|| *x
!= 'x') return false;
1048 String8
xName(name
, x
-name
);
1052 while (*y
>= '0' && *y
<= '9') y
++;
1053 if (y
== name
|| *y
!= 0) return false;
1054 String8
yName(x
, y
-x
);
1056 uint16_t w
= (uint16_t)atoi(xName
.string());
1057 uint16_t h
= (uint16_t)atoi(yName
.string());
1063 out
->screenWidth
= w
;
1064 out
->screenHeight
= h
;
1070 bool AaptGroupEntry::getVersionName(const char* name
,
1071 ResTable_config
* out
)
1073 if (strcmp(name
, kWildcardName
) == 0) {
1075 out
->sdkVersion
= out
->SDKVERSION_ANY
;
1076 out
->minorVersion
= out
->MINORVERSION_ANY
;
1086 const char* s
= name
;
1087 while (*s
>= '0' && *s
<= '9') s
++;
1088 if (s
== name
|| *s
!= 0) return false;
1089 String8
sdkName(name
, s
-name
);
1092 out
->sdkVersion
= (uint16_t)atoi(sdkName
.string());
1093 out
->minorVersion
= 0;
1099 int AaptGroupEntry::compare(const AaptGroupEntry
& o
) const
1101 int v
= mcc
.compare(o
.mcc
);
1102 if (v
== 0) v
= mnc
.compare(o
.mnc
);
1103 if (v
== 0) v
= locale
.compare(o
.locale
);
1104 if (v
== 0) v
= vendor
.compare(o
.vendor
);
1105 if (v
== 0) v
= screenLayoutSize
.compare(o
.screenLayoutSize
);
1106 if (v
== 0) v
= screenLayoutLong
.compare(o
.screenLayoutLong
);
1107 if (v
== 0) v
= orientation
.compare(o
.orientation
);
1108 if (v
== 0) v
= uiModeType
.compare(o
.uiModeType
);
1109 if (v
== 0) v
= uiModeNight
.compare(o
.uiModeNight
);
1110 if (v
== 0) v
= density
.compare(o
.density
);
1111 if (v
== 0) v
= touchscreen
.compare(o
.touchscreen
);
1112 if (v
== 0) v
= keysHidden
.compare(o
.keysHidden
);
1113 if (v
== 0) v
= keyboard
.compare(o
.keyboard
);
1114 if (v
== 0) v
= navHidden
.compare(o
.navHidden
);
1115 if (v
== 0) v
= navigation
.compare(o
.navigation
);
1116 if (v
== 0) v
= screenSize
.compare(o
.screenSize
);
1117 if (v
== 0) v
= version
.compare(o
.version
);
1121 ResTable_config
AaptGroupEntry::toParams() const
1123 ResTable_config params
;
1124 memset(¶ms
, 0, sizeof(params
));
1125 getMccName(mcc
.string(), ¶ms
);
1126 getMncName(mnc
.string(), ¶ms
);
1127 getLocaleName(locale
.string(), ¶ms
);
1128 getScreenLayoutSizeName(screenLayoutSize
.string(), ¶ms
);
1129 getScreenLayoutLongName(screenLayoutLong
.string(), ¶ms
);
1130 getOrientationName(orientation
.string(), ¶ms
);
1131 getUiModeTypeName(uiModeType
.string(), ¶ms
);
1132 getUiModeNightName(uiModeNight
.string(), ¶ms
);
1133 getDensityName(density
.string(), ¶ms
);
1134 getTouchscreenName(touchscreen
.string(), ¶ms
);
1135 getKeysHiddenName(keysHidden
.string(), ¶ms
);
1136 getKeyboardName(keyboard
.string(), ¶ms
);
1137 getNavHiddenName(navHidden
.string(), ¶ms
);
1138 getNavigationName(navigation
.string(), ¶ms
);
1139 getScreenSizeName(screenSize
.string(), ¶ms
);
1140 getVersionName(version
.string(), ¶ms
);
1142 // Fix up version number based on specified parameters.
1144 if ((params
.uiMode
&ResTable_config::MASK_UI_MODE_TYPE
)
1145 != ResTable_config::UI_MODE_TYPE_ANY
1146 || (params
.uiMode
&ResTable_config::MASK_UI_MODE_NIGHT
)
1147 != ResTable_config::UI_MODE_NIGHT_ANY
) {
1149 } else if ((params
.screenLayout
&ResTable_config::MASK_SCREENSIZE
)
1150 != ResTable_config::SCREENSIZE_ANY
1151 || (params
.screenLayout
&ResTable_config::MASK_SCREENLONG
)
1152 != ResTable_config::SCREENLONG_ANY
1153 || params
.density
!= ResTable_config::DENSITY_DEFAULT
) {
1157 if (minSdk
> params
.sdkVersion
) {
1158 params
.sdkVersion
= minSdk
;
1164 // =========================================================================
1165 // =========================================================================
1166 // =========================================================================
1168 void* AaptFile::editData(size_t size
)
1170 if (size
<= mBufferSize
) {
1174 size_t allocSize
= (size
*3)/2;
1175 void* buf
= realloc(mData
, allocSize
);
1181 mBufferSize
= allocSize
;
1185 void* AaptFile::editData(size_t* outSize
)
1188 *outSize
= mDataSize
;
1193 void* AaptFile::padData(size_t wordSize
)
1195 const size_t extra
= mDataSize%wordSize
;
1200 size_t initial
= mDataSize
;
1201 void* data
= editData(initial
+(wordSize
-extra
));
1203 memset(((uint8_t*)data
) + initial
, 0, wordSize
-extra
);
1208 status_t
AaptFile::writeData(const void* data
, size_t size
)
1210 size_t end
= mDataSize
;
1211 size_t total
= size
+ end
;
1212 void* buf
= editData(total
);
1214 return UNKNOWN_ERROR
;
1216 memcpy(((char*)buf
)+end
, data
, size
);
1220 void AaptFile::clearData()
1222 if (mData
!= NULL
) free(mData
);
1228 String8
AaptFile::getPrintableSource() const
1231 String8
name(mGroupEntry
.locale
.string());
1232 name
.appendPath(mGroupEntry
.vendor
.string());
1233 name
.appendPath(mPath
);
1234 name
.append(" #generated");
1240 // =========================================================================
1241 // =========================================================================
1242 // =========================================================================
1244 status_t
AaptGroup::addFile(const sp
<AaptFile
>& file
)
1246 if (mFiles
.indexOfKey(file
->getGroupEntry()) < 0) {
1247 file
->mPath
= mPath
;
1248 mFiles
.add(file
->getGroupEntry(), file
);
1252 SourcePos(file
->getSourceFile(), -1).error("Duplicate file.\n%s: Original is here.",
1253 getPrintableSource().string());
1254 return UNKNOWN_ERROR
;
1257 void AaptGroup::removeFile(size_t index
)
1259 mFiles
.removeItemsAt(index
);
1262 void AaptGroup::print() const
1264 printf(" %s\n", getPath().string());
1265 const size_t N
=mFiles
.size();
1267 for (i
=0; i
<N
; i
++) {
1268 sp
<AaptFile
> file
= mFiles
.valueAt(i
);
1269 const AaptGroupEntry
& e
= file
->getGroupEntry();
1270 if (file
->hasData()) {
1271 printf(" Gen: (%s) %d bytes\n", e
.toString().string(),
1272 (int)file
->getSize());
1274 printf(" Src: %s\n", file
->getPrintableSource().string());
1279 String8
AaptGroup::getPrintableSource() const
1281 if (mFiles
.size() > 0) {
1282 // Arbitrarily pull the first source file out of the list.
1283 return mFiles
.valueAt(0)->getPrintableSource();
1286 // Should never hit this case, but to be safe...
1291 // =========================================================================
1292 // =========================================================================
1293 // =========================================================================
1295 status_t
AaptDir::addFile(const String8
& name
, const sp
<AaptGroup
>& file
)
1297 if (mFiles
.indexOfKey(name
) >= 0) {
1298 return ALREADY_EXISTS
;
1300 mFiles
.add(name
, file
);
1304 status_t
AaptDir::addDir(const String8
& name
, const sp
<AaptDir
>& dir
)
1306 if (mDirs
.indexOfKey(name
) >= 0) {
1307 return ALREADY_EXISTS
;
1309 mDirs
.add(name
, dir
);
1313 sp
<AaptDir
> AaptDir::makeDir(const String8
& path
)
1316 String8 remain
= path
;
1318 sp
<AaptDir
> subdir
= this;
1319 while (name
= remain
.walkPath(&remain
), remain
!= "") {
1320 subdir
= subdir
->makeDir(name
);
1323 ssize_t i
= subdir
->mDirs
.indexOfKey(name
);
1325 return subdir
->mDirs
.valueAt(i
);
1327 sp
<AaptDir
> dir
= new AaptDir(name
, subdir
->mPath
.appendPathCopy(name
));
1328 subdir
->mDirs
.add(name
, dir
);
1332 void AaptDir::removeFile(const String8
& name
)
1334 mFiles
.removeItem(name
);
1337 void AaptDir::removeDir(const String8
& name
)
1339 mDirs
.removeItem(name
);
1342 status_t
AaptDir::renameFile(const sp
<AaptFile
>& file
, const String8
& newName
)
1344 sp
<AaptGroup
> origGroup
;
1346 // Find and remove the given file with shear, brute force!
1347 const size_t NG
= mFiles
.size();
1349 for (i
=0; origGroup
== NULL
&& i
<NG
; i
++) {
1350 sp
<AaptGroup
> g
= mFiles
.valueAt(i
);
1351 const size_t NF
= g
->getFiles().size();
1352 for (size_t j
=0; j
<NF
; j
++) {
1353 if (g
->getFiles().valueAt(j
) == file
) {
1357 mFiles
.removeItemsAt(i
);
1364 //printf("Renaming %s to %s\n", file->getPath().getPathName(), newName.string());
1366 // Place the file under its new name.
1367 if (origGroup
!= NULL
) {
1368 return addLeafFile(newName
, file
);
1374 status_t
AaptDir::addLeafFile(const String8
& leafName
, const sp
<AaptFile
>& file
)
1376 sp
<AaptGroup
> group
;
1377 if (mFiles
.indexOfKey(leafName
) >= 0) {
1378 group
= mFiles
.valueFor(leafName
);
1380 group
= new AaptGroup(leafName
, mPath
.appendPathCopy(leafName
));
1381 mFiles
.add(leafName
, group
);
1384 return group
->addFile(file
);
1387 ssize_t
AaptDir::slurpFullTree(Bundle
* bundle
, const String8
& srcDir
,
1388 const AaptGroupEntry
& kind
, const String8
& resType
)
1390 Vector
<String8
> fileNames
;
1395 dir
= opendir(srcDir
.string());
1397 fprintf(stderr
, "ERROR: opendir(%s): %s\n", srcDir
.string(), strerror(errno
));
1398 return UNKNOWN_ERROR
;
1402 * Slurp the filenames out of the directory.
1405 struct dirent
* entry
;
1407 entry
= readdir(dir
);
1411 if (isHidden(srcDir
.string(), entry
->d_name
))
1414 fileNames
.add(String8(entry
->d_name
));
1423 * Stash away the files and recursively descend into subdirectories.
1425 const size_t N
= fileNames
.size();
1427 for (i
= 0; i
< N
; i
++) {
1428 String8
pathName(srcDir
);
1431 pathName
.appendPath(fileNames
[i
].string());
1432 type
= getFileType(pathName
.string());
1433 if (type
== kFileTypeDirectory
) {
1435 bool notAdded
= false;
1436 if (mDirs
.indexOfKey(fileNames
[i
]) >= 0) {
1437 subdir
= mDirs
.valueFor(fileNames
[i
]);
1439 subdir
= new AaptDir(fileNames
[i
], mPath
.appendPathCopy(fileNames
[i
]));
1442 ssize_t res
= subdir
->slurpFullTree(bundle
, pathName
, kind
,
1444 if (res
< NO_ERROR
) {
1447 if (res
> 0 && notAdded
) {
1448 mDirs
.add(fileNames
[i
], subdir
);
1451 } else if (type
== kFileTypeRegular
) {
1452 sp
<AaptFile
> file
= new AaptFile(pathName
, kind
, resType
);
1453 status_t err
= addLeafFile(fileNames
[i
], file
);
1454 if (err
!= NO_ERROR
) {
1461 if (bundle
->getVerbose())
1462 printf(" (ignoring non-file/dir '%s')\n", pathName
.string());
1469 status_t
AaptDir::validate() const
1471 const size_t NF
= mFiles
.size();
1472 const size_t ND
= mDirs
.size();
1474 for (i
= 0; i
< NF
; i
++) {
1475 if (!validateFileName(mFiles
.valueAt(i
)->getLeaf().string())) {
1476 SourcePos(mFiles
.valueAt(i
)->getPrintableSource(), -1).error(
1477 "Invalid filename. Unable to add.");
1478 return UNKNOWN_ERROR
;
1482 for (j
= i
+1; j
< NF
; j
++) {
1483 if (strcasecmp(mFiles
.valueAt(i
)->getLeaf().string(),
1484 mFiles
.valueAt(j
)->getLeaf().string()) == 0) {
1485 SourcePos(mFiles
.valueAt(i
)->getPrintableSource(), -1).error(
1486 "File is case-insensitive equivalent to: %s",
1487 mFiles
.valueAt(j
)->getPrintableSource().string());
1488 return UNKNOWN_ERROR
;
1491 // TODO: if ".gz", check for non-.gz; if non-, check for ".gz"
1492 // (this is mostly caught by the "marked" stuff, below)
1495 for (j
= 0; j
< ND
; j
++) {
1496 if (strcasecmp(mFiles
.valueAt(i
)->getLeaf().string(),
1497 mDirs
.valueAt(j
)->getLeaf().string()) == 0) {
1498 SourcePos(mFiles
.valueAt(i
)->getPrintableSource(), -1).error(
1499 "File conflicts with dir from: %s",
1500 mDirs
.valueAt(j
)->getPrintableSource().string());
1501 return UNKNOWN_ERROR
;
1506 for (i
= 0; i
< ND
; i
++) {
1507 if (!validateFileName(mDirs
.valueAt(i
)->getLeaf().string())) {
1508 SourcePos(mDirs
.valueAt(i
)->getPrintableSource(), -1).error(
1509 "Invalid directory name, unable to add.");
1510 return UNKNOWN_ERROR
;
1514 for (j
= i
+1; j
< ND
; j
++) {
1515 if (strcasecmp(mDirs
.valueAt(i
)->getLeaf().string(),
1516 mDirs
.valueAt(j
)->getLeaf().string()) == 0) {
1517 SourcePos(mDirs
.valueAt(i
)->getPrintableSource(), -1).error(
1518 "Directory is case-insensitive equivalent to: %s",
1519 mDirs
.valueAt(j
)->getPrintableSource().string());
1520 return UNKNOWN_ERROR
;
1524 status_t err
= mDirs
.valueAt(i
)->validate();
1525 if (err
!= NO_ERROR
) {
1533 void AaptDir::print() const
1535 const size_t ND
=getDirs().size();
1537 for (i
=0; i
<ND
; i
++) {
1538 getDirs().valueAt(i
)->print();
1541 const size_t NF
=getFiles().size();
1542 for (i
=0; i
<NF
; i
++) {
1543 getFiles().valueAt(i
)->print();
1547 String8
AaptDir::getPrintableSource() const
1549 if (mFiles
.size() > 0) {
1550 // Arbitrarily pull the first file out of the list as the source dir.
1551 return mFiles
.valueAt(0)->getPrintableSource().getPathDir();
1553 if (mDirs
.size() > 0) {
1554 // Or arbitrarily pull the first dir out of the list as the source dir.
1555 return mDirs
.valueAt(0)->getPrintableSource().getPathDir();
1558 // Should never hit this case, but to be safe...
1563 // =========================================================================
1564 // =========================================================================
1565 // =========================================================================
1567 sp
<AaptFile
> AaptAssets::addFile(
1568 const String8
& filePath
, const AaptGroupEntry
& entry
,
1569 const String8
& srcDir
, sp
<AaptGroup
>* outGroup
,
1570 const String8
& resType
)
1572 sp
<AaptDir
> dir
= this;
1573 sp
<AaptGroup
> group
;
1575 String8 root
, remain(filePath
), partialPath
;
1576 while (remain
.length() > 0) {
1577 root
= remain
.walkPath(&remain
);
1578 partialPath
.appendPath(root
);
1580 const String8
rootStr(root
);
1582 if (remain
.length() == 0) {
1583 ssize_t i
= dir
->getFiles().indexOfKey(rootStr
);
1585 group
= dir
->getFiles().valueAt(i
);
1587 group
= new AaptGroup(rootStr
, filePath
);
1588 status_t res
= dir
->addFile(rootStr
, group
);
1589 if (res
!= NO_ERROR
) {
1593 file
= new AaptFile(srcDir
.appendPathCopy(filePath
), entry
, resType
);
1594 status_t res
= group
->addFile(file
);
1595 if (res
!= NO_ERROR
) {
1601 ssize_t i
= dir
->getDirs().indexOfKey(rootStr
);
1603 dir
= dir
->getDirs().valueAt(i
);
1605 sp
<AaptDir
> subdir
= new AaptDir(rootStr
, partialPath
);
1606 status_t res
= dir
->addDir(rootStr
, subdir
);
1607 if (res
!= NO_ERROR
) {
1615 mGroupEntries
.add(entry
);
1616 if (outGroup
) *outGroup
= group
;
1620 void AaptAssets::addResource(const String8
& leafName
, const String8
& path
,
1621 const sp
<AaptFile
>& file
, const String8
& resType
)
1623 sp
<AaptDir
> res
= AaptDir::makeDir(kResString
);
1624 String8 dirname
= file
->getGroupEntry().toDirName(resType
);
1625 sp
<AaptDir
> subdir
= res
->makeDir(dirname
);
1626 sp
<AaptGroup
> grr
= new AaptGroup(leafName
, path
);
1629 subdir
->addFile(leafName
, grr
);
1633 ssize_t
AaptAssets::slurpFromArgs(Bundle
* bundle
)
1638 const Vector
<const char *>& resDirs
= bundle
->getResourceSourceDirs();
1639 const size_t dirCount
=resDirs
.size();
1640 sp
<AaptAssets
> current
= this;
1642 const int N
= bundle
->getFileSpecCount();
1645 * If a package manifest was specified, include that first.
1647 if (bundle
->getAndroidManifestFile() != NULL
) {
1648 // place at root of zip.
1649 String8
srcFile(bundle
->getAndroidManifestFile());
1650 addFile(srcFile
.getPathLeaf(), AaptGroupEntry(), srcFile
.getPathDir(),
1656 * If a directory of custom assets was supplied, slurp 'em up.
1658 if (bundle
->getAssetSourceDir()) {
1659 const char* assetDir
= bundle
->getAssetSourceDir();
1661 FileType type
= getFileType(assetDir
);
1662 if (type
== kFileTypeNonexistent
) {
1663 fprintf(stderr
, "ERROR: asset directory '%s' does not exist\n", assetDir
);
1664 return UNKNOWN_ERROR
;
1666 if (type
!= kFileTypeDirectory
) {
1667 fprintf(stderr
, "ERROR: '%s' is not a directory\n", assetDir
);
1668 return UNKNOWN_ERROR
;
1671 String8
assetRoot(assetDir
);
1672 sp
<AaptDir
> assetAaptDir
= makeDir(String8(kAssetDir
));
1673 AaptGroupEntry group
;
1674 count
= assetAaptDir
->slurpFullTree(bundle
, assetRoot
, group
,
1681 mGroupEntries
.add(group
);
1683 totalCount
+= count
;
1685 if (bundle
->getVerbose())
1686 printf("Found %d custom asset file%s in %s\n",
1687 count
, (count
==1) ? "" : "s", assetDir
);
1691 * If a directory of resource-specific assets was supplied, slurp 'em up.
1693 for (size_t i
=0; i
<dirCount
; i
++) {
1694 const char *res
= resDirs
[i
];
1696 type
= getFileType(res
);
1697 if (type
== kFileTypeNonexistent
) {
1698 fprintf(stderr
, "ERROR: resource directory '%s' does not exist\n", res
);
1699 return UNKNOWN_ERROR
;
1701 if (type
== kFileTypeDirectory
) {
1703 sp
<AaptAssets
> nextOverlay
= new AaptAssets();
1704 current
->setOverlay(nextOverlay
);
1705 current
= nextOverlay
;
1707 count
= current
->slurpResourceTree(bundle
, String8(res
));
1713 totalCount
+= count
;
1716 fprintf(stderr
, "ERROR: '%s' is not a directory\n", res
);
1717 return UNKNOWN_ERROR
;
1723 * Now do any additional raw files.
1725 for (int arg
=0; arg
<N
; arg
++) {
1726 const char* assetDir
= bundle
->getFileSpecEntry(arg
);
1728 FileType type
= getFileType(assetDir
);
1729 if (type
== kFileTypeNonexistent
) {
1730 fprintf(stderr
, "ERROR: input directory '%s' does not exist\n", assetDir
);
1731 return UNKNOWN_ERROR
;
1733 if (type
!= kFileTypeDirectory
) {
1734 fprintf(stderr
, "ERROR: '%s' is not a directory\n", assetDir
);
1735 return UNKNOWN_ERROR
;
1738 String8
assetRoot(assetDir
);
1740 if (bundle
->getVerbose())
1741 printf("Processing raw dir '%s'\n", (const char*) assetDir
);
1744 * Do a recursive traversal of subdir tree. We don't make any
1745 * guarantees about ordering, so we're okay with an inorder search
1746 * using whatever order the OS happens to hand back to us.
1748 count
= slurpFullTree(bundle
, assetRoot
, AaptGroupEntry(), String8());
1750 /* failure; report error and remove archive */
1754 totalCount
+= count
;
1756 if (bundle
->getVerbose())
1757 printf("Found %d asset file%s in %s\n",
1758 count
, (count
==1) ? "" : "s", assetDir
);
1762 if (count
!= NO_ERROR
) {
1772 ssize_t
AaptAssets::slurpFullTree(Bundle
* bundle
, const String8
& srcDir
,
1773 const AaptGroupEntry
& kind
,
1774 const String8
& resType
)
1776 ssize_t res
= AaptDir::slurpFullTree(bundle
, srcDir
, kind
, resType
);
1778 mGroupEntries
.add(kind
);
1784 ssize_t
AaptAssets::slurpResourceTree(Bundle
* bundle
, const String8
& srcDir
)
1788 DIR* dir
= opendir(srcDir
.string());
1790 fprintf(stderr
, "ERROR: opendir(%s): %s\n", srcDir
.string(), strerror(errno
));
1791 return UNKNOWN_ERROR
;
1797 * Run through the directory, looking for dirs that match the
1801 struct dirent
* entry
= readdir(dir
);
1802 if (entry
== NULL
) {
1806 if (isHidden(srcDir
.string(), entry
->d_name
)) {
1810 String8
subdirName(srcDir
);
1811 subdirName
.appendPath(entry
->d_name
);
1813 AaptGroupEntry group
;
1815 bool b
= group
.initFromDirName(entry
->d_name
, &resType
);
1817 fprintf(stderr
, "invalid resource directory name: %s/%s\n", srcDir
.string(),
1823 FileType type
= getFileType(subdirName
.string());
1825 if (type
== kFileTypeDirectory
) {
1826 sp
<AaptDir
> dir
= makeDir(String8(entry
->d_name
));
1827 ssize_t res
= dir
->slurpFullTree(bundle
, subdirName
, group
,
1834 mGroupEntries
.add(group
);
1840 if (bundle
->getVerbose()) {
1841 fprintf(stderr
, " (ignoring file '%s')\n", subdirName
.string());
1857 AaptAssets::slurpResourceZip(Bundle
* bundle
, const char* filename
)
1860 SortedVector
<AaptGroupEntry
> entries
;
1862 ZipFile
* zip
= new ZipFile
;
1863 status_t err
= zip
->open(filename
, ZipFile::kOpenReadOnly
);
1864 if (err
!= NO_ERROR
) {
1865 fprintf(stderr
, "error opening zip file %s\n", filename
);
1871 const int N
= zip
->getNumEntries();
1872 for (int i
=0; i
<N
; i
++) {
1873 ZipEntry
* entry
= zip
->getEntryByIndex(i
);
1874 if (entry
->getDeleted()) {
1878 String8
entryName(entry
->getFileName());
1880 String8 dirName
= entryName
.getPathDir();
1881 sp
<AaptDir
> dir
= dirName
== "" ? this : makeDir(dirName
);
1884 AaptGroupEntry kind
;
1887 if (entryName
.walkPath(&remain
) == kResourceDir
) {
1888 // these are the resources, pull their type out of the directory name
1889 kind
.initFromDirName(remain
.walkPath().string(), &resType
);
1891 // these are untyped and don't have an AaptGroupEntry
1893 if (entries
.indexOf(kind
) < 0) {
1895 mGroupEntries
.add(kind
);
1898 // use the one from the zip file if they both exist.
1899 dir
->removeFile(entryName
.getPathLeaf());
1901 sp
<AaptFile
> file
= new AaptFile(entryName
, kind
, resType
);
1902 status_t err
= dir
->addLeafFile(entryName
.getPathLeaf(), file
);
1903 if (err
!= NO_ERROR
) {
1904 fprintf(stderr
, "err=%s entryName=%s\n", strerror(err
), entryName
.string());
1908 file
->setCompressionMethod(entry
->getCompressionMethod());
1911 if (entryName
== "AndroidManifest.xml") {
1912 printf("AndroidManifest.xml\n");
1914 printf("\n\nfile: %s\n", entryName
.string());
1917 size_t len
= entry
->getUncompressedLen();
1918 void* data
= zip
->uncompress(entry
);
1919 void* buf
= file
->editData(len
);
1920 memcpy(buf
, data
, len
);
1924 const unsigned char* p
= (unsigned char*)data
;
1925 const unsigned char* end
= p
+len
;
1927 for (int i
=0; i
<32 && p
< end
; i
++) {
1928 printf("0x%03x ", i
*0x10 + OFF
);
1929 for (int j
=0; j
<0x10 && p
< end
; j
++) {
1930 printf(" %02x", *p
);
1947 sp
<AaptSymbols
> AaptAssets::getSymbolsFor(const String8
& name
)
1949 sp
<AaptSymbols
> sym
= mSymbols
.valueFor(name
);
1951 sym
= new AaptSymbols();
1952 mSymbols
.add(name
, sym
);
1957 status_t
AaptAssets::buildIncludedResources(Bundle
* bundle
)
1959 if (!mHaveIncludedAssets
) {
1960 // Add in all includes.
1961 const Vector
<const char*>& incl
= bundle
->getPackageIncludes();
1962 const size_t N
=incl
.size();
1963 for (size_t i
=0; i
<N
; i
++) {
1964 if (bundle
->getVerbose())
1965 printf("Including resources from package: %s\n", incl
[i
]);
1966 if (!mIncludedAssets
.addAssetPath(String8(incl
[i
]), NULL
)) {
1967 fprintf(stderr
, "ERROR: Asset package include '%s' not found.\n",
1969 return UNKNOWN_ERROR
;
1972 mHaveIncludedAssets
= true;
1978 status_t
AaptAssets::addIncludedResources(const sp
<AaptFile
>& file
)
1980 const ResTable
& res
= getIncludedResources();
1982 return const_cast<ResTable
&>(res
).add(file
->getData(), file
->getSize(), NULL
);
1985 const ResTable
& AaptAssets::getIncludedResources() const
1987 return mIncludedAssets
.getResources(false);
1990 void AaptAssets::print() const
1992 printf("Locale/Vendor pairs:\n");
1993 const size_t N
=mGroupEntries
.size();
1994 for (size_t i
=0; i
<N
; i
++) {
1996 mGroupEntries
.itemAt(i
).locale
.string(),
1997 mGroupEntries
.itemAt(i
).vendor
.string());
2000 printf("\nFiles:\n");
2004 sp
<AaptDir
> AaptAssets::resDir(const String8
& name
)
2006 const Vector
<sp
<AaptDir
> >& dirs
= mDirs
;
2007 const size_t N
= dirs
.size();
2008 for (size_t i
=0; i
<N
; i
++) {
2009 const sp
<AaptDir
>& d
= dirs
.itemAt(i
);
2010 if (d
->getLeaf() == name
) {
2018 valid_symbol_name(const String8
& symbol
)
2020 static char const * const KEYWORDS
[] = {
2021 "abstract", "assert", "boolean", "break",
2022 "byte", "case", "catch", "char", "class", "const", "continue",
2023 "default", "do", "double", "else", "enum", "extends", "final",
2024 "finally", "float", "for", "goto", "if", "implements", "import",
2025 "instanceof", "int", "interface", "long", "native", "new", "package",
2026 "private", "protected", "public", "return", "short", "static",
2027 "strictfp", "super", "switch", "synchronized", "this", "throw",
2028 "throws", "transient", "try", "void", "volatile", "while",
2029 "true", "false", "null",
2032 const char*const* k
= KEYWORDS
;
2033 const char*const s
= symbol
.string();
2035 if (0 == strcmp(s
, *k
)) {