AaptAssets.cpp revision b0db8de73e6e4151b4e9d1fe3be1f609c3c1fb83
1282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// 2282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// Copyright 2006 The Android Open Source Project 3282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// 4282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 5282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "AaptAssets.h" 6fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski#include "AaptConfig.h" 7fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski#include "AaptUtil.h" 8282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "Main.h" 9fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski#include "ResourceFilter.h" 10282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 11282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <utils/misc.h> 12282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <utils/SortedVector.h> 13282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 14282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <ctype.h> 15282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <dirent.h> 16282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <errno.h> 17282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 18282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char* kDefaultLocale = "default"; 19282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char* kAssetDir = "assets"; 20282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char* kResourceDir = "res"; 21282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char* kValuesDir = "values"; 22282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char* kMipmapDir = "mipmap"; 23282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char* kInvalidChars = "/\\:"; 24282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const size_t kMaxAssetFileName = 100; 25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 26282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const String8 kResString(kResourceDir); 27282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 28282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Names of asset files must meet the following criteria: 30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * - the filename length must be less than kMaxAssetFileName bytes long 32282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * (and can't be empty) 33282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * - all characters must be 7-bit printable ASCII 34282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * - none of { '/' '\\' ':' } 35282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 36282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Pass in just the filename, not the full path. 37282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic bool validateFileName(const char* fileName) 39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* cp = fileName; 41282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len = 0; 42282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (*cp != '\0') { 44282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((*cp & 0x80) != 0) 45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; // reject high ASCII 46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (*cp < 0x20 || *cp >= 0x7f) 47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; // reject control chars and 0x7f 48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strchr(kInvalidChars, *cp) != NULL) 49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; // reject path sep chars 50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski cp++; 51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski len++; 52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (len < 1 || len > kMaxAssetFileName) 55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; // reject empty or too long 56282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 57282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 58282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// The default to use if no other ignore pattern is defined. 61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiconst char * const gDefaultIgnoreAssets = 62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"; 63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// The ignore pattern that can be passed via --ignore-assets in Main.cpp 64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiconst char * gUserIgnoreAssets = NULL; 65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic bool isHidden(const char *root, const char *path) 67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Patterns syntax: 69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // - Delimiter is : 70282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // - Entry can start with the flag ! to avoid printing a warning 71282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // about the file being ignored. 72282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // - Entry can have the flag "<dir>" to match only directories 73282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // or <file> to match only files. Default is to match both. 74282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // - Entry can be a simplified glob "<prefix>*" or "*<suffix>" 75282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // where prefix/suffix must have at least 1 character (so that 76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // we don't match a '*' catch-all pattern.) 77282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // - The special filenames "." and ".." are always ignored. 78282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // - Otherwise the full string is matched. 79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // - match is not case-sensitive. 80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp(path, ".") == 0 || strcmp(path, "..") == 0) { 82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char *delim = ":"; 86282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char *p = gUserIgnoreAssets; 87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!p || !p[0]) { 88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p = getenv("ANDROID_AAPT_IGNORE"); 89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!p || !p[0]) { 91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p = gDefaultIgnoreAssets; 92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 93282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char *patterns = strdup(p); 94282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool ignore = false; 96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool chatty = true; 97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char *matchedPattern = NULL; 98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 fullPath(root); 100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fullPath.appendPath(path); 101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FileType type = getFileType(fullPath); 102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int plen = strlen(path); 104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Note: we don't have strtok_r under mingw. 106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for(char *token = strtok(patterns, delim); 107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski !ignore && token != NULL; 108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski token = strtok(NULL, delim)) { 109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski chatty = token[0] != '!'; 110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!chatty) token++; // skip ! 111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strncasecmp(token, "<dir>" , 5) == 0) { 112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (type != kFileTypeDirectory) continue; 113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski token += 5; 114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strncasecmp(token, "<file>", 6) == 0) { 116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (type != kFileTypeRegular) continue; 117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski token += 6; 118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski matchedPattern = token; 121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int n = strlen(token); 122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (token[0] == '*') { 124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Match *suffix 125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski token++; 126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski n--; 127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (n <= plen) { 128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ignore = strncasecmp(token, path + plen - n, n) == 0; 129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (n > 1 && token[n - 1] == '*') { 131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Match prefix* 132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ignore = strncasecmp(token, path, n - 1) == 0; 133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ignore = strcasecmp(token, path) == 0; 135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (ignore && chatty) { 139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, " (skipping %s '%s' due to ANDROID_AAPT_IGNORE pattern '%s')\n", 140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type == kFileTypeDirectory ? "dir" : "file", 141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski path, 142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski matchedPattern ? matchedPattern : ""); 143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski free(patterns); 146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ignore; 147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================= 150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================= 151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================= 152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 15391447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath/* static */ 15491447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamathinline bool isAlpha(const String8& string) { 15591447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath const size_t length = string.length(); 15691447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath for (size_t i = 0; i < length; ++i) { 15791447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath if (!isalpha(string[i])) { 15891447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath return false; 15991447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath } 16091447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath } 16191447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath 16291447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath return true; 16391447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath} 16491447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath 16591447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath/* static */ 16691447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamathinline bool isNumber(const String8& string) { 16791447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath const size_t length = string.length(); 16891447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath for (size_t i = 0; i < length; ++i) { 16991447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath if (!isdigit(string[i])) { 17091447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath return false; 17191447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath } 17291447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath } 17391447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath 17491447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath return true; 17591447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath} 17691447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath 17791447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamathvoid AaptLocaleValue::setLanguage(const char* languageChars) { 17891447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath size_t i = 0; 17991447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath while ((*languageChars) != '\0') { 18091447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath language[i++] = tolower(*languageChars); 18191447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath languageChars++; 18291447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath } 18391447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath} 18491447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath 18591447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamathvoid AaptLocaleValue::setRegion(const char* regionChars) { 18691447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath size_t i = 0; 18791447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath while ((*regionChars) != '\0') { 18891447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath region[i++] = toupper(*regionChars); 18991447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath regionChars++; 19091447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath } 19191447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath} 19291447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath 19391447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamathvoid AaptLocaleValue::setScript(const char* scriptChars) { 19491447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath size_t i = 0; 19591447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath while ((*scriptChars) != '\0') { 19691447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath if (i == 0) { 19791447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath script[i++] = toupper(*scriptChars); 19891447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath } else { 19991447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath script[i++] = tolower(*scriptChars); 20091447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath } 20191447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath scriptChars++; 20291447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath } 20391447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath} 20491447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath 20591447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamathvoid AaptLocaleValue::setVariant(const char* variantChars) { 20691447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath size_t i = 0; 20791447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath while ((*variantChars) != '\0') { 20891447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath variant[i++] = *variantChars; 20991447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath variantChars++; 21091447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath } 21191447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath} 21291447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath 21391447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamathbool AaptLocaleValue::initFromFilterString(const String8& str) { 21491447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath // A locale (as specified in the filter) is an underscore separated name such 21591447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath // as "en_US", "en_Latn_US", or "en_US_POSIX". 216fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski Vector<String8> parts = AaptUtil::splitAndLowerCase(str, '_'); 21791447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath 21891447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath const int numTags = parts.size(); 21991447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath bool valid = false; 22091447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath if (numTags >= 1) { 22191447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath const String8& lang = parts[0]; 22291447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath if (isAlpha(lang) && (lang.length() == 2 || lang.length() == 3)) { 22391447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath setLanguage(lang.string()); 22491447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath valid = true; 22591447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath } 22691447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath } 22791447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath 22891447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath if (!valid || numTags == 1) { 229fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return valid; 230fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 232fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // At this point, valid == true && numTags > 1. 233fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const String8& part2 = parts[1]; 234fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if ((part2.length() == 2 && isAlpha(part2)) || 235fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski (part2.length() == 3 && isNumber(part2))) { 236fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setRegion(part2.string()); 237fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else if (part2.length() == 4 && isAlpha(part2)) { 238fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setScript(part2.string()); 239fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else if (part2.length() >= 5 && part2.length() <= 8) { 240fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setVariant(part2.string()); 241fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else { 242fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski valid = false; 243fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 245fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (!valid || numTags == 2) { 246fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return valid; 247fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 249fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // At this point, valid == true && numTags > 1. 250fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const String8& part3 = parts[2]; 251fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (((part3.length() == 2 && isAlpha(part3)) || 252fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski (part3.length() == 3 && isNumber(part3))) && script[0]) { 253fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setRegion(part3.string()); 254fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else if (part3.length() >= 5 && part3.length() <= 8) { 255fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setVariant(part3.string()); 256fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else { 257fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski valid = false; 258fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 260fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (!valid || numTags == 3) { 261fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return valid; 262fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 264fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const String8& part4 = parts[3]; 265fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (part4.length() >= 5 && part4.length() <= 8) { 266fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setVariant(part4.string()); 267fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else { 268fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski valid = false; 269fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 271fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (!valid || numTags > 4) { 272fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return false; 273fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 275fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return true; 276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 278fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskiint AaptLocaleValue::initFromDirName(const Vector<String8>& parts, const int startIndex) { 279fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const int size = parts.size(); 280fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski int currentIndex = startIndex; 281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 282fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski String8 part = parts[currentIndex]; 283fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (part[0] == 'b' && part[1] == '+') { 284fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // This is a "modified" BCP-47 language tag. Same semantics as BCP-47 tags, 285fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // except that the separator is "+" and not "-". 286fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski Vector<String8> subtags = AaptUtil::splitAndLowerCase(part, '+'); 287fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski subtags.removeItemsAt(0); 288fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (subtags.size() == 1) { 289fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setLanguage(subtags[0]); 290fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else if (subtags.size() == 2) { 291fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setLanguage(subtags[0]); 292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 293fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // The second tag can either be a region, a variant or a script. 294fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski switch (subtags[1].size()) { 295fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski case 2: 296fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski case 3: 297fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setRegion(subtags[1]); 298fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski break; 299fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski case 4: 300fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setScript(subtags[1]); 301fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski break; 302fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski case 5: 303fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski case 6: 304fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski case 7: 305fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski case 8: 306fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setVariant(subtags[1]); 307fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski break; 308fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski default: 309fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski fprintf(stderr, "ERROR: Invalid BCP-47 tag in directory name %s\n", 310fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski part.string()); 311fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return -1; 312fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 313fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else if (subtags.size() == 3) { 314fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // The language is always the first subtag. 315fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setLanguage(subtags[0]); 316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 317fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // The second subtag can either be a script or a region code. 318fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // If its size is 4, it's a script code, else it's a region code. 319fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski bool hasRegion = false; 320fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (subtags[1].size() == 4) { 321fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setScript(subtags[1]); 322fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else if (subtags[1].size() == 2 || subtags[1].size() == 3) { 323fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setRegion(subtags[1]); 324fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski hasRegion = true; 325fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else { 326fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski fprintf(stderr, "ERROR: Invalid BCP-47 tag in directory name %s\n", part.string()); 327fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return -1; 328fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 330fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // The third tag can either be a region code (if the second tag was 331fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // a script), else a variant code. 332fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (subtags[2].size() > 4) { 333fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setVariant(subtags[2]); 334fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else { 335fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setRegion(subtags[2]); 336fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 337fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else if (subtags.size() == 4) { 338fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setLanguage(subtags[0]); 339fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setScript(subtags[1]); 340fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setRegion(subtags[2]); 341fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setVariant(subtags[3]); 342fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else { 343fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski fprintf(stderr, "ERROR: Invalid BCP-47 tag in directory name: %s\n", part.string()); 344fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return -1; 345fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 347fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return ++currentIndex; 348fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else { 349fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if ((part.length() == 2 || part.length() == 3) && isAlpha(part)) { 350fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setLanguage(part); 351fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (++currentIndex == size) { 352fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return size; 353fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 354fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else { 355fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return currentIndex; 356fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 358fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski part = parts[currentIndex]; 359fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (part.string()[0] == 'r' && part.length() == 3) { 360fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setRegion(part.string() + 1); 361fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (++currentIndex == size) { 362fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return size; 363fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 367fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return currentIndex; 368fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski} 369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 371fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam LesinskiString8 AaptLocaleValue::toDirName() const { 372fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski String8 dirName(""); 373fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (language[0]) { 374fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski dirName += language; 375fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else { 376fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return dirName; 377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 379fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (script[0]) { 380fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski dirName += "-s"; 381fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski dirName += script; 382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 384fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (region[0]) { 385fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski dirName += "-r"; 386fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski dirName += region; 387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 389fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (variant[0]) { 390fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski dirName += "-v"; 391fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski dirName += variant; 392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 394fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return dirName; 395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 397fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskivoid AaptLocaleValue::initFromResTable(const ResTable_config& config) { 398fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski config.unpackLanguage(language); 399fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski config.unpackRegion(region); 400fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (config.localeScript[0]) { 401fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski memcpy(script, config.localeScript, sizeof(config.localeScript)); 402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 404fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (config.localeVariant[0]) { 405fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski memcpy(variant, config.localeVariant, sizeof(config.localeVariant)); 406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 409fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskivoid AaptLocaleValue::writeTo(ResTable_config* out) const { 410fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski out->packLanguage(language); 411fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski out->packRegion(region); 412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 413fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (script[0]) { 414fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski memcpy(out->localeScript, script, sizeof(out->localeScript)); 415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 417fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (variant[0]) { 418fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski memcpy(out->localeVariant, variant, sizeof(out->localeVariant)); 419fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 422fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool 423fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam LesinskiAaptGroupEntry::initFromDirName(const char* dir, String8* resType) 424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 425fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const char* q = strchr(dir, '-'); 426fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski size_t typeLen; 427fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (q != NULL) { 428fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski typeLen = q - dir; 429fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else { 430fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski typeLen = strlen(dir); 431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 433fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski String8 type(dir, typeLen); 434fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (!isValidResourceType(type)) { 435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 438fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (q != NULL) { 439fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (!AaptConfig::parse(String8(q + 1), &mParams)) { 440fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return false; 441fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 444fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski *resType = type; 445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 448fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam LesinskiString8 449fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam LesinskiAaptGroupEntry::toDirName(const String8& resType) const 450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 451fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski String8 s = resType; 452fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski String8 params = mParams.toString(); 453fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (params.length() > 0) { 454fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (s.length() > 0) { 455fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski s += "-"; 456fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 457fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski s += params; 458fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 459fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return s; 460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================= 464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================= 465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================= 466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid* AaptFile::editData(size_t size) 468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (size <= mBufferSize) { 470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDataSize = size; 471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mData; 472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t allocSize = (size*3)/2; 474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski void* buf = realloc(mData, allocSize); 475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (buf == NULL) { 476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mData = buf; 479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDataSize = size; 480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mBufferSize = allocSize; 481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return buf; 482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 484de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinskivoid* AaptFile::editDataInRange(size_t offset, size_t size) 485de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski{ 486de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski return (void*)(((uint8_t*) editData(offset + size)) + offset); 487de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski} 488de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid* AaptFile::editData(size_t* outSize) 490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outSize) { 492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outSize = mDataSize; 493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mData; 495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid* AaptFile::padData(size_t wordSize) 498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t extra = mDataSize%wordSize; 500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (extra == 0) { 501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mData; 502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t initial = mDataSize; 505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski void* data = editData(initial+(wordSize-extra)); 506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (data != NULL) { 507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memset(((uint8_t*)data) + initial, 0, wordSize-extra); 508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return data; 510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AaptFile::writeData(const void* data, size_t size) 513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t end = mDataSize; 515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t total = size + end; 516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski void* buf = editData(total); 517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (buf == NULL) { 518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memcpy(((char*)buf)+end, data, size); 521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AaptFile::clearData() 525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mData != NULL) free(mData); 527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mData = NULL; 528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDataSize = 0; 529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mBufferSize = 0; 530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 532282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiString8 AaptFile::getPrintableSource() const 533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasData()) { 535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name(mGroupEntry.toDirName(String8())); 536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name.appendPath(mPath); 537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name.append(" #generated"); 538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return name; 539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mSourceFile; 541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================= 544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================= 545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================= 546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 54709384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinskistatus_t AaptGroup::addFile(const sp<AaptFile>& file, const bool overwriteDuplicate) 548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 54909384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski ssize_t index = mFiles.indexOfKey(file->getGroupEntry()); 55009384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski if (index >= 0 && overwriteDuplicate) { 55109384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski fprintf(stderr, "warning: overwriting '%s' with '%s'\n", 55209384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski mFiles[index]->getSourceFile().string(), 55309384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski file->getSourceFile().string()); 55409384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski removeFile(index); 55509384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski index = -1; 55609384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski } 55709384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski 55809384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski if (index < 0) { 559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski file->mPath = mPath; 560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mFiles.add(file->getGroupEntry(), file); 561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#if 0 565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Error adding file %s: group %s already exists in leaf=%s path=%s\n", 566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski file->getSourceFile().string(), 567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski file->getGroupEntry().toDirName(String8()).string(), 568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLeaf.string(), mPath.string()); 569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(file->getSourceFile(), -1).error("Duplicate file.\n%s: Original is here.", 572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getPrintableSource().string()); 573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AaptGroup::removeFile(size_t index) 577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mFiles.removeItemsAt(index); 579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AaptGroup::print(const String8& prefix) const 582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("%s%s\n", prefix.string(), getPath().string()); 584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N=mFiles.size(); 585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> file = mFiles.valueAt(i); 588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const AaptGroupEntry& e = file->getGroupEntry(); 589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (file->hasData()) { 590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("%s Gen: (%s) %d bytes\n", prefix.string(), e.toDirName(String8()).string(), 591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (int)file->getSize()); 592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("%s Src: (%s) %s\n", prefix.string(), e.toDirName(String8()).string(), 594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski file->getPrintableSource().string()); 595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("%s File Group Entry: %s\n", prefix.string(), 597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // file->getGroupEntry().toDirName(String8()).string()); 598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 601282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiString8 AaptGroup::getPrintableSource() const 602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mFiles.size() > 0) { 604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Arbitrarily pull the first source file out of the list. 605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mFiles.valueAt(0)->getPrintableSource(); 606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Should never hit this case, but to be safe... 609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return getPath(); 610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================= 614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================= 615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================= 616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AaptDir::addFile(const String8& name, const sp<AaptGroup>& file) 618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mFiles.indexOfKey(name) >= 0) { 620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ALREADY_EXISTS; 621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mFiles.add(name, file); 623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AaptDir::addDir(const String8& name, const sp<AaptDir>& dir) 627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mDirs.indexOfKey(name) >= 0) { 629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ALREADY_EXISTS; 630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDirs.add(name, dir); 632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<AaptDir> AaptDir::makeDir(const String8& path) 636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name; 638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 remain = path; 639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptDir> subdir = this; 641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (name = remain.walkPath(&remain), remain != "") { 642282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski subdir = subdir->makeDir(name); 643282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t i = subdir->mDirs.indexOfKey(name); 646282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (i >= 0) { 647282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return subdir->mDirs.valueAt(i); 648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 649282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptDir> dir = new AaptDir(name, subdir->mPath.appendPathCopy(name)); 650282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski subdir->mDirs.add(name, dir); 651282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return dir; 652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 653282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 654282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AaptDir::removeFile(const String8& name) 655282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 656282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mFiles.removeItem(name); 657282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 658282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 659282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AaptDir::removeDir(const String8& name) 660282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 661282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDirs.removeItem(name); 662282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 663282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 66409384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinskistatus_t AaptDir::addLeafFile(const String8& leafName, const sp<AaptFile>& file, 66509384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski const bool overwrite) 666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 667282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptGroup> group; 668282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mFiles.indexOfKey(leafName) >= 0) { 669282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski group = mFiles.valueFor(leafName); 670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski group = new AaptGroup(leafName, mPath.appendPathCopy(leafName)); 672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mFiles.add(leafName, group); 673282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 67509384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski return group->addFile(file, overwrite); 676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskissize_t AaptDir::slurpFullTree(Bundle* bundle, const String8& srcDir, 679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const AaptGroupEntry& kind, const String8& resType, 68009384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski sp<FilePathStore>& fullResPaths, const bool overwrite) 681282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<String8> fileNames; 683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DIR* dir = NULL; 685282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dir = opendir(srcDir.string()); 687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (dir == NULL) { 688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: opendir(%s): %s\n", srcDir.string(), strerror(errno)); 689282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 693282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Slurp the filenames out of the directory. 694282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 695282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (1) { 696282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski struct dirent* entry; 697282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 698282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski entry = readdir(dir); 699282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (entry == NULL) 700282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 701282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 702282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (isHidden(srcDir.string(), entry->d_name)) 703282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 704282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 705282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name(entry->d_name); 706282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fileNames.add(name); 707282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Add fully qualified path for dependency purposes 708282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // if we're collecting them 709282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (fullResPaths != NULL) { 710282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fullResPaths->add(srcDir.appendPathCopy(name)); 711282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 712282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski closedir(dir); 714282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 715282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 716282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t count = 0; 717282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 718282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 719282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Stash away the files and recursively descend into subdirectories. 720282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 721282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = fileNames.size(); 722282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i = 0; i < N; i++) { 724282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 pathName(srcDir); 725282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FileType type; 726282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 727282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pathName.appendPath(fileNames[i].string()); 728282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type = getFileType(pathName.string()); 729282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (type == kFileTypeDirectory) { 730282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptDir> subdir; 731282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool notAdded = false; 732282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mDirs.indexOfKey(fileNames[i]) >= 0) { 733282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski subdir = mDirs.valueFor(fileNames[i]); 734282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 735282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski subdir = new AaptDir(fileNames[i], mPath.appendPathCopy(fileNames[i])); 736282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski notAdded = true; 737282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 738282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t res = subdir->slurpFullTree(bundle, pathName, kind, 73909384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski resType, fullResPaths, overwrite); 740282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (res < NO_ERROR) { 741282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return res; 742282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 743282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (res > 0 && notAdded) { 744282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDirs.add(fileNames[i], subdir); 745282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 746282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski count += res; 747282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (type == kFileTypeRegular) { 748282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> file = new AaptFile(pathName, kind, resType); 74909384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski status_t err = addLeafFile(fileNames[i], file, overwrite); 750282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 751282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 752282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 753282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 754282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski count++; 755282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 756282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 757282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) 758282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" (ignoring non-file/dir '%s')\n", pathName.string()); 759282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 760282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 761282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 762282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return count; 763282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 764282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 765282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AaptDir::validate() const 766282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 767282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NF = mFiles.size(); 768282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t ND = mDirs.size(); 769282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 770282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i = 0; i < NF; i++) { 771282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!validateFileName(mFiles.valueAt(i)->getLeaf().string())) { 772282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(mFiles.valueAt(i)->getPrintableSource(), -1).error( 773282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Invalid filename. Unable to add."); 774282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 775282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 776282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 777282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t j; 778282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (j = i+1; j < NF; j++) { 779282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcasecmp(mFiles.valueAt(i)->getLeaf().string(), 780282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mFiles.valueAt(j)->getLeaf().string()) == 0) { 781282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(mFiles.valueAt(i)->getPrintableSource(), -1).error( 782282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "File is case-insensitive equivalent to: %s", 783282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mFiles.valueAt(j)->getPrintableSource().string()); 784282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 785282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 786282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 787282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // TODO: if ".gz", check for non-.gz; if non-, check for ".gz" 788282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // (this is mostly caught by the "marked" stuff, below) 789282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 790282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 791282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (j = 0; j < ND; j++) { 792282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcasecmp(mFiles.valueAt(i)->getLeaf().string(), 793282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDirs.valueAt(j)->getLeaf().string()) == 0) { 794282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(mFiles.valueAt(i)->getPrintableSource(), -1).error( 795282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "File conflicts with dir from: %s", 796282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDirs.valueAt(j)->getPrintableSource().string()); 797282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 798282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 799282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 800282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 801282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 802282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i = 0; i < ND; i++) { 803282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!validateFileName(mDirs.valueAt(i)->getLeaf().string())) { 804282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(mDirs.valueAt(i)->getPrintableSource(), -1).error( 805282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Invalid directory name, unable to add."); 806282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 807282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 808282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 809282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t j; 810282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (j = i+1; j < ND; j++) { 811282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcasecmp(mDirs.valueAt(i)->getLeaf().string(), 812282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDirs.valueAt(j)->getLeaf().string()) == 0) { 813282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(mDirs.valueAt(i)->getPrintableSource(), -1).error( 814282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Directory is case-insensitive equivalent to: %s", 815282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDirs.valueAt(j)->getPrintableSource().string()); 816282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 817282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 820282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = mDirs.valueAt(i)->validate(); 821282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 822282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 823282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 824282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 825282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 826282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 827282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 828282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 829282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AaptDir::print(const String8& prefix) const 830282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 831282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t ND=getDirs().size(); 832282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 833282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<ND; i++) { 834282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getDirs().valueAt(i)->print(prefix); 835282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 836282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 837282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NF=getFiles().size(); 838282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<NF; i++) { 839282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getFiles().valueAt(i)->print(prefix); 840282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 841282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 842282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 843282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiString8 AaptDir::getPrintableSource() const 844282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mFiles.size() > 0) { 846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Arbitrarily pull the first file out of the list as the source dir. 847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mFiles.valueAt(0)->getPrintableSource().getPathDir(); 848282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 849282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mDirs.size() > 0) { 850282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Or arbitrarily pull the first dir out of the list as the source dir. 851282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mDirs.valueAt(0)->getPrintableSource().getPathDir(); 852282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 853282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 854282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Should never hit this case, but to be safe... 855282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mPath; 856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 857282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 858282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 859282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================= 860282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================= 861282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================= 862282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 863282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AaptSymbols::applyJavaSymbols(const sp<AaptSymbols>& javaSymbols) 864282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 865282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = NO_ERROR; 866282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t N = javaSymbols->mSymbols.size(); 867282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 868282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String8& name = javaSymbols->mSymbols.keyAt(i); 869282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const AaptSymbolEntry& entry = javaSymbols->mSymbols.valueAt(i); 870282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t pos = mSymbols.indexOfKey(name); 871282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pos < 0) { 872282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski entry.sourcePos.error("Symbol '%s' declared with <java-symbol> not defined\n", name.string()); 873282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = UNKNOWN_ERROR; 874282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 875282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 876282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("**** setting symbol #%d/%d %s to isJavaSymbol=%d\n", 877282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // i, N, name.string(), entry.isJavaSymbol ? 1 : 0); 878282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mSymbols.editValueAt(pos).isJavaSymbol = entry.isJavaSymbol; 879282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 880282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 881282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski N = javaSymbols->mNestedSymbols.size(); 882282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 883282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String8& name = javaSymbols->mNestedSymbols.keyAt(i); 884282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptSymbols>& symbols = javaSymbols->mNestedSymbols.valueAt(i); 885282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t pos = mNestedSymbols.indexOfKey(name); 886282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pos < 0) { 887282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos pos; 888282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pos.error("Java symbol dir %s not defined\n", name.string()); 889282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = UNKNOWN_ERROR; 890282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 891282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 892282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("**** applying java symbols in dir %s\n", name.string()); 893282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t myerr = mNestedSymbols.valueAt(pos)->applyJavaSymbols(symbols); 894282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (myerr != NO_ERROR) { 895282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = myerr; 896282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 897282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 898282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 899282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 900282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 901282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 902282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================= 903282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================= 904282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================= 905282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 906282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiAaptAssets::AaptAssets() 907282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski : AaptDir(String8(), String8()), 90891447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath mHavePrivateSymbols(false), 90991447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath mChanged(false), mHaveIncludedAssets(false), 910fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski mRes(NULL) {} 911282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 912282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiconst SortedVector<AaptGroupEntry>& AaptAssets::getGroupEntries() const { 913282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mChanged) { 914282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 915282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mGroupEntries; 916282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 917282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 918282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AaptAssets::addFile(const String8& name, const sp<AaptGroup>& file) 919282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 920282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mChanged = true; 921282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return AaptDir::addFile(name, file); 922282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 923282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 924282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<AaptFile> AaptAssets::addFile( 925282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String8& filePath, const AaptGroupEntry& entry, 926282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String8& srcDir, sp<AaptGroup>* outGroup, 927282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String8& resType) 928282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 929282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptDir> dir = this; 930282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptGroup> group; 931282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> file; 932282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 root, remain(filePath), partialPath; 933282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (remain.length() > 0) { 934282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski root = remain.walkPath(&remain); 935282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski partialPath.appendPath(root); 936282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 937282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String8 rootStr(root); 938282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 939282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (remain.length() == 0) { 940282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t i = dir->getFiles().indexOfKey(rootStr); 941282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (i >= 0) { 942282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski group = dir->getFiles().valueAt(i); 943282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 944282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski group = new AaptGroup(rootStr, filePath); 945282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t res = dir->addFile(rootStr, group); 946282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (res != NO_ERROR) { 947282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 948282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 949282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 950282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski file = new AaptFile(srcDir.appendPathCopy(filePath), entry, resType); 951282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t res = group->addFile(file); 952282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (res != NO_ERROR) { 953282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 954282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 955282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 956282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 957282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 958282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t i = dir->getDirs().indexOfKey(rootStr); 959282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (i >= 0) { 960282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dir = dir->getDirs().valueAt(i); 961282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 962282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptDir> subdir = new AaptDir(rootStr, partialPath); 963282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t res = dir->addDir(rootStr, subdir); 964282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (res != NO_ERROR) { 965282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 966282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 967282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dir = subdir; 968282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 969282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 970282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 971282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 972282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mGroupEntries.add(entry); 973282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outGroup) *outGroup = group; 974282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return file; 975282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 976282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 977282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AaptAssets::addResource(const String8& leafName, const String8& path, 978282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptFile>& file, const String8& resType) 979282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 980282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptDir> res = AaptDir::makeDir(kResString); 981282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 dirname = file->getGroupEntry().toDirName(resType); 982282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptDir> subdir = res->makeDir(dirname); 983282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptGroup> grr = new AaptGroup(leafName, path); 984282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski grr->addFile(file); 985282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 986282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski subdir->addFile(leafName, grr); 987282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 988282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 989282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 990282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskissize_t AaptAssets::slurpFromArgs(Bundle* bundle) 991282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 992282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int count; 993282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int totalCount = 0; 994282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FileType type; 995282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<const char *>& resDirs = bundle->getResourceSourceDirs(); 996282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t dirCount =resDirs.size(); 997282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptAssets> current = this; 998282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 999282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const int N = bundle->getFileSpecCount(); 1000282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1001282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 1002282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * If a package manifest was specified, include that first. 1003282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 1004282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getAndroidManifestFile() != NULL) { 1005282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // place at root of zip. 1006282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 srcFile(bundle->getAndroidManifestFile()); 1007282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski addFile(srcFile.getPathLeaf(), AaptGroupEntry(), srcFile.getPathDir(), 1008282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NULL, String8()); 1009282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalCount++; 1010282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1011282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1012282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 1013282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * If a directory of custom assets was supplied, slurp 'em up. 1014282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 101509384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski const Vector<const char*>& assetDirs = bundle->getAssetSourceDirs(); 101609384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski const int AN = assetDirs.size(); 101709384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski for (int i = 0; i < AN; i++) { 101809384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski FileType type = getFileType(assetDirs[i]); 1019282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (type == kFileTypeNonexistent) { 102009384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski fprintf(stderr, "ERROR: asset directory '%s' does not exist\n", assetDirs[i]); 1021282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1022282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1023282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (type != kFileTypeDirectory) { 102409384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski fprintf(stderr, "ERROR: '%s' is not a directory\n", assetDirs[i]); 1025282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1026282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1027282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 102809384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski String8 assetRoot(assetDirs[i]); 1029282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptDir> assetAaptDir = makeDir(String8(kAssetDir)); 1030282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AaptGroupEntry group; 1031282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski count = assetAaptDir->slurpFullTree(bundle, assetRoot, group, 103209384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski String8(), mFullAssetPaths, true); 1033282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (count < 0) { 1034282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalCount = count; 1035282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1036282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1037282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (count > 0) { 1038282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mGroupEntries.add(group); 1039282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1040282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalCount += count; 1041282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 104209384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski if (bundle->getVerbose()) { 1043282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Found %d custom asset file%s in %s\n", 104409384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski count, (count==1) ? "" : "s", assetDirs[i]); 104509384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski } 1046282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1047282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1048282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 1049282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * If a directory of resource-specific assets was supplied, slurp 'em up. 1050282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 1051282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<dirCount; i++) { 1052282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char *res = resDirs[i]; 1053282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (res) { 1054282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type = getFileType(res); 1055282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (type == kFileTypeNonexistent) { 1056282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: resource directory '%s' does not exist\n", res); 1057282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1058282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1059282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (type == kFileTypeDirectory) { 1060282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (i>0) { 1061282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptAssets> nextOverlay = new AaptAssets(); 1062282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski current->setOverlay(nextOverlay); 1063282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski current = nextOverlay; 1064282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski current->setFullResPaths(mFullResPaths); 1065282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1066282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski count = current->slurpResourceTree(bundle, String8(res)); 10679ab9b93eae8b2fc747d6101cf0e4c19b2218715fBryan Mawhinney if (i > 0 && count > 0) { 10689ab9b93eae8b2fc747d6101cf0e4c19b2218715fBryan Mawhinney count = current->filter(bundle); 10699ab9b93eae8b2fc747d6101cf0e4c19b2218715fBryan Mawhinney } 1070282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1071282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (count < 0) { 1072282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalCount = count; 1073282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1074282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1075282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalCount += count; 1076282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1077282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else { 1078282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: '%s' is not a directory\n", res); 1079282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1080282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1081282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1082282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1083282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1084282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 1085282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Now do any additional raw files. 1086282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 1087282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int arg=0; arg<N; arg++) { 1088282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* assetDir = bundle->getFileSpecEntry(arg); 1089282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1090282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FileType type = getFileType(assetDir); 1091282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (type == kFileTypeNonexistent) { 1092282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: input directory '%s' does not exist\n", assetDir); 1093282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1094282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1095282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (type != kFileTypeDirectory) { 1096282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: '%s' is not a directory\n", assetDir); 1097282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1098282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1099282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 assetRoot(assetDir); 1101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) 1103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Processing raw dir '%s'\n", (const char*) assetDir); 1104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 1106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Do a recursive traversal of subdir tree. We don't make any 1107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * guarantees about ordering, so we're okay with an inorder search 1108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * using whatever order the OS happens to hand back to us. 1109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 1110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski count = slurpFullTree(bundle, assetRoot, AaptGroupEntry(), String8(), mFullAssetPaths); 1111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (count < 0) { 1112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* failure; report error and remove archive */ 1113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalCount = count; 1114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalCount += count; 1117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) 1119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Found %d asset file%s in %s\n", 1120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski count, (count==1) ? "" : "s", assetDir); 1121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski count = validate(); 1124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (count != NO_ERROR) { 1125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalCount = count; 1126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski count = filter(bundle); 1130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (count != NO_ERROR) { 1131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalCount = count; 1132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 1136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return totalCount; 1137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskissize_t AaptAssets::slurpFullTree(Bundle* bundle, const String8& srcDir, 1140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const AaptGroupEntry& kind, 1141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String8& resType, 1142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<FilePathStore>& fullResPaths) 1143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t res = AaptDir::slurpFullTree(bundle, srcDir, kind, resType, fullResPaths); 1145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (res > 0) { 1146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mGroupEntries.add(kind); 1147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return res; 1150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskissize_t AaptAssets::slurpResourceTree(Bundle* bundle, const String8& srcDir) 1153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t err = 0; 1155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DIR* dir = opendir(srcDir.string()); 1157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (dir == NULL) { 1158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: opendir(%s): %s\n", srcDir.string(), strerror(errno)); 1159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t count = 0; 1163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 1165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Run through the directory, looking for dirs that match the 1166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * expected pattern. 1167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 1168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (1) { 1169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski struct dirent* entry = readdir(dir); 1170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (entry == NULL) { 1171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (isHidden(srcDir.string(), entry->d_name)) { 1175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 subdirName(srcDir); 1179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski subdirName.appendPath(entry->d_name); 1180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AaptGroupEntry group; 1182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 resType; 1183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool b = group.initFromDirName(entry->d_name, &resType); 1184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!b) { 1185fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski fprintf(stderr, "invalid resource directory name: %s %s\n", srcDir.string(), 1186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski entry->d_name); 1187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = -1; 1188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getMaxResVersion() != NULL && group.getVersionString().length() != 0) { 1192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int maxResInt = atoi(bundle->getMaxResVersion()); 1193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char *verString = group.getVersionString().string(); 1194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int dirVersionInt = atoi(verString + 1); // skip 'v' in version name 1195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (dirVersionInt > maxResInt) { 1196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "max res %d, skipping %s\n", maxResInt, entry->d_name); 1197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FileType type = getFileType(subdirName.string()); 1202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (type == kFileTypeDirectory) { 1204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptDir> dir = makeDir(resType); 1205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t res = dir->slurpFullTree(bundle, subdirName, group, 1206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resType, mFullResPaths); 1207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (res < 0) { 1208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski count = res; 1209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (res > 0) { 1212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mGroupEntries.add(group); 1213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski count += res; 1214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Only add this directory if we don't already have a resource dir 1217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // for the current type. This ensures that we only add the dir once 1218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // for all configs. 1219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptDir> rdir = resDir(resType); 1220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (rdir == NULL) { 1221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mResDirs.add(dir); 1222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 1225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, " (ignoring file '%s')\n", subdirName.string()); 1226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 1231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski closedir(dir); 1232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dir = NULL; 1233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != 0) { 1235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 1236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return count; 1238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskissize_t 1241282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiAaptAssets::slurpResourceZip(Bundle* bundle, const char* filename) 1242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int count = 0; 1244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SortedVector<AaptGroupEntry> entries; 1245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipFile* zip = new ZipFile; 1247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = zip->open(filename, ZipFile::kOpenReadOnly); 1248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "error opening zip file %s\n", filename); 1250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski count = err; 1251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete zip; 1252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return -1; 1253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const int N = zip->getNumEntries(); 1256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i=0; i<N; i++) { 1257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipEntry* entry = zip->getEntryByIndex(i); 1258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (entry->getDeleted()) { 1259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 entryName(entry->getFileName()); 1263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 dirName = entryName.getPathDir(); 1265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptDir> dir = dirName == "" ? this : makeDir(dirName); 1266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 resType; 1268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AaptGroupEntry kind; 1269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 remain; 1271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (entryName.walkPath(&remain) == kResourceDir) { 1272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // these are the resources, pull their type out of the directory name 1273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski kind.initFromDirName(remain.walkPath().string(), &resType); 1274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // these are untyped and don't have an AaptGroupEntry 1276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (entries.indexOf(kind) < 0) { 1278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski entries.add(kind); 1279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mGroupEntries.add(kind); 1280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // use the one from the zip file if they both exist. 1283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dir->removeFile(entryName.getPathLeaf()); 1284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> file = new AaptFile(entryName, kind, resType); 1286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = dir->addLeafFile(entryName.getPathLeaf(), file); 1287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "err=%s entryName=%s\n", strerror(err), entryName.string()); 1289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski count = err; 1290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski file->setCompressionMethod(entry->getCompressionMethod()); 1293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#if 0 1295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (entryName == "AndroidManifest.xml") { 1296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("AndroidManifest.xml\n"); 1297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\n\nfile: %s\n", entryName.string()); 1299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 1300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len = entry->getUncompressedLen(); 1302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski void* data = zip->uncompress(entry); 1303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski void* buf = file->editData(len); 1304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memcpy(buf, data, len); 1305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#if 0 1307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const int OFF = 0; 1308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const unsigned char* p = (unsigned char*)data; 1309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const unsigned char* end = p+len; 1310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p += OFF; 1311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i=0; i<32 && p < end; i++) { 1312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("0x%03x ", i*0x10 + OFF); 1313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int j=0; j<0x10 && p < end; j++) { 1314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" %02x", *p); 1315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p++; 1316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\n"); 1318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 1320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski free(data); 1322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski count++; 1324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 1327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete zip; 1328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return count; 1329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AaptAssets::filter(Bundle* bundle) 1332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1333fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski WeakResourceFilter reqFilter; 1334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = reqFilter.parse(bundle->getConfigurations()); 1335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 1337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1339fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski uint32_t preferredDensity = 0; 1340fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (bundle->getPreferredDensity().size() > 0) { 1341fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski ResTable_config preferredConfig; 1342fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (!AaptConfig::parseDensity(bundle->getPreferredDensity().string(), &preferredConfig)) { 1343fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski fprintf(stderr, "Error parsing preferred density: %s\n", 1344fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski bundle->getPreferredDensity().string()); 1345fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return UNKNOWN_ERROR; 1346fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 1347fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski preferredDensity = preferredConfig.density; 1348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1350fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (reqFilter.isEmpty() && preferredDensity == 0) { 1351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 1352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 1355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!reqFilter.isEmpty()) { 1356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Applying required filter: %s\n", 1357fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski bundle->getConfigurations().string()); 1358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1359fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (preferredDensity > 0) { 1360fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski printf("Applying preferred density filter: %s\n", 1361fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski bundle->getPreferredDensity().string()); 1362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<sp<AaptDir> >& resdirs = mResDirs; 1366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t ND = resdirs.size(); 1367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<ND; i++) { 1368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptDir>& dir = resdirs.itemAt(i); 1369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (dir->getLeaf() == kValuesDir) { 1370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // The "value" dir is special since a single file defines 1371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // multiple resources, so we can not do filtering on the 1372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // files themselves. 1373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (dir->getLeaf() == kMipmapDir) { 1376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // We also skip the "mipmap" directory, since the point of this 1377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // is to include all densities without stripping. If you put 1378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // other configurations in here as well they won't be stripped 1379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // either... So don't do that. Seriously. What is wrong with you? 1380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NG = dir->getFiles().size(); 1384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t j=0; j<NG; j++) { 1385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptGroup> grp = dir->getFiles().valueAt(j); 1386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // First remove any configurations we know we don't need. 1388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t k=0; k<grp->getFiles().size(); k++) { 1389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> file = grp->getFiles().valueAt(k); 1390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (k == 0 && grp->getFiles().size() == 1) { 1391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If this is the only file left, we need to keep it. 1392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Otherwise the resource IDs we are using will be inconsistent 1393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // with what we get when not stripping. Sucky, but at least 1394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // for now we can rely on the back-end doing another filtering 1395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass to take this out and leave us with this resource name 1396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // containing no entries. 1397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (file->getPath().getPathExtension() == ".xml") { 1400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // We can't remove .xml files at this point, because when 1401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // we parse them they may add identifier resources, so 1402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // removing them can cause our resource identifiers to 1403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // become inconsistent. 1404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config& config(file->getGroupEntry().toParams()); 1407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!reqFilter.match(config)) { 1408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 1409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Pruning unneeded resource: %s\n", 1410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski file->getPrintableSource().string()); 1411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski grp->removeFile(k); 1413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski k--; 1414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Quick check: no preferred filters, nothing more to do. 1418fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (preferredDensity == 0) { 1419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 14228cf61845187e301dfc4f64b42921977d38766a34Adam Lesinski // Get the preferred density if there is one. We do not match exactly for density. 14238cf61845187e301dfc4f64b42921977d38766a34Adam Lesinski // If our preferred density is hdpi but we only have mdpi and xhdpi resources, we 14248cf61845187e301dfc4f64b42921977d38766a34Adam Lesinski // pick xhdpi. 1425fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski for (size_t k=0; k<grp->getFiles().size(); k++) { 1426fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski sp<AaptFile> file = grp->getFiles().valueAt(k); 1427fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (k == 0 && grp->getFiles().size() == 1) { 1428fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // If this is the only file left, we need to keep it. 1429fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // Otherwise the resource IDs we are using will be inconsistent 1430fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // with what we get when not stripping. Sucky, but at least 1431fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // for now we can rely on the back-end doing another filtering 1432fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // pass to take this out and leave us with this resource name 1433fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // containing no entries. 1434fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski continue; 1435fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 1436fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (file->getPath().getPathExtension() == ".xml") { 1437fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // We can't remove .xml files at this point, because when 1438fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // we parse them they may add identifier resources, so 1439fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // removing them can cause our resource identifiers to 1440fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // become inconsistent. 1441fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski continue; 1442fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 1443fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const ResTable_config& config(file->getGroupEntry().toParams()); 1444fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (config.density != 0 && config.density != preferredDensity) { 1445fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // This is a resource we would prefer not to have. Check 1446fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // to see if have a similar variation that we would like 1447fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // to have and, if so, we can drop it. 1448fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski uint32_t bestDensity = config.density; 1449fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 1450fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski for (size_t m=0; m<grp->getFiles().size(); m++) { 1451fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (m == k) { 1452fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski continue; 1453fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 14548cf61845187e301dfc4f64b42921977d38766a34Adam Lesinski 1455fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski sp<AaptFile> mfile = grp->getFiles().valueAt(m); 1456fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const ResTable_config& mconfig(mfile->getGroupEntry().toParams()); 1457fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (AaptConfig::isSameExcept(config, mconfig, ResTable_config::CONFIG_DENSITY)) { 1458fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // See if there is a better density resource 1459fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (mconfig.density < bestDensity && 1460b0db8de73e6e4151b4e9d1fe3be1f609c3c1fb83Bryan Mawhinney mconfig.density >= preferredDensity && 1461fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski bestDensity > preferredDensity) { 1462b0db8de73e6e4151b4e9d1fe3be1f609c3c1fb83Bryan Mawhinney // This density is our preferred density, or between our best density and 1463fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // the preferred density, therefore it is better. 1464fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski bestDensity = mconfig.density; 1465fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else if (mconfig.density > bestDensity && 1466fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski bestDensity < preferredDensity) { 1467fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // This density is better than our best density and 1468fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // our best density was smaller than our preferred 1469fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // density, so it is better. 1470fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski bestDensity = mconfig.density; 1471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1473fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 14748cf61845187e301dfc4f64b42921977d38766a34Adam Lesinski 1475fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (bestDensity != config.density) { 1476fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (bundle->getVerbose()) { 1477fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski printf("Pruning unneeded resource: %s\n", 1478fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski file->getPrintableSource().string()); 14798cf61845187e301dfc4f64b42921977d38766a34Adam Lesinski } 1480fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski grp->removeFile(k); 1481fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski k--; 1482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 1489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<AaptSymbols> AaptAssets::getSymbolsFor(const String8& name) 1492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> sym = mSymbols.valueFor(name); 1494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (sym == NULL) { 1495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sym = new AaptSymbols(); 1496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mSymbols.add(name, sym); 1497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return sym; 1499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<AaptSymbols> AaptAssets::getJavaSymbolsFor(const String8& name) 1502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> sym = mJavaSymbols.valueFor(name); 1504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (sym == NULL) { 1505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sym = new AaptSymbols(); 1506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mJavaSymbols.add(name, sym); 1507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return sym; 1509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AaptAssets::applyJavaSymbols() 1512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t N = mJavaSymbols.size(); 1514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 1515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String8& name = mJavaSymbols.keyAt(i); 1516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptSymbols>& symbols = mJavaSymbols.valueAt(i); 1517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t pos = mSymbols.indexOfKey(name); 1518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pos < 0) { 1519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos pos; 1520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pos.error("Java symbol dir %s not defined\n", name.string()); 1521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("**** applying java symbols in dir %s\n", name.string()); 1524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = mSymbols.valueAt(pos)->applyJavaSymbols(symbols); 1525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 1527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 1531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool AaptAssets::isJavaSymbol(const AaptSymbolEntry& sym, bool includePrivate) const { 1534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("isJavaSymbol %s: public=%d, includePrivate=%d, isJavaSymbol=%d\n", 1535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // sym.name.string(), sym.isPublic ? 1 : 0, includePrivate ? 1 : 0, 1536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // sym.isJavaSymbol ? 1 : 0); 1537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!mHavePrivateSymbols) return true; 1538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (sym.isPublic) return true; 1539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (includePrivate && sym.isJavaSymbol) return true; 1540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 1541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AaptAssets::buildIncludedResources(Bundle* bundle) 1544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!mHaveIncludedAssets) { 1546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Add in all includes. 1547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<const char*>& incl = bundle->getPackageIncludes(); 1548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N=incl.size(); 1549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 1550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) 1551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Including resources from package: %s\n", incl[i]); 1552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!mIncludedAssets.addAssetPath(String8(incl[i]), NULL)) { 1553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: Asset package include '%s' not found.\n", 1554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski incl[i]); 1555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mHaveIncludedAssets = true; 1559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 1562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AaptAssets::addIncludedResources(const sp<AaptFile>& file) 1565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable& res = getIncludedResources(); 1567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // XXX dirty! 156800b314436f4fdfada4bbf1e79ec12e9fa38aeaf1Narayan Kamath return const_cast<ResTable&>(res).add(file->getData(), file->getSize()); 1569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiconst ResTable& AaptAssets::getIncludedResources() const 1572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mIncludedAssets.getResources(false); 1574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AaptAssets::print(const String8& prefix) const 1577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 innerPrefix(prefix); 1579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski innerPrefix.append(" "); 1580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 innerInnerPrefix(innerPrefix); 1581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski innerInnerPrefix.append(" "); 1582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("%sConfigurations:\n", prefix.string()); 1583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N=mGroupEntries.size(); 1584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 1585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 cname = mGroupEntries.itemAt(i).toDirName(String8()); 1586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("%s %s\n", prefix.string(), 1587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski cname != "" ? cname.string() : "(default)"); 1588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\n%sFiles:\n", prefix.string()); 1591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AaptDir::print(innerPrefix); 1592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\n%sResource Dirs:\n", prefix.string()); 1594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<sp<AaptDir> >& resdirs = mResDirs; 1595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NR = resdirs.size(); 1596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<NR; i++) { 1597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptDir>& d = resdirs.itemAt(i); 1598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("%s Type %s\n", prefix.string(), d->getLeaf().string()); 1599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d->print(innerInnerPrefix); 1600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<AaptDir> AaptAssets::resDir(const String8& name) const 1604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<sp<AaptDir> >& resdirs = mResDirs; 1606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = resdirs.size(); 1607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 1608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptDir>& d = resdirs.itemAt(i); 1609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d->getLeaf() == name) { 1610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return d; 1611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 1614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool 1617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivalid_symbol_name(const String8& symbol) 1618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski static char const * const KEYWORDS[] = { 1620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "abstract", "assert", "boolean", "break", 1621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "byte", "case", "catch", "char", "class", "const", "continue", 1622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "default", "do", "double", "else", "enum", "extends", "final", 1623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "finally", "float", "for", "goto", "if", "implements", "import", 1624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "instanceof", "int", "interface", "long", "native", "new", "package", 1625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "private", "protected", "public", "return", "short", "static", 1626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "strictfp", "super", "switch", "synchronized", "this", "throw", 1627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "throws", "transient", "try", "void", "volatile", "while", 1628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "true", "false", "null", 1629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NULL 1630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski }; 1631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char*const* k = KEYWORDS; 1632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char*const s = symbol.string(); 1633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (*k) { 1634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (0 == strcmp(s, *k)) { 1635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 1636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski k++; 1638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 1640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1641