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* kAssetDir = "assets"; 19282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char* kResourceDir = "res"; 20282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char* kValuesDir = "values"; 21282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char* kMipmapDir = "mipmap"; 22282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char* kInvalidChars = "/\\:"; 23282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const size_t kMaxAssetFileName = 100; 24282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const String8 kResString(kResourceDir); 26282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 27282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 28282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Names of asset files must meet the following criteria: 29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * - the filename length must be less than kMaxAssetFileName bytes long 31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * (and can't be empty) 32282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * - all characters must be 7-bit printable ASCII 33282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * - none of { '/' '\\' ':' } 34282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 35282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Pass in just the filename, not the full path. 36282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 37282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic bool validateFileName(const char* fileName) 38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* cp = fileName; 40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len = 0; 41282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 42282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (*cp != '\0') { 43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((*cp & 0x80) != 0) 44282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; // reject high ASCII 45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (*cp < 0x20 || *cp >= 0x7f) 46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; // reject control chars and 0x7f 47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strchr(kInvalidChars, *cp) != NULL) 48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; // reject path sep chars 49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski cp++; 50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski len++; 51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (len < 1 || len > kMaxAssetFileName) 54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; // reject empty or too long 55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 56282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 57282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 58282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// The default to use if no other ignore pattern is defined. 60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiconst char * const gDefaultIgnoreAssets = 61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"; 62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// The ignore pattern that can be passed via --ignore-assets in Main.cpp 63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiconst char * gUserIgnoreAssets = NULL; 64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic bool isHidden(const char *root, const char *path) 66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Patterns syntax: 68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // - Delimiter is : 69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // - Entry can start with the flag ! to avoid printing a warning 70282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // about the file being ignored. 71282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // - Entry can have the flag "<dir>" to match only directories 72282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // or <file> to match only files. Default is to match both. 73282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // - Entry can be a simplified glob "<prefix>*" or "*<suffix>" 74282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // where prefix/suffix must have at least 1 character (so that 75282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // we don't match a '*' catch-all pattern.) 76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // - The special filenames "." and ".." are always ignored. 77282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // - Otherwise the full string is matched. 78282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // - match is not case-sensitive. 79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp(path, ".") == 0 || strcmp(path, "..") == 0) { 81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char *delim = ":"; 85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char *p = gUserIgnoreAssets; 86282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!p || !p[0]) { 87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p = getenv("ANDROID_AAPT_IGNORE"); 88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!p || !p[0]) { 90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p = gDefaultIgnoreAssets; 91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char *patterns = strdup(p); 93282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 94282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool ignore = false; 95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool chatty = true; 96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char *matchedPattern = NULL; 97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 fullPath(root); 99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fullPath.appendPath(path); 100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FileType type = getFileType(fullPath); 101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int plen = strlen(path); 103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Note: we don't have strtok_r under mingw. 105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for(char *token = strtok(patterns, delim); 106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski !ignore && token != NULL; 107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski token = strtok(NULL, delim)) { 108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski chatty = token[0] != '!'; 109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!chatty) token++; // skip ! 110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strncasecmp(token, "<dir>" , 5) == 0) { 111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (type != kFileTypeDirectory) continue; 112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski token += 5; 113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strncasecmp(token, "<file>", 6) == 0) { 115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (type != kFileTypeRegular) continue; 116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski token += 6; 117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski matchedPattern = token; 120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int n = strlen(token); 121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (token[0] == '*') { 123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Match *suffix 124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski token++; 125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski n--; 126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (n <= plen) { 127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ignore = strncasecmp(token, path + plen - n, n) == 0; 128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (n > 1 && token[n - 1] == '*') { 130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Match prefix* 131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ignore = strncasecmp(token, path, n - 1) == 0; 132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ignore = strcasecmp(token, path) == 0; 134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (ignore && chatty) { 138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, " (skipping %s '%s' due to ANDROID_AAPT_IGNORE pattern '%s')\n", 139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type == kFileTypeDirectory ? "dir" : "file", 140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski path, 141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski matchedPattern ? matchedPattern : ""); 142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski free(patterns); 145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ignore; 146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================= 149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================= 150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================= 151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 15291447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath/* static */ 15391447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamathinline bool isAlpha(const String8& string) { 15491447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath const size_t length = string.length(); 15591447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath for (size_t i = 0; i < length; ++i) { 15691447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath if (!isalpha(string[i])) { 15791447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath return false; 15891447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath } 15991447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath } 16091447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath 16191447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath return true; 16291447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath} 16391447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath 16491447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath/* static */ 16591447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamathinline bool isNumber(const String8& string) { 16691447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath const size_t length = string.length(); 16791447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath for (size_t i = 0; i < length; ++i) { 16891447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath if (!isdigit(string[i])) { 16991447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath return false; 17091447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath } 17191447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath } 17291447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath 17391447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath return true; 17491447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath} 17591447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath 17691447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamathvoid AaptLocaleValue::setLanguage(const char* languageChars) { 17791447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath size_t i = 0; 178b8dc7bc582ee4acd9d6c1379701a002c5ddbe323Andreas Gampe while ((*languageChars) != '\0' && i < sizeof(language)/sizeof(language[0])) { 17991447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath language[i++] = tolower(*languageChars); 18091447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath languageChars++; 18191447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath } 18291447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath} 18391447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath 18491447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamathvoid AaptLocaleValue::setRegion(const char* regionChars) { 18591447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath size_t i = 0; 186b8dc7bc582ee4acd9d6c1379701a002c5ddbe323Andreas Gampe while ((*regionChars) != '\0' && i < sizeof(region)/sizeof(region[0])) { 18791447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath region[i++] = toupper(*regionChars); 18891447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath regionChars++; 18991447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath } 19091447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath} 19191447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath 19291447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamathvoid AaptLocaleValue::setScript(const char* scriptChars) { 19391447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath size_t i = 0; 194b8dc7bc582ee4acd9d6c1379701a002c5ddbe323Andreas Gampe while ((*scriptChars) != '\0' && i < sizeof(script)/sizeof(script[0])) { 19591447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath if (i == 0) { 19691447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath script[i++] = toupper(*scriptChars); 19791447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath } else { 19891447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath script[i++] = tolower(*scriptChars); 19991447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath } 20091447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath scriptChars++; 20191447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath } 20291447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath} 20391447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath 20491447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamathvoid AaptLocaleValue::setVariant(const char* variantChars) { 20591447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath size_t i = 0; 206b8dc7bc582ee4acd9d6c1379701a002c5ddbe323Andreas Gampe while ((*variantChars) != '\0' && i < sizeof(variant)/sizeof(variant[0])) { 20791447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath variant[i++] = *variantChars; 20891447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath variantChars++; 20991447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath } 21091447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath} 21191447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath 21291447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamathbool AaptLocaleValue::initFromFilterString(const String8& str) { 21391447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath // A locale (as specified in the filter) is an underscore separated name such 21491447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath // as "en_US", "en_Latn_US", or "en_US_POSIX". 215fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski Vector<String8> parts = AaptUtil::splitAndLowerCase(str, '_'); 21691447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath 21791447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath const int numTags = parts.size(); 21891447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath bool valid = false; 21991447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath if (numTags >= 1) { 22091447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath const String8& lang = parts[0]; 22191447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath if (isAlpha(lang) && (lang.length() == 2 || lang.length() == 3)) { 22291447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath setLanguage(lang.string()); 22391447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath valid = true; 22491447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath } 22591447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath } 22691447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath 22791447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath if (!valid || numTags == 1) { 228fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return valid; 229fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 231fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // At this point, valid == true && numTags > 1. 232fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const String8& part2 = parts[1]; 233fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if ((part2.length() == 2 && isAlpha(part2)) || 234fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski (part2.length() == 3 && isNumber(part2))) { 235fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setRegion(part2.string()); 236fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else if (part2.length() == 4 && isAlpha(part2)) { 237fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setScript(part2.string()); 238b927c559e1ef8530b08712507f320502627db298Roozbeh Pournader } else if (part2.length() >= 4 && part2.length() <= 8) { 239fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setVariant(part2.string()); 240fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else { 241fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski valid = false; 242fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 244fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (!valid || numTags == 2) { 245fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return valid; 246fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 248fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // At this point, valid == true && numTags > 1. 249fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const String8& part3 = parts[2]; 250fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (((part3.length() == 2 && isAlpha(part3)) || 251fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski (part3.length() == 3 && isNumber(part3))) && script[0]) { 252fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setRegion(part3.string()); 253b927c559e1ef8530b08712507f320502627db298Roozbeh Pournader } else if (part3.length() >= 4 && part3.length() <= 8) { 254fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setVariant(part3.string()); 255fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else { 256fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski valid = false; 257fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 259fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (!valid || numTags == 3) { 260fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return valid; 261fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 263fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const String8& part4 = parts[3]; 264b927c559e1ef8530b08712507f320502627db298Roozbeh Pournader if (part4.length() >= 4 && part4.length() <= 8) { 265fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setVariant(part4.string()); 266fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else { 267fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski valid = false; 268fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 270fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (!valid || numTags > 4) { 271fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return false; 272fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 274fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return true; 275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 277fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskiint AaptLocaleValue::initFromDirName(const Vector<String8>& parts, const int startIndex) { 278fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const int size = parts.size(); 279fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski int currentIndex = startIndex; 280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 281fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski String8 part = parts[currentIndex]; 282fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (part[0] == 'b' && part[1] == '+') { 283b927c559e1ef8530b08712507f320502627db298Roozbeh Pournader // This is a "modified" BCP 47 language tag. Same semantics as BCP 47 tags, 284fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // except that the separator is "+" and not "-". 285fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski Vector<String8> subtags = AaptUtil::splitAndLowerCase(part, '+'); 286fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski subtags.removeItemsAt(0); 287fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (subtags.size() == 1) { 288fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setLanguage(subtags[0]); 289fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else if (subtags.size() == 2) { 290fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setLanguage(subtags[0]); 291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 292fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // The second tag can either be a region, a variant or a script. 293fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski switch (subtags[1].size()) { 294fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski case 2: 295fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski case 3: 296fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setRegion(subtags[1]); 297fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski break; 298fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski case 4: 299b927c559e1ef8530b08712507f320502627db298Roozbeh Pournader if (isAlpha(subtags[1])) { 300b927c559e1ef8530b08712507f320502627db298Roozbeh Pournader setScript(subtags[1]); 301b927c559e1ef8530b08712507f320502627db298Roozbeh Pournader break; 302b927c559e1ef8530b08712507f320502627db298Roozbeh Pournader } 303b927c559e1ef8530b08712507f320502627db298Roozbeh Pournader // This is not alphabetical, so we fall through to variant 304fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski case 5: 305fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski case 6: 306fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski case 7: 307fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski case 8: 308fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setVariant(subtags[1]); 309fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski break; 310fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski default: 311b927c559e1ef8530b08712507f320502627db298Roozbeh Pournader fprintf(stderr, "ERROR: Invalid BCP 47 tag in directory name %s\n", 312fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski part.string()); 313fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return -1; 314fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 315fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else if (subtags.size() == 3) { 316fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // The language is always the first subtag. 317fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setLanguage(subtags[0]); 318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 319fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // The second subtag can either be a script or a region code. 320fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // If its size is 4, it's a script code, else it's a region code. 321fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski bool hasRegion = false; 322fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (subtags[1].size() == 4) { 323fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setScript(subtags[1]); 324fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else if (subtags[1].size() == 2 || subtags[1].size() == 3) { 325fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setRegion(subtags[1]); 326fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski hasRegion = true; 327fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else { 328b927c559e1ef8530b08712507f320502627db298Roozbeh Pournader fprintf(stderr, "ERROR: Invalid BCP 47 tag in directory name %s\n", part.string()); 329fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return -1; 330fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 332fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // The third tag can either be a region code (if the second tag was 333fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // a script), else a variant code. 334b927c559e1ef8530b08712507f320502627db298Roozbeh Pournader if (subtags[2].size() >= 4) { 335fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setVariant(subtags[2]); 336fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else { 337fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setRegion(subtags[2]); 338fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 339fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else if (subtags.size() == 4) { 340fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setLanguage(subtags[0]); 341fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setScript(subtags[1]); 342fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setRegion(subtags[2]); 343fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setVariant(subtags[3]); 344fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else { 345b927c559e1ef8530b08712507f320502627db298Roozbeh Pournader fprintf(stderr, "ERROR: Invalid BCP 47 tag in directory name: %s\n", part.string()); 346fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return -1; 347fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 349fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return ++currentIndex; 350fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else { 3517f1a8957cca420d525719836069b7f6d5ee04718Narayan Kamath if ((part.length() == 2 || part.length() == 3) 3527f1a8957cca420d525719836069b7f6d5ee04718Narayan Kamath && isAlpha(part) && strcmp("car", part.string())) { 353fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setLanguage(part); 354fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (++currentIndex == size) { 355fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return size; 356fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 357fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else { 358fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return currentIndex; 359fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 361fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski part = parts[currentIndex]; 362fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (part.string()[0] == 'r' && part.length() == 3) { 363fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski setRegion(part.string() + 1); 364fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (++currentIndex == size) { 365fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return size; 366fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 370fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return currentIndex; 371fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski} 372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 373fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskivoid AaptLocaleValue::initFromResTable(const ResTable_config& config) { 374fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski config.unpackLanguage(language); 375fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski config.unpackRegion(region); 3767960898f6f886aadda1dd3d7a89106dde9f44217Roozbeh Pournader if (config.localeScript[0] && !config.localeScriptWasComputed) { 377fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski memcpy(script, config.localeScript, sizeof(config.localeScript)); 378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 380fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (config.localeVariant[0]) { 381fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski memcpy(variant, config.localeVariant, sizeof(config.localeVariant)); 382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 385fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskivoid AaptLocaleValue::writeTo(ResTable_config* out) const { 386fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski out->packLanguage(language); 387fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski out->packRegion(region); 388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 389fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (script[0]) { 390fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski memcpy(out->localeScript, script, sizeof(out->localeScript)); 391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 393fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (variant[0]) { 394fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski memcpy(out->localeVariant, variant, sizeof(out->localeVariant)); 395fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 398fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool 399fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam LesinskiAaptGroupEntry::initFromDirName(const char* dir, String8* resType) 400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 401fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const char* q = strchr(dir, '-'); 402fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski size_t typeLen; 403fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (q != NULL) { 404fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski typeLen = q - dir; 405fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else { 406fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski typeLen = strlen(dir); 407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 409fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski String8 type(dir, typeLen); 410fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (!isValidResourceType(type)) { 411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 414fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (q != NULL) { 415fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (!AaptConfig::parse(String8(q + 1), &mParams)) { 416fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return false; 417fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 420fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski *resType = type; 421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 424fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam LesinskiString8 425fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam LesinskiAaptGroupEntry::toDirName(const String8& resType) const 426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 427fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski String8 s = resType; 428fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski String8 params = mParams.toString(); 429fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (params.length() > 0) { 430fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (s.length() > 0) { 431fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski s += "-"; 432fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 433fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski s += params; 434fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 435fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return s; 436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================= 440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================= 441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================= 442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid* AaptFile::editData(size_t size) 444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (size <= mBufferSize) { 446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDataSize = size; 447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mData; 448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t allocSize = (size*3)/2; 450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski void* buf = realloc(mData, allocSize); 451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (buf == NULL) { 452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mData = buf; 455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDataSize = size; 456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mBufferSize = allocSize; 457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return buf; 458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 460de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinskivoid* AaptFile::editDataInRange(size_t offset, size_t size) 461de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski{ 462de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski return (void*)(((uint8_t*) editData(offset + size)) + offset); 463de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski} 464de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid* AaptFile::editData(size_t* outSize) 466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outSize) { 468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outSize = mDataSize; 469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mData; 471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid* AaptFile::padData(size_t wordSize) 474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t extra = mDataSize%wordSize; 476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (extra == 0) { 477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mData; 478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t initial = mDataSize; 481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski void* data = editData(initial+(wordSize-extra)); 482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (data != NULL) { 483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memset(((uint8_t*)data) + initial, 0, wordSize-extra); 484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return data; 486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AaptFile::writeData(const void* data, size_t size) 489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t end = mDataSize; 491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t total = size + end; 492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski void* buf = editData(total); 493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (buf == NULL) { 494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memcpy(((char*)buf)+end, data, size); 497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AaptFile::clearData() 501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mData != NULL) free(mData); 503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mData = NULL; 504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDataSize = 0; 505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mBufferSize = 0; 506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 508282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiString8 AaptFile::getPrintableSource() const 509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasData()) { 511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name(mGroupEntry.toDirName(String8())); 512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name.appendPath(mPath); 513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name.append(" #generated"); 514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return name; 515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mSourceFile; 517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================= 520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================= 521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================= 522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 52309384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinskistatus_t AaptGroup::addFile(const sp<AaptFile>& file, const bool overwriteDuplicate) 524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 52509384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski ssize_t index = mFiles.indexOfKey(file->getGroupEntry()); 52609384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski if (index >= 0 && overwriteDuplicate) { 52709384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski fprintf(stderr, "warning: overwriting '%s' with '%s'\n", 52809384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski mFiles[index]->getSourceFile().string(), 52909384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski file->getSourceFile().string()); 53009384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski removeFile(index); 53109384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski index = -1; 53209384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski } 53309384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski 53409384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski if (index < 0) { 535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski file->mPath = mPath; 536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mFiles.add(file->getGroupEntry(), file); 537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 54048f05d29f398576c76b2c3b47a22f4e44e8919fcAdam Lesinski // Check if the version is automatically applied. This is a common source of 54148f05d29f398576c76b2c3b47a22f4e44e8919fcAdam Lesinski // error. 54248f05d29f398576c76b2c3b47a22f4e44e8919fcAdam Lesinski ConfigDescription withoutVersion = file->getGroupEntry().toParams(); 54348f05d29f398576c76b2c3b47a22f4e44e8919fcAdam Lesinski withoutVersion.version = 0; 54448f05d29f398576c76b2c3b47a22f4e44e8919fcAdam Lesinski AaptConfig::applyVersionForCompatibility(&withoutVersion); 54548f05d29f398576c76b2c3b47a22f4e44e8919fcAdam Lesinski 54648f05d29f398576c76b2c3b47a22f4e44e8919fcAdam Lesinski const sp<AaptFile>& originalFile = mFiles.valueAt(index); 54748f05d29f398576c76b2c3b47a22f4e44e8919fcAdam Lesinski SourcePos(file->getSourceFile(), -1) 54848f05d29f398576c76b2c3b47a22f4e44e8919fcAdam Lesinski .error("Duplicate file.\n%s: Original is here. %s", 54948f05d29f398576c76b2c3b47a22f4e44e8919fcAdam Lesinski originalFile->getPrintableSource().string(), 55048f05d29f398576c76b2c3b47a22f4e44e8919fcAdam Lesinski (withoutVersion.version != 0) ? "The version qualifier may be implied." : ""); 551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AaptGroup::removeFile(size_t index) 555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mFiles.removeItemsAt(index); 557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AaptGroup::print(const String8& prefix) const 560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("%s%s\n", prefix.string(), getPath().string()); 562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N=mFiles.size(); 563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> file = mFiles.valueAt(i); 566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const AaptGroupEntry& e = file->getGroupEntry(); 567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (file->hasData()) { 568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("%s Gen: (%s) %d bytes\n", prefix.string(), e.toDirName(String8()).string(), 569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (int)file->getSize()); 570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("%s Src: (%s) %s\n", prefix.string(), e.toDirName(String8()).string(), 572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski file->getPrintableSource().string()); 573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("%s File Group Entry: %s\n", prefix.string(), 575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // file->getGroupEntry().toDirName(String8()).string()); 576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 579282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiString8 AaptGroup::getPrintableSource() const 580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mFiles.size() > 0) { 582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Arbitrarily pull the first source file out of the list. 583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mFiles.valueAt(0)->getPrintableSource(); 584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Should never hit this case, but to be safe... 587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return getPath(); 588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================= 592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================= 593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================= 594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AaptDir::addFile(const String8& name, const sp<AaptGroup>& file) 596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mFiles.indexOfKey(name) >= 0) { 598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ALREADY_EXISTS; 599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mFiles.add(name, file); 601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AaptDir::addDir(const String8& name, const sp<AaptDir>& dir) 605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mDirs.indexOfKey(name) >= 0) { 607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ALREADY_EXISTS; 608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDirs.add(name, dir); 610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<AaptDir> AaptDir::makeDir(const String8& path) 614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name; 616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 remain = path; 617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptDir> subdir = this; 619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (name = remain.walkPath(&remain), remain != "") { 620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski subdir = subdir->makeDir(name); 621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t i = subdir->mDirs.indexOfKey(name); 624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (i >= 0) { 625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return subdir->mDirs.valueAt(i); 626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptDir> dir = new AaptDir(name, subdir->mPath.appendPathCopy(name)); 628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski subdir->mDirs.add(name, dir); 629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return dir; 630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AaptDir::removeFile(const String8& name) 633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mFiles.removeItem(name); 635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AaptDir::removeDir(const String8& name) 638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDirs.removeItem(name); 640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 64209384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinskistatus_t AaptDir::addLeafFile(const String8& leafName, const sp<AaptFile>& file, 64309384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski const bool overwrite) 644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptGroup> group; 646282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mFiles.indexOfKey(leafName) >= 0) { 647282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski group = mFiles.valueFor(leafName); 648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 649282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski group = new AaptGroup(leafName, mPath.appendPathCopy(leafName)); 650282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mFiles.add(leafName, group); 651282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 65309384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski return group->addFile(file, overwrite); 654282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 655282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 656282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskissize_t AaptDir::slurpFullTree(Bundle* bundle, const String8& srcDir, 657282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const AaptGroupEntry& kind, const String8& resType, 65809384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski sp<FilePathStore>& fullResPaths, const bool overwrite) 659282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 660282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<String8> fileNames; 661282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 662282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DIR* dir = NULL; 663282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 664282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dir = opendir(srcDir.string()); 665282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (dir == NULL) { 666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: opendir(%s): %s\n", srcDir.string(), strerror(errno)); 667282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 668282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 669282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Slurp the filenames out of the directory. 672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 673282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (1) { 674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski struct dirent* entry; 675282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski entry = readdir(dir); 677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (entry == NULL) 678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (isHidden(srcDir.string(), entry->d_name)) 681282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 name(entry->d_name); 684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fileNames.add(name); 685282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Add fully qualified path for dependency purposes 686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // if we're collecting them 687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (fullResPaths != NULL) { 688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fullResPaths->add(srcDir.appendPathCopy(name)); 689282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski closedir(dir); 692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 693282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 694282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t count = 0; 695282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 696282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 697282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Stash away the files and recursively descend into subdirectories. 698282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 699282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = fileNames.size(); 700282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 701282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i = 0; i < N; i++) { 702282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 pathName(srcDir); 703282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FileType type; 704282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 705282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pathName.appendPath(fileNames[i].string()); 706282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type = getFileType(pathName.string()); 707282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (type == kFileTypeDirectory) { 708282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptDir> subdir; 709282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool notAdded = false; 710282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mDirs.indexOfKey(fileNames[i]) >= 0) { 711282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski subdir = mDirs.valueFor(fileNames[i]); 712282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski subdir = new AaptDir(fileNames[i], mPath.appendPathCopy(fileNames[i])); 714282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski notAdded = true; 715282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 716282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t res = subdir->slurpFullTree(bundle, pathName, kind, 71709384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski resType, fullResPaths, overwrite); 718282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (res < NO_ERROR) { 719282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return res; 720282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 721282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (res > 0 && notAdded) { 722282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDirs.add(fileNames[i], subdir); 723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 724282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski count += res; 725282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (type == kFileTypeRegular) { 726282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> file = new AaptFile(pathName, kind, resType); 72709384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski status_t err = addLeafFile(fileNames[i], file, overwrite); 728282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 729282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 730282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 731282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 732282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski count++; 733282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 734282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 735282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) 736282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" (ignoring non-file/dir '%s')\n", pathName.string()); 737282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 738282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 739282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 740282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return count; 741282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 742282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 743282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AaptDir::validate() const 744282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 745282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NF = mFiles.size(); 746282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t ND = mDirs.size(); 747282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 748282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i = 0; i < NF; i++) { 749282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!validateFileName(mFiles.valueAt(i)->getLeaf().string())) { 750282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(mFiles.valueAt(i)->getPrintableSource(), -1).error( 751282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Invalid filename. Unable to add."); 752282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 753282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 754282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 755282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t j; 756282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (j = i+1; j < NF; j++) { 757282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcasecmp(mFiles.valueAt(i)->getLeaf().string(), 758282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mFiles.valueAt(j)->getLeaf().string()) == 0) { 759282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(mFiles.valueAt(i)->getPrintableSource(), -1).error( 760282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "File is case-insensitive equivalent to: %s", 761282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mFiles.valueAt(j)->getPrintableSource().string()); 762282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 763282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 764282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 765282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // TODO: if ".gz", check for non-.gz; if non-, check for ".gz" 766282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // (this is mostly caught by the "marked" stuff, below) 767282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 768282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 769282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (j = 0; j < ND; j++) { 770282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcasecmp(mFiles.valueAt(i)->getLeaf().string(), 771282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDirs.valueAt(j)->getLeaf().string()) == 0) { 772282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(mFiles.valueAt(i)->getPrintableSource(), -1).error( 773282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "File conflicts with dir from: %s", 774282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDirs.valueAt(j)->getPrintableSource().string()); 775282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 776282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 777282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 778282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 779282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 780282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i = 0; i < ND; i++) { 781282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!validateFileName(mDirs.valueAt(i)->getLeaf().string())) { 782282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(mDirs.valueAt(i)->getPrintableSource(), -1).error( 783282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Invalid directory name, unable to add."); 784282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 785282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 786282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 787282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t j; 788282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (j = i+1; j < ND; j++) { 789282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcasecmp(mDirs.valueAt(i)->getLeaf().string(), 790282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDirs.valueAt(j)->getLeaf().string()) == 0) { 791282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(mDirs.valueAt(i)->getPrintableSource(), -1).error( 792282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Directory is case-insensitive equivalent to: %s", 793282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDirs.valueAt(j)->getPrintableSource().string()); 794282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 795282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 796282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 797282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 798282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = mDirs.valueAt(i)->validate(); 799282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 800282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 801282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 802282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 803282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 804282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 805282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 806282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 807282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AaptDir::print(const String8& prefix) const 808282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 809282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t ND=getDirs().size(); 810282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 811282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<ND; i++) { 812282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getDirs().valueAt(i)->print(prefix); 813282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 814282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 815282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NF=getFiles().size(); 816282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<NF; i++) { 817282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getFiles().valueAt(i)->print(prefix); 818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 820282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 821282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiString8 AaptDir::getPrintableSource() const 822282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 823282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mFiles.size() > 0) { 824282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Arbitrarily pull the first file out of the list as the source dir. 825282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mFiles.valueAt(0)->getPrintableSource().getPathDir(); 826282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 827282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mDirs.size() > 0) { 828282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Or arbitrarily pull the first dir out of the list as the source dir. 829282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mDirs.valueAt(0)->getPrintableSource().getPathDir(); 830282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 831282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 832282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Should never hit this case, but to be safe... 833282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mPath; 834282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 835282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 836282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 837282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================= 838282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================= 839282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================= 840282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 841282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AaptSymbols::applyJavaSymbols(const sp<AaptSymbols>& javaSymbols) 842282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 843282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = NO_ERROR; 844282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t N = javaSymbols->mSymbols.size(); 845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String8& name = javaSymbols->mSymbols.keyAt(i); 847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const AaptSymbolEntry& entry = javaSymbols->mSymbols.valueAt(i); 848282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t pos = mSymbols.indexOfKey(name); 849282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pos < 0) { 850282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski entry.sourcePos.error("Symbol '%s' declared with <java-symbol> not defined\n", name.string()); 851282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = UNKNOWN_ERROR; 852282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 853282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 854282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("**** setting symbol #%d/%d %s to isJavaSymbol=%d\n", 855282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // i, N, name.string(), entry.isJavaSymbol ? 1 : 0); 856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mSymbols.editValueAt(pos).isJavaSymbol = entry.isJavaSymbol; 857282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 858282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 859282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski N = javaSymbols->mNestedSymbols.size(); 860282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 861282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String8& name = javaSymbols->mNestedSymbols.keyAt(i); 862282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptSymbols>& symbols = javaSymbols->mNestedSymbols.valueAt(i); 863282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t pos = mNestedSymbols.indexOfKey(name); 864282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pos < 0) { 865282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos pos; 866282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pos.error("Java symbol dir %s not defined\n", name.string()); 867282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = UNKNOWN_ERROR; 868282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 869282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 870282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("**** applying java symbols in dir %s\n", name.string()); 871282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t myerr = mNestedSymbols.valueAt(pos)->applyJavaSymbols(symbols); 872282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (myerr != NO_ERROR) { 873282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = myerr; 874282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 875282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 876282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 877282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 878282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 879282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 880282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================= 881282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================= 882282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ========================================================================= 883282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 884282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiAaptAssets::AaptAssets() 885282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski : AaptDir(String8(), String8()), 88691447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath mHavePrivateSymbols(false), 88791447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath mChanged(false), mHaveIncludedAssets(false), 888fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski mRes(NULL) {} 889282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 890282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiconst SortedVector<AaptGroupEntry>& AaptAssets::getGroupEntries() const { 891282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mChanged) { 892282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 893282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mGroupEntries; 894282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 895282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 896282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AaptAssets::addFile(const String8& name, const sp<AaptGroup>& file) 897282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 898282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mChanged = true; 899282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return AaptDir::addFile(name, file); 900282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 901282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 902282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<AaptFile> AaptAssets::addFile( 903282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String8& filePath, const AaptGroupEntry& entry, 904282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String8& srcDir, sp<AaptGroup>* outGroup, 905282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String8& resType) 906282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 907282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptDir> dir = this; 908282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptGroup> group; 909282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> file; 910282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 root, remain(filePath), partialPath; 911282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (remain.length() > 0) { 912282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski root = remain.walkPath(&remain); 913282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski partialPath.appendPath(root); 914282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 915282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String8 rootStr(root); 916282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 917282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (remain.length() == 0) { 918282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t i = dir->getFiles().indexOfKey(rootStr); 919282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (i >= 0) { 920282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski group = dir->getFiles().valueAt(i); 921282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 922282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski group = new AaptGroup(rootStr, filePath); 923282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t res = dir->addFile(rootStr, group); 924282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (res != NO_ERROR) { 925282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 926282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 927282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 928282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski file = new AaptFile(srcDir.appendPathCopy(filePath), entry, resType); 929282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t res = group->addFile(file); 930282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (res != NO_ERROR) { 931282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 932282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 933282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 934282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 935282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 936282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t i = dir->getDirs().indexOfKey(rootStr); 937282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (i >= 0) { 938282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dir = dir->getDirs().valueAt(i); 939282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 940282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptDir> subdir = new AaptDir(rootStr, partialPath); 941282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t res = dir->addDir(rootStr, subdir); 942282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (res != NO_ERROR) { 943282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 944282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 945282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dir = subdir; 946282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 947282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 948282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 949282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 950282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mGroupEntries.add(entry); 951282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outGroup) *outGroup = group; 952282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return file; 953282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 954282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 955282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AaptAssets::addResource(const String8& leafName, const String8& path, 956282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptFile>& file, const String8& resType) 957282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 958282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptDir> res = AaptDir::makeDir(kResString); 959282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 dirname = file->getGroupEntry().toDirName(resType); 960282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptDir> subdir = res->makeDir(dirname); 961282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptGroup> grr = new AaptGroup(leafName, path); 962282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski grr->addFile(file); 963282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 964282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski subdir->addFile(leafName, grr); 965282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 966282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 9678c2df71739808d6f1aec4277fb47c191e7031164Guang Zhu 968282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskissize_t AaptAssets::slurpFromArgs(Bundle* bundle) 969282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 970282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int count; 971282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int totalCount = 0; 972282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FileType type; 973282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<const char *>& resDirs = bundle->getResourceSourceDirs(); 974282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t dirCount =resDirs.size(); 975282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptAssets> current = this; 976282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 977282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const int N = bundle->getFileSpecCount(); 978282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 979282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 980282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * If a package manifest was specified, include that first. 981282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 982282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getAndroidManifestFile() != NULL) { 983282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // place at root of zip. 984282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 srcFile(bundle->getAndroidManifestFile()); 985282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski addFile(srcFile.getPathLeaf(), AaptGroupEntry(), srcFile.getPathDir(), 986282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NULL, String8()); 987282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalCount++; 988282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 989282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 990282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 991282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * If a directory of custom assets was supplied, slurp 'em up. 992282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 99309384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski const Vector<const char*>& assetDirs = bundle->getAssetSourceDirs(); 99409384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski const int AN = assetDirs.size(); 99509384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski for (int i = 0; i < AN; i++) { 99609384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski FileType type = getFileType(assetDirs[i]); 997282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (type == kFileTypeNonexistent) { 99809384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski fprintf(stderr, "ERROR: asset directory '%s' does not exist\n", assetDirs[i]); 999282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1000282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1001282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (type != kFileTypeDirectory) { 100209384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski fprintf(stderr, "ERROR: '%s' is not a directory\n", assetDirs[i]); 1003282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1004282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1005282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 100609384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski String8 assetRoot(assetDirs[i]); 1007282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptDir> assetAaptDir = makeDir(String8(kAssetDir)); 1008282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AaptGroupEntry group; 1009282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski count = assetAaptDir->slurpFullTree(bundle, assetRoot, group, 101009384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski String8(), mFullAssetPaths, true); 1011282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (count < 0) { 1012282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalCount = count; 1013282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1014282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1015282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (count > 0) { 1016282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mGroupEntries.add(group); 1017282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1018282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalCount += count; 1019282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 102009384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski if (bundle->getVerbose()) { 1021282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Found %d custom asset file%s in %s\n", 102209384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski count, (count==1) ? "" : "s", assetDirs[i]); 102309384303dea4f3f01d5682918d7bab9bf83a02b1Adam Lesinski } 1024282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1025282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1026282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 1027282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * If a directory of resource-specific assets was supplied, slurp 'em up. 1028282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 1029282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<dirCount; i++) { 1030282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char *res = resDirs[i]; 1031282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (res) { 1032282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type = getFileType(res); 1033282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (type == kFileTypeNonexistent) { 1034282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: resource directory '%s' does not exist\n", res); 1035282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1036282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1037282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (type == kFileTypeDirectory) { 1038282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (i>0) { 1039282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptAssets> nextOverlay = new AaptAssets(); 1040282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski current->setOverlay(nextOverlay); 1041282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski current = nextOverlay; 1042282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski current->setFullResPaths(mFullResPaths); 1043282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1044282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski count = current->slurpResourceTree(bundle, String8(res)); 10459ab9b93eae8b2fc747d6101cf0e4c19b2218715fBryan Mawhinney if (i > 0 && count > 0) { 10469ab9b93eae8b2fc747d6101cf0e4c19b2218715fBryan Mawhinney count = current->filter(bundle); 10479ab9b93eae8b2fc747d6101cf0e4c19b2218715fBryan Mawhinney } 1048282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1049282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (count < 0) { 1050282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalCount = count; 1051282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1052282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1053282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalCount += count; 1054282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1055282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else { 1056282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: '%s' is not a directory\n", res); 1057282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1058282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1059282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1060282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1061282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1062282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 1063282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Now do any additional raw files. 1064282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 1065282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int arg=0; arg<N; arg++) { 1066282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* assetDir = bundle->getFileSpecEntry(arg); 1067282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1068282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FileType type = getFileType(assetDir); 1069282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (type == kFileTypeNonexistent) { 1070282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: input directory '%s' does not exist\n", assetDir); 1071282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1072282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1073282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (type != kFileTypeDirectory) { 1074282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: '%s' is not a directory\n", assetDir); 1075282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1076282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1077282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1078282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 assetRoot(assetDir); 1079282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1080282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) 1081282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Processing raw dir '%s'\n", (const char*) assetDir); 1082282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1083282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 1084282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Do a recursive traversal of subdir tree. We don't make any 1085282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * guarantees about ordering, so we're okay with an inorder search 1086282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * using whatever order the OS happens to hand back to us. 1087282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 1088282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski count = slurpFullTree(bundle, assetRoot, AaptGroupEntry(), String8(), mFullAssetPaths); 1089282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (count < 0) { 1090282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* failure; report error and remove archive */ 1091282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalCount = count; 1092282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1093282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1094282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalCount += count; 1095282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1096282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) 1097282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Found %d asset file%s in %s\n", 1098282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski count, (count==1) ? "" : "s", assetDir); 1099282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski count = validate(); 1102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (count != NO_ERROR) { 1103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalCount = count; 1104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski count = filter(bundle); 1108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (count != NO_ERROR) { 1109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski totalCount = count; 1110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 1114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return totalCount; 1115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskissize_t AaptAssets::slurpFullTree(Bundle* bundle, const String8& srcDir, 1118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const AaptGroupEntry& kind, 1119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String8& resType, 112040e8eefbedcafc51948945647d746daaee092f16Adam Lesinski sp<FilePathStore>& fullResPaths, 112140e8eefbedcafc51948945647d746daaee092f16Adam Lesinski const bool overwrite) 1122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 112340e8eefbedcafc51948945647d746daaee092f16Adam Lesinski ssize_t res = AaptDir::slurpFullTree(bundle, srcDir, kind, resType, fullResPaths, overwrite); 1124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (res > 0) { 1125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mGroupEntries.add(kind); 1126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return res; 1129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskissize_t AaptAssets::slurpResourceTree(Bundle* bundle, const String8& srcDir) 1132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t err = 0; 1134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DIR* dir = opendir(srcDir.string()); 1136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (dir == NULL) { 1137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: opendir(%s): %s\n", srcDir.string(), strerror(errno)); 1138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t count = 0; 1142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 1144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Run through the directory, looking for dirs that match the 1145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * expected pattern. 1146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 1147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (1) { 1148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski struct dirent* entry = readdir(dir); 1149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (entry == NULL) { 1150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (isHidden(srcDir.string(), entry->d_name)) { 1154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 subdirName(srcDir); 1158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski subdirName.appendPath(entry->d_name); 1159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AaptGroupEntry group; 1161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 resType; 1162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool b = group.initFromDirName(entry->d_name, &resType); 1163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!b) { 1164fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski fprintf(stderr, "invalid resource directory name: %s %s\n", srcDir.string(), 1165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski entry->d_name); 1166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = -1; 1167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getMaxResVersion() != NULL && group.getVersionString().length() != 0) { 1171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int maxResInt = atoi(bundle->getMaxResVersion()); 1172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char *verString = group.getVersionString().string(); 1173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int dirVersionInt = atoi(verString + 1); // skip 'v' in version name 1174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (dirVersionInt > maxResInt) { 1175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "max res %d, skipping %s\n", maxResInt, entry->d_name); 1176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FileType type = getFileType(subdirName.string()); 1181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (type == kFileTypeDirectory) { 1183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptDir> dir = makeDir(resType); 1184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t res = dir->slurpFullTree(bundle, subdirName, group, 1185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resType, mFullResPaths); 1186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (res < 0) { 1187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski count = res; 1188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (res > 0) { 1191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mGroupEntries.add(group); 1192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski count += res; 1193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Only add this directory if we don't already have a resource dir 1196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // for the current type. This ensures that we only add the dir once 1197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // for all configs. 1198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptDir> rdir = resDir(resType); 1199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (rdir == NULL) { 1200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mResDirs.add(dir); 1201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 1204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, " (ignoring file '%s')\n", subdirName.string()); 1205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 1210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski closedir(dir); 1211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dir = NULL; 1212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != 0) { 1214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 1215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return count; 1217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskissize_t 12202412f84064c26b643c722ce914a97c4ec7776c69Andreas GampeAaptAssets::slurpResourceZip(Bundle* /* bundle */, const char* filename) 1221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int count = 0; 1223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SortedVector<AaptGroupEntry> entries; 1224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipFile* zip = new ZipFile; 1226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = zip->open(filename, ZipFile::kOpenReadOnly); 1227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "error opening zip file %s\n", filename); 1229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski count = err; 1230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete zip; 1231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return -1; 1232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const int N = zip->getNumEntries(); 1235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i=0; i<N; i++) { 1236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipEntry* entry = zip->getEntryByIndex(i); 1237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (entry->getDeleted()) { 1238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 entryName(entry->getFileName()); 1242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 dirName = entryName.getPathDir(); 1244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptDir> dir = dirName == "" ? this : makeDir(dirName); 1245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 resType; 1247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AaptGroupEntry kind; 1248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 remain; 1250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (entryName.walkPath(&remain) == kResourceDir) { 1251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // these are the resources, pull their type out of the directory name 1252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski kind.initFromDirName(remain.walkPath().string(), &resType); 1253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // these are untyped and don't have an AaptGroupEntry 1255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (entries.indexOf(kind) < 0) { 1257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski entries.add(kind); 1258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mGroupEntries.add(kind); 1259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // use the one from the zip file if they both exist. 1262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dir->removeFile(entryName.getPathLeaf()); 1263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> file = new AaptFile(entryName, kind, resType); 1265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = dir->addLeafFile(entryName.getPathLeaf(), file); 1266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "err=%s entryName=%s\n", strerror(err), entryName.string()); 1268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski count = err; 1269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 1270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski file->setCompressionMethod(entry->getCompressionMethod()); 1272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#if 0 1274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (entryName == "AndroidManifest.xml") { 1275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("AndroidManifest.xml\n"); 1276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\n\nfile: %s\n", entryName.string()); 1278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 1279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len = entry->getUncompressedLen(); 1281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski void* data = zip->uncompress(entry); 1282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski void* buf = file->editData(len); 1283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memcpy(buf, data, len); 1284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#if 0 1286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const int OFF = 0; 1287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const unsigned char* p = (unsigned char*)data; 1288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const unsigned char* end = p+len; 1289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p += OFF; 1290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i=0; i<32 && p < end; i++) { 1291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("0x%03x ", i*0x10 + OFF); 1292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int j=0; j<0x10 && p < end; j++) { 1293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf(" %02x", *p); 1294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p++; 1295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\n"); 1297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 1299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski free(data); 1301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski count++; 1303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 1306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete zip; 1307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return count; 1308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AaptAssets::filter(Bundle* bundle) 1311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 131225dfa75ee39cb75794dd0cc088769b38bc66460aHans Boehm sp<WeakResourceFilter> reqFilter(new WeakResourceFilter()); 131325dfa75ee39cb75794dd0cc088769b38bc66460aHans Boehm status_t err = reqFilter->parse(bundle->getConfigurations()); 1314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 1316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1318fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski uint32_t preferredDensity = 0; 1319fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (bundle->getPreferredDensity().size() > 0) { 1320fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski ResTable_config preferredConfig; 1321fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (!AaptConfig::parseDensity(bundle->getPreferredDensity().string(), &preferredConfig)) { 1322fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski fprintf(stderr, "Error parsing preferred density: %s\n", 1323fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski bundle->getPreferredDensity().string()); 1324fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski return UNKNOWN_ERROR; 1325fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 1326fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski preferredDensity = preferredConfig.density; 1327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 132925dfa75ee39cb75794dd0cc088769b38bc66460aHans Boehm if (reqFilter->isEmpty() && preferredDensity == 0) { 1330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 1331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 133425dfa75ee39cb75794dd0cc088769b38bc66460aHans Boehm if (!reqFilter->isEmpty()) { 1335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Applying required filter: %s\n", 1336fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski bundle->getConfigurations().string()); 1337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1338fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (preferredDensity > 0) { 1339fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski printf("Applying preferred density filter: %s\n", 1340fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski bundle->getPreferredDensity().string()); 1341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<sp<AaptDir> >& resdirs = mResDirs; 1345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t ND = resdirs.size(); 1346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<ND; i++) { 1347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptDir>& dir = resdirs.itemAt(i); 1348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (dir->getLeaf() == kValuesDir) { 1349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // The "value" dir is special since a single file defines 1350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // multiple resources, so we can not do filtering on the 1351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // files themselves. 1352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (dir->getLeaf() == kMipmapDir) { 1355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // We also skip the "mipmap" directory, since the point of this 1356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // is to include all densities without stripping. If you put 1357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // other configurations in here as well they won't be stripped 1358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // either... So don't do that. Seriously. What is wrong with you? 1359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NG = dir->getFiles().size(); 1363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t j=0; j<NG; j++) { 1364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptGroup> grp = dir->getFiles().valueAt(j); 1365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // First remove any configurations we know we don't need. 1367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t k=0; k<grp->getFiles().size(); k++) { 1368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> file = grp->getFiles().valueAt(k); 1369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (k == 0 && grp->getFiles().size() == 1) { 1370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If this is the only file left, we need to keep it. 1371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Otherwise the resource IDs we are using will be inconsistent 1372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // with what we get when not stripping. Sucky, but at least 1373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // for now we can rely on the back-end doing another filtering 1374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass to take this out and leave us with this resource name 1375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // containing no entries. 1376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (file->getPath().getPathExtension() == ".xml") { 1379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // We can't remove .xml files at this point, because when 1380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // we parse them they may add identifier resources, so 1381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // removing them can cause our resource identifiers to 1382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // become inconsistent. 1383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config& config(file->getGroupEntry().toParams()); 138625dfa75ee39cb75794dd0cc088769b38bc66460aHans Boehm if (!reqFilter->match(config)) { 1387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getVerbose()) { 1388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Pruning unneeded resource: %s\n", 1389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski file->getPrintableSource().string()); 1390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski grp->removeFile(k); 1392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski k--; 1393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Quick check: no preferred filters, nothing more to do. 1397fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (preferredDensity == 0) { 1398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 14018cf61845187e301dfc4f64b42921977d38766a34Adam Lesinski // Get the preferred density if there is one. We do not match exactly for density. 14028cf61845187e301dfc4f64b42921977d38766a34Adam Lesinski // If our preferred density is hdpi but we only have mdpi and xhdpi resources, we 14038cf61845187e301dfc4f64b42921977d38766a34Adam Lesinski // pick xhdpi. 1404fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski for (size_t k=0; k<grp->getFiles().size(); k++) { 1405fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski sp<AaptFile> file = grp->getFiles().valueAt(k); 1406fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (k == 0 && grp->getFiles().size() == 1) { 1407fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // If this is the only file left, we need to keep it. 1408fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // Otherwise the resource IDs we are using will be inconsistent 1409fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // with what we get when not stripping. Sucky, but at least 1410fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // for now we can rely on the back-end doing another filtering 1411fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // pass to take this out and leave us with this resource name 1412fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // containing no entries. 1413fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski continue; 1414fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 1415fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (file->getPath().getPathExtension() == ".xml") { 1416fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // We can't remove .xml files at this point, because when 1417fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // we parse them they may add identifier resources, so 1418fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // removing them can cause our resource identifiers to 1419fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // become inconsistent. 1420fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski continue; 1421fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 1422fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const ResTable_config& config(file->getGroupEntry().toParams()); 1423fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (config.density != 0 && config.density != preferredDensity) { 1424fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // This is a resource we would prefer not to have. Check 1425fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // to see if have a similar variation that we would like 1426fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // to have and, if so, we can drop it. 1427fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski uint32_t bestDensity = config.density; 1428fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski 1429fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski for (size_t m=0; m<grp->getFiles().size(); m++) { 1430fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (m == k) { 1431fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski continue; 1432fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 14338cf61845187e301dfc4f64b42921977d38766a34Adam Lesinski 1434fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski sp<AaptFile> mfile = grp->getFiles().valueAt(m); 1435fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const ResTable_config& mconfig(mfile->getGroupEntry().toParams()); 1436fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (AaptConfig::isSameExcept(config, mconfig, ResTable_config::CONFIG_DENSITY)) { 1437fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // See if there is a better density resource 1438fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (mconfig.density < bestDensity && 1439b0db8de73e6e4151b4e9d1fe3be1f609c3c1fb83Bryan Mawhinney mconfig.density >= preferredDensity && 1440fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski bestDensity > preferredDensity) { 1441b0db8de73e6e4151b4e9d1fe3be1f609c3c1fb83Bryan Mawhinney // This density is our preferred density, or between our best density and 1442fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // the preferred density, therefore it is better. 1443fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski bestDensity = mconfig.density; 1444fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } else if (mconfig.density > bestDensity && 1445fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski bestDensity < preferredDensity) { 1446fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // This density is better than our best density and 1447fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // our best density was smaller than our preferred 1448fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski // density, so it is better. 1449fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski bestDensity = mconfig.density; 1450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1452fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski } 14538cf61845187e301dfc4f64b42921977d38766a34Adam Lesinski 1454fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (bestDensity != config.density) { 1455fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (bundle->getVerbose()) { 1456fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski printf("Pruning unneeded resource: %s\n", 1457fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski file->getPrintableSource().string()); 14588cf61845187e301dfc4f64b42921977d38766a34Adam Lesinski } 1459fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski grp->removeFile(k); 1460fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski k--; 1461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 1468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<AaptSymbols> AaptAssets::getSymbolsFor(const String8& name) 1471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> sym = mSymbols.valueFor(name); 1473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (sym == NULL) { 1474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sym = new AaptSymbols(); 1475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mSymbols.add(name, sym); 1476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return sym; 1478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<AaptSymbols> AaptAssets::getJavaSymbolsFor(const String8& name) 1481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> sym = mJavaSymbols.valueFor(name); 1483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (sym == NULL) { 1484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sym = new AaptSymbols(); 1485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mJavaSymbols.add(name, sym); 1486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return sym; 1488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AaptAssets::applyJavaSymbols() 1491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t N = mJavaSymbols.size(); 1493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 1494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String8& name = mJavaSymbols.keyAt(i); 1495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptSymbols>& symbols = mJavaSymbols.valueAt(i); 1496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t pos = mSymbols.indexOfKey(name); 1497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pos < 0) { 1498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos pos; 1499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pos.error("Java symbol dir %s not defined\n", name.string()); 1500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("**** applying java symbols in dir %s\n", name.string()); 1503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = mSymbols.valueAt(pos)->applyJavaSymbols(symbols); 1504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 1506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 1510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool AaptAssets::isJavaSymbol(const AaptSymbolEntry& sym, bool includePrivate) const { 1513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("isJavaSymbol %s: public=%d, includePrivate=%d, isJavaSymbol=%d\n", 1514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // sym.name.string(), sym.isPublic ? 1 : 0, includePrivate ? 1 : 0, 1515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // sym.isJavaSymbol ? 1 : 0); 1516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!mHavePrivateSymbols) return true; 1517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (sym.isPublic) return true; 1518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (includePrivate && sym.isJavaSymbol) return true; 1519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 1520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AaptAssets::buildIncludedResources(Bundle* bundle) 1523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1524833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (mHaveIncludedAssets) { 1525833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski return NO_ERROR; 1526833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 1527833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 1528833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski // Add in all includes. 1529833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski const Vector<String8>& includes = bundle->getPackageIncludes(); 1530833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski const size_t packageIncludeCount = includes.size(); 1531833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski for (size_t i = 0; i < packageIncludeCount; i++) { 1532833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (bundle->getVerbose()) { 1533833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski printf("Including resources from package: %s\n", includes[i].string()); 1534833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 1535833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 1536833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (!mIncludedAssets.addAssetPath(includes[i], NULL)) { 1537833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski fprintf(stderr, "ERROR: Asset package include '%s' not found.\n", 1538833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski includes[i].string()); 1539833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski return UNKNOWN_ERROR; 1540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1543833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski const String8& featureOfBase = bundle->getFeatureOfPackage(); 1544833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (!featureOfBase.isEmpty()) { 1545833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (bundle->getVerbose()) { 1546833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski printf("Including base feature resources from package: %s\n", 1547833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski featureOfBase.string()); 1548833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 1549833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 1550833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (!mIncludedAssets.addAssetPath(featureOfBase, NULL)) { 1551833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski fprintf(stderr, "ERROR: base feature package '%s' not found.\n", 1552833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski featureOfBase.string()); 1553833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski return UNKNOWN_ERROR; 1554833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 1555833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 1556833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 1557833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski mHaveIncludedAssets = true; 1558833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 1559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 1560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AaptAssets::addIncludedResources(const sp<AaptFile>& file) 1563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable& res = getIncludedResources(); 1565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // XXX dirty! 156600b314436f4fdfada4bbf1e79ec12e9fa38aeaf1Narayan Kamath return const_cast<ResTable&>(res).add(file->getData(), file->getSize()); 1567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiconst ResTable& AaptAssets::getIncludedResources() const 1570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mIncludedAssets.getResources(false); 1572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1574ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam LesinskiAssetManager& AaptAssets::getAssetManager() 1575ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski{ 1576ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski return mIncludedAssets; 1577ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski} 1578ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski 1579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AaptAssets::print(const String8& prefix) const 1580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 innerPrefix(prefix); 1582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski innerPrefix.append(" "); 1583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 innerInnerPrefix(innerPrefix); 1584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski innerInnerPrefix.append(" "); 1585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("%sConfigurations:\n", prefix.string()); 1586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N=mGroupEntries.size(); 1587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 1588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 cname = mGroupEntries.itemAt(i).toDirName(String8()); 1589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("%s %s\n", prefix.string(), 1590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski cname != "" ? cname.string() : "(default)"); 1591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\n%sFiles:\n", prefix.string()); 1594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AaptDir::print(innerPrefix); 1595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("\n%sResource Dirs:\n", prefix.string()); 1597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<sp<AaptDir> >& resdirs = mResDirs; 1598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NR = resdirs.size(); 1599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<NR; i++) { 1600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptDir>& d = resdirs.itemAt(i); 1601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("%s Type %s\n", prefix.string(), d->getLeaf().string()); 1602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d->print(innerInnerPrefix); 1603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<AaptDir> AaptAssets::resDir(const String8& name) const 1607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<sp<AaptDir> >& resdirs = mResDirs; 1609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = resdirs.size(); 1610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 1611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptDir>& d = resdirs.itemAt(i); 1612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d->getLeaf() == name) { 1613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return d; 1614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 1617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool 1620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivalid_symbol_name(const String8& symbol) 1621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski static char const * const KEYWORDS[] = { 1623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "abstract", "assert", "boolean", "break", 1624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "byte", "case", "catch", "char", "class", "const", "continue", 1625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "default", "do", "double", "else", "enum", "extends", "final", 1626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "finally", "float", "for", "goto", "if", "implements", "import", 1627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "instanceof", "int", "interface", "long", "native", "new", "package", 1628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "private", "protected", "public", "return", "short", "static", 1629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "strictfp", "super", "switch", "synchronized", "this", "throw", 1630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "throws", "transient", "try", "void", "volatile", "while", 1631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "true", "false", "null", 1632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NULL 1633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski }; 1634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char*const* k = KEYWORDS; 1635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char*const s = symbol.string(); 1636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (*k) { 1637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (0 == strcmp(s, *k)) { 1638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 1639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski k++; 1641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1642282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 1643282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1644