ResourceTable.cpp revision f90f2f8dc36e7243b85e0b6a7fd5a590893c827e
1282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// 2282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// Copyright 2006 The Android Open Source Project 3282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// 4282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// Build resource files from raw assets. 5282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// 6282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 7282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "ResourceTable.h" 8282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 9282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "XMLNode.h" 10282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "ResourceFilter.h" 11282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "ResourceIdCache.h" 12282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 13282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <androidfw/ResourceTypes.h> 14282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <utils/ByteOrder.h> 15282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <stdarg.h> 16282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 17282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#define NOISY(x) //x 18282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 19282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t compileXmlFile(const sp<AaptAssets>& assets, 20282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptFile>& target, 21282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceTable* table, 22282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int options) 23282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 24282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<XMLNode> root = XMLNode::parse(target); 25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (root == NULL) { 26282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 27282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 28a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin 29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return compileXmlFile(assets, root, target, table, options); 30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t compileXmlFile(const sp<AaptAssets>& assets, 33282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptFile>& target, 34282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptFile>& outTarget, 35282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceTable* table, 36282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int options) 37282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<XMLNode> root = XMLNode::parse(target); 39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (root == NULL) { 40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 41282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 42282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return compileXmlFile(assets, root, outTarget, table, options); 44282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t compileXmlFile(const sp<AaptAssets>& assets, 47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<XMLNode>& root, 48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptFile>& target, 49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceTable* table, 50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int options) 51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((options&XML_COMPILE_STRIP_WHITESPACE) != 0) { 53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski root->removeWhitespace(true, NULL); 54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if ((options&XML_COMPILE_COMPACT_WHITESPACE) != 0) { 55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski root->removeWhitespace(false, NULL); 56282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 57282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 58282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((options&XML_COMPILE_UTF8) != 0) { 59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski root->setUTF8(true); 60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasErrors = false; 63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((options&XML_COMPILE_ASSIGN_ATTRIBUTE_IDS) != 0) { 65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = root->assignResourceIds(assets, table); 66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 70282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 71282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = root->parseValues(assets, table); 72282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 73282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 74282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 75282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasErrors) { 77282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 78282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Input XML Resource:\n")); 81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(root->print()); 82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = root->flatten(target, 83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (options&XML_COMPILE_STRIP_COMMENTS) != 0, 84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (options&XML_COMPILE_STRIP_RAW_VALUES) != 0); 85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 86282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Output XML Resource:\n")); 90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(ResXMLTree tree; 91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tree.setTo(target->getData(), target->getSize()); 92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printXMLBlock(&tree)); 93282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 94282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski target->setCompressionMethod(ZipEntry::kCompressDeflated); 95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#undef NOISY 100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#define NOISY(x) //x 101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistruct flag_entry 103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* name; 105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t nameLen; 106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t value; 107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* description; 108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}; 109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t referenceArray[] = 111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 'r', 'e', 'f', 'e', 'r', 'e', 'n', 'c', 'e' }; 112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t stringArray[] = 113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 's', 't', 'r', 'i', 'n', 'g' }; 114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t integerArray[] = 115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 'i', 'n', 't', 'e', 'g', 'e', 'r' }; 116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t booleanArray[] = 117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 'b', 'o', 'o', 'l', 'e', 'a', 'n' }; 118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t colorArray[] = 119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 'c', 'o', 'l', 'o', 'r' }; 120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t floatArray[] = 121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 'f', 'l', 'o', 'a', 't' }; 122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t dimensionArray[] = 123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n' }; 124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t fractionArray[] = 125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 'f', 'r', 'a', 'c', 't', 'i', 'o', 'n' }; 126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t enumArray[] = 127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 'e', 'n', 'u', 'm' }; 128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t flagsArray[] = 129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 'f', 'l', 'a', 'g', 's' }; 130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const flag_entry gFormatFlags[] = { 132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { referenceArray, sizeof(referenceArray)/2, ResTable_map::TYPE_REFERENCE, 133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "a reference to another resource, in the form \"<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>\"\n" 134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "or to a theme attribute in the form \"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>\"."}, 135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { stringArray, sizeof(stringArray)/2, ResTable_map::TYPE_STRING, 136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "a string value, using '\\\\;' to escape characters such as '\\\\n' or '\\\\uxxxx' for a unicode character." }, 137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { integerArray, sizeof(integerArray)/2, ResTable_map::TYPE_INTEGER, 138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "an integer value, such as \"<code>100</code>\"." }, 139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { booleanArray, sizeof(booleanArray)/2, ResTable_map::TYPE_BOOLEAN, 140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "a boolean value, either \"<code>true</code>\" or \"<code>false</code>\"." }, 141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { colorArray, sizeof(colorArray)/2, ResTable_map::TYPE_COLOR, 142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "a color value, in the form of \"<code>#<i>rgb</i></code>\", \"<code>#<i>argb</i></code>\",\n" 143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "\"<code>#<i>rrggbb</i></code>\", or \"<code>#<i>aarrggbb</i></code>\"." }, 144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { floatArray, sizeof(floatArray)/2, ResTable_map::TYPE_FLOAT, 145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "a floating point value, such as \"<code>1.2</code>\"."}, 146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { dimensionArray, sizeof(dimensionArray)/2, ResTable_map::TYPE_DIMENSION, 147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "a dimension value, which is a floating point number appended with a unit such as \"<code>14.5sp</code>\".\n" 148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size),\n" 149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "in (inches), mm (millimeters)." }, 150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { fractionArray, sizeof(fractionArray)/2, ResTable_map::TYPE_FRACTION, 151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "a fractional value, which is a floating point number appended with either % or %p, such as \"<code>14.5%</code>\".\n" 152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "The % suffix always means a percentage of the base size; the optional %p suffix provides a size relative to\n" 153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "some parent container." }, 154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { enumArray, sizeof(enumArray)/2, ResTable_map::TYPE_ENUM, NULL }, 155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { flagsArray, sizeof(flagsArray)/2, ResTable_map::TYPE_FLAGS, NULL }, 156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { NULL, 0, 0, NULL } 157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}; 158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t suggestedArray[] = { 's', 'u', 'g', 'g', 'e', 's', 't', 'e', 'd' }; 160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const flag_entry l10nRequiredFlags[] = { 162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { suggestedArray, sizeof(suggestedArray)/2, ResTable_map::L10N_SUGGESTED, NULL }, 163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { NULL, 0, 0, NULL } 164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}; 165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t nulStr[] = { 0 }; 167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic uint32_t parse_flags(const char16_t* str, size_t len, 169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const flag_entry* flags, bool* outError = NULL) 170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (len > 0 && isspace(*str)) { 172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski str++; 173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski len--; 174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (len > 0 && isspace(str[len-1])) { 176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski len--; 177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* const end = str + len; 180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t value = 0; 181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (str < end) { 183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* div = str; 184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (div < end && *div != '|') { 185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski div++; 186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const flag_entry* cur = flags; 189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (cur->name) { 190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strzcmp16(cur->name, cur->nameLen, str, div-str) == 0) { 191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski value |= cur->value; 192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski cur++; 195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!cur->name) { 198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outError) *outError = true; 199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski str = div < end ? div+1 : div; 203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outError) *outError = false; 206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return value; 207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic String16 mayOrMust(int type, int flags) 210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((type&(~flags)) == 0) { 212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return String16("<p>Must"); 213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return String16("<p>May"); 216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic void appendTypeInfo(ResourceTable* outTable, const String16& pkg, 219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& typeName, const String16& ident, int type, 220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const flag_entry* flags) 221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hadType = false; 223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (flags->name) { 224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((type&flags->value) != 0 && flags->description != NULL) { 225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 fullMsg(mayOrMust(type, flags->value)); 226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fullMsg.append(String16(" be ")); 227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fullMsg.append(String16(flags->description)); 228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outTable->appendTypeComment(pkg, typeName, ident, fullMsg); 229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hadType = true; 230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski flags++; 232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hadType && (type&ResTable_map::TYPE_REFERENCE) == 0) { 234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outTable->appendTypeComment(pkg, typeName, ident, 235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16("<p>This may also be a reference to a resource (in the form\n" 236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "\"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>\") or\n" 237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "theme attribute (in the form\n" 238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "\"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>\")\n" 239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "containing a value of this type.")); 240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistruct PendingAttribute 244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 myPackage; 246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const SourcePos sourcePos; 247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool appendComment; 248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t type; 249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 ident; 250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment; 251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasErrors; 252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool added; 253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski PendingAttribute(String16 _package, const sp<AaptFile>& in, 255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree& block, bool _appendComment) 256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski : myPackage(_package) 257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , sourcePos(in->getPrintableSource(), block.getLineNumber()) 258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , appendComment(_appendComment) 259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , type(ResTable_map::TYPE_ANY) 260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , hasErrors(false) 261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , added(false) 262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t createIfNeeded(ResourceTable* outTable) 266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (added || hasErrors) { 268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski added = true; 271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 attr16("attr"); 273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outTable->hasBagOrEntry(myPackage, attr16, ident)) { 275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Attribute \"%s\" has already been defined\n", 276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(ident).string()); 277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char numberStr[16]; 282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sprintf(numberStr, "%d", type); 283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = outTable->addBag(sourcePos, myPackage, 284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr16, ident, String16(""), 285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16("^type"), 286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16(numberStr), NULL, NULL); 287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outTable->appendComment(myPackage, attr16, ident, comment, appendComment); 292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Attribute %s comment: %s\n", String8(ident).string(), 293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(comment).string()); 294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}; 297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic status_t compileAttribute(const sp<AaptFile>& in, 299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree& block, 300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& myPackage, 301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceTable* outTable, 302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16* outIdent = NULL, 303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool inStyleable = false) 304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski PendingAttribute attr(myPackage, in, block, inStyleable); 306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 attr16("attr"); 308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 id16("id"); 309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Attribute type constants. 311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 enum16("enum"); 312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 flag16("flag"); 313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree::event_code_t code; 315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err; 317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t identIdx = block.indexOfAttribute(NULL, "name"); 319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (identIdx >= 0) { 320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.ident = String16(block.getAttributeStringValue(identIdx, &len)); 321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outIdent) { 322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outIdent = attr.ident; 323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.sourcePos.error("A 'name' attribute is required for <attr>\n"); 326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.comment = String16( 330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.getComment(&len) ? block.getComment(&len) : nulStr); 331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t typeIdx = block.indexOfAttribute(NULL, "format"); 333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (typeIdx >= 0) { 334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 typeStr = String16(block.getAttributeStringValue(typeIdx, &len)); 335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.type = parse_flags(typeStr.string(), typeStr.size(), gFormatFlags); 336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (attr.type == 0) { 337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.sourcePos.error("Tag <attr> 'format' attribute value \"%s\" not valid\n", 338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(typeStr).string()); 339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.createIfNeeded(outTable); 342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (!inStyleable) { 343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Attribute definitions outside of styleables always define the 344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // attribute as a generic value. 345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.createIfNeeded(outTable); 346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Attribute %s: type=0x%08x\n", String8(attr.ident).string(), attr.type); 349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t minIdx = block.indexOfAttribute(NULL, "min"); 351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (minIdx >= 0) { 352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 val = String16(block.getAttributeStringValue(minIdx, &len)); 353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!ResTable::stringToInt(val.string(), val.size(), NULL)) { 354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.sourcePos.error("Tag <attr> 'min' attribute must be a number, not \"%s\"\n", 355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(val).string()); 356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.createIfNeeded(outTable); 359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!attr.hasErrors) { 360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident, 361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16(""), String16("^min"), String16(val), NULL, NULL); 362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t maxIdx = block.indexOfAttribute(NULL, "max"); 369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (maxIdx >= 0) { 370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 val = String16(block.getAttributeStringValue(maxIdx, &len)); 371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!ResTable::stringToInt(val.string(), val.size(), NULL)) { 372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.sourcePos.error("Tag <attr> 'max' attribute must be a number, not \"%s\"\n", 373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(val).string()); 374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.createIfNeeded(outTable); 377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!attr.hasErrors) { 378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident, 379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16(""), String16("^max"), String16(val), NULL, NULL); 380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((minIdx >= 0 || maxIdx >= 0) && (attr.type&ResTable_map::TYPE_INTEGER) == 0) { 385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.sourcePos.error("Tag <attr> must have format=integer attribute if using max or min\n"); 386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t l10nIdx = block.indexOfAttribute(NULL, "localization"); 390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (l10nIdx >= 0) { 391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const uint16_t* str = block.getAttributeStringValue(l10nIdx, &len); 392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool error; 393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t l10n_required = parse_flags(str, len, l10nRequiredFlags, &error); 394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error) { 395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.sourcePos.error("Tag <attr> 'localization' attribute value \"%s\" not valid\n", 396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(str).string()); 397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.createIfNeeded(outTable); 400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!attr.hasErrors) { 401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char buf[11]; 402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sprintf(buf, "%d", l10n_required); 403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident, 404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16(""), String16("^l10n"), String16(buf), NULL, NULL); 405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 enumOrFlagsComment; 412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::START_TAG) { 415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t localType = 0; 416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), enum16.string()) == 0) { 417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski localType = ResTable_map::TYPE_ENUM; 418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), flag16.string()) == 0) { 419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski localType = ResTable_map::TYPE_FLAGS; 420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()) 422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .error("Tag <%s> can not appear inside <attr>, only <enum> or <flag>\n", 423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getElementName(&len)).string()); 424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.createIfNeeded(outTable); 428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (attr.type == ResTable_map::TYPE_ANY) { 430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // No type was explicitly stated, so supplying enum tags 431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // implicitly creates an enum or flag. 432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.type = 0; 433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((attr.type&(ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS)) == 0) { 436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Wasn't originally specified as an enum, so update its type. 437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.type |= localType; 438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!attr.hasErrors) { 439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char numberStr[16]; 440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sprintf(numberStr, "%d", attr.type); 441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addBag(SourcePos(in->getPrintableSource(), block.getLineNumber()), 442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski myPackage, attr16, attr.ident, String16(""), 443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16("^type"), String16(numberStr), NULL, NULL, true); 444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if ((uint32_t)(attr.type&(ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS)) != localType) { 449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (localType == ResTable_map::TYPE_ENUM) { 450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()) 451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .error("<enum> attribute can not be used inside a flags format\n"); 452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()) 455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .error("<flag> attribute can not be used inside a enum format\n"); 456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 itemIdent; 461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t itemIdentIdx = block.indexOfAttribute(NULL, "name"); 462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (itemIdentIdx >= 0) { 463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent = String16(block.getAttributeStringValue(itemIdentIdx, &len)); 464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()) 466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .error("A 'name' attribute is required for <enum> or <flag>\n"); 467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 value; 471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t valueIdx = block.indexOfAttribute(NULL, "value"); 472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (valueIdx >= 0) { 473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski value = String16(block.getAttributeStringValue(valueIdx, &len)); 474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()) 476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .error("A 'value' attribute is required for <enum> or <flag>\n"); 477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!attr.hasErrors && !ResTable::stringToInt(value.string(), value.size(), NULL)) { 480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()) 481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .error("Tag <enum> or <flag> 'value' attribute must be a number," 482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " not \"%s\"\n", 483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(value).string()); 484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Make sure an id is defined for this enum/flag identifier... 488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!attr.hasErrors && !outTable->hasBagOrEntry(itemIdent, &id16, &myPackage)) { 489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->startBag(SourcePos(in->getPrintableSource(), block.getLineNumber()), 490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski myPackage, id16, itemIdent, String16(), NULL); 491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!attr.hasErrors) { 497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (enumOrFlagsComment.size() == 0) { 498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(mayOrMust(attr.type, 499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS)); 500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append((attr.type&ResTable_map::TYPE_ENUM) 501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ? String16(" be one of the following constant values.") 502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski : String16(" be one or more (separated by '|') of the following constant values.")); 503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(String16("</p>\n<table>\n" 504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "<colgroup align=\"left\" />\n" 505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "<colgroup align=\"left\" />\n" 506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "<colgroup align=\"left\" />\n" 507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "<tr><th>Constant</th><th>Value</th><th>Description</th></tr>")); 508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(String16("\n<tr><td><code>")); 511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(itemIdent); 512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(String16("</code></td><td>")); 513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(value); 514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(String16("</td><td>")); 515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (block.getComment(&len)) { 516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(String16(block.getComment(&len))); 517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(String16("</td></tr>")); 519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addBag(SourcePos(in->getPrintableSource(), block.getLineNumber()), 521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski myPackage, 522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr16, attr.ident, String16(""), 523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent, value, NULL, NULL, false, true); 524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (code == ResXMLTree::END_TAG) { 529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), attr16.string()) == 0) { 530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((attr.type&ResTable_map::TYPE_ENUM) != 0) { 533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), enum16.string()) != 0) { 534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()) 535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .error("Found tag </%s> where </enum> is expected\n", 536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getElementName(&len)).string()); 537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), flag16.string()) != 0) { 541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()) 542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .error("Found tag </%s> where </flag> is expected\n", 543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getElementName(&len)).string()); 544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!attr.hasErrors && attr.added) { 551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski appendTypeInfo(outTable, myPackage, attr16, attr.ident, attr.type, gFormatFlags); 552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!attr.hasErrors && enumOrFlagsComment.size() > 0) { 555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(String16("\n</table>")); 556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outTable->appendTypeComment(myPackage, attr16, attr.ident, enumOrFlagsComment); 557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool localeIsDefined(const ResTable_config& config) 564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return config.locale == 0; 566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t parseAndAddBag(Bundle* bundle, 569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptFile>& in, 570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree* block, 571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config& config, 572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& myPackage, 573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& curType, 574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& ident, 575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& parentIdent, 576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& itemIdent, 577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t curFormat, 578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool isFormatted, 579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& product, 580a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin PseudolocalizationMethod pseudolocalize, 581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool overwrite, 582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceTable* outTable) 583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err; 585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 item16("item"); 586a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin 587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 str; 588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<StringPool::entry_style_span> spans; 589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = parseStyledString(bundle, in->getPrintableSource().string(), 590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block, item16, &str, &spans, isFormatted, 591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pseudolocalize); 592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Adding resource bag entry l=%c%c c=%c%c orien=%d d=%d " 597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " pid=%s, bag=%s, id=%s: %s\n", 598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.language[0], config.language[1], 599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.country[0], config.country[1], 600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.orientation, config.density, 601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(parentIdent).string(), 602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(ident).string(), 603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(itemIdent).string(), 604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(str).string())); 605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addBag(SourcePos(in->getPrintableSource(), block->getLineNumber()), 607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski myPackage, curType, ident, parentIdent, itemIdent, str, 608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski &spans, &config, overwrite, false, curFormat); 609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Returns true if needle is one of the elements in the comma-separated list 614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * haystack, false otherwise. 615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool isInProductList(const String16& needle, const String16& haystack) { 617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t *needle2 = needle.string(); 618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t *haystack2 = haystack.string(); 619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t needlesize = needle.size(); 620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (*haystack2 != '\0') { 622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strncmp16(haystack2, needle2, needlesize) == 0) { 623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (haystack2[needlesize] == '\0' || haystack2[needlesize] == ',') { 624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (*haystack2 != '\0' && *haystack2 != ',') { 629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski haystack2++; 630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (*haystack2 == ',') { 632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski haystack2++; 633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 6398ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski/* 6408ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski * A simple container that holds a resource type and name. It is ordered first by type then 6418ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski * by name. 6428ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski */ 6438ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinskistruct type_ident_pair_t { 6448ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski String16 type; 6458ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski String16 ident; 6468ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski 6478ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski type_ident_pair_t() { }; 6488ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski type_ident_pair_t(const String16& t, const String16& i) : type(t), ident(i) { } 6498ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski type_ident_pair_t(const type_ident_pair_t& o) : type(o.type), ident(o.ident) { } 6508ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski inline bool operator < (const type_ident_pair_t& o) const { 6518ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski int cmp = compare_type(type, o.type); 6528ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski if (cmp < 0) { 6538ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski return true; 6548ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski } else if (cmp > 0) { 6558ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski return false; 6568ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski } else { 6578ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski return strictly_order_type(ident, o.ident); 6588ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski } 6598ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski } 6608ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski}; 6618ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski 6628ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski 663282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t parseAndAddEntry(Bundle* bundle, 664282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptFile>& in, 665282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree* block, 666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config& config, 667282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& myPackage, 668282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& curType, 669282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& ident, 670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& curTag, 671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool curIsStyled, 672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t curFormat, 673282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool isFormatted, 674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& product, 675a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin PseudolocalizationMethod pseudolocalize, 676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool overwrite, 6778ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski KeyedVector<type_ident_pair_t, bool>* skippedResourceNames, 678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceTable* outTable) 679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err; 681282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 str; 683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<StringPool::entry_style_span> spans; 684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = parseStyledString(bundle, in->getPrintableSource().string(), block, 685282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag, &str, curIsStyled ? &spans : NULL, 686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski isFormatted, pseudolocalize); 687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 689282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 693282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * If a product type was specified on the command line 694282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * and also in the string, and the two are not the same, 695282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * return without adding the string. 696282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 697282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 698282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char *bundleProduct = bundle->getProduct(); 699282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundleProduct == NULL) { 700282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bundleProduct = ""; 701282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 702282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 703282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (product.size() != 0) { 704282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 705282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * If the command-line-specified product is empty, only "default" 706282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * matches. Other variants are skipped. This is so generation 707282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * of the R.java file when the product is not known is predictable. 708282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 709282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 710282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundleProduct[0] == '\0') { 711282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(String16("default").string(), product.string()) != 0) { 7128ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski /* 7138ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski * This string has a product other than 'default'. Do not add it, 7148ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski * but record it so that if we do not see the same string with 7158ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski * product 'default' or no product, then report an error. 7168ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski */ 7178ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski skippedResourceNames->replaceValueFor( 7188ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski type_ident_pair_t(curType, ident), true); 719282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 720282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 721282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 722282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * The command-line product is not empty. 724282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * If the product for this string is on the command-line list, 725282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * it matches. "default" also matches, but only if nothing 726282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * else has matched already. 727282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 728282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 729282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (isInProductList(product, String16(bundleProduct))) { 730282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ; 731282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(String16("default").string(), product.string()) == 0 && 732282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski !outTable->hasBagOrEntry(myPackage, curType, ident, config)) { 733282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ; 734282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 735282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 736282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 737282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 738282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 739282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 740282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Adding resource entry l=%c%c c=%c%c orien=%d d=%d id=%s: %s\n", 741282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.language[0], config.language[1], 742282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.country[0], config.country[1], 743282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.orientation, config.density, 744282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(ident).string(), String8(str).string())); 745282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 746282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addEntry(SourcePos(in->getPrintableSource(), block->getLineNumber()), 747282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski myPackage, curType, ident, str, &spans, &config, 748282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski false, curFormat, overwrite); 749282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 750282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 751282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 752282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 753282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t compileResourceFile(Bundle* bundle, 754282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptAssets>& assets, 755282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptFile>& in, 756282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config& defParams, 757282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool overwrite, 758282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceTable* outTable) 759282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 760282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree block; 761282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = parseXMLResource(in, &block, false, true); 762282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 763282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 764282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 765282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 766282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Top-level tag. 767282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 resources16("resources"); 768282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 769282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Identifier declaration tags. 770282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 declare_styleable16("declare-styleable"); 771282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 attr16("attr"); 772282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 773282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Data creation organizational tags. 774282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 string16("string"); 775282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 drawable16("drawable"); 776282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 color16("color"); 777282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 bool16("bool"); 778282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 integer16("integer"); 779282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 dimen16("dimen"); 780282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 fraction16("fraction"); 781282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 style16("style"); 782282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 plurals16("plurals"); 783282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 array16("array"); 784282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 string_array16("string-array"); 785282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 integer_array16("integer-array"); 786282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 public16("public"); 787282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 public_padding16("public-padding"); 788282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 private_symbols16("private-symbols"); 789282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 java_symbol16("java-symbol"); 790282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 add_resource16("add-resource"); 791282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 skip16("skip"); 792282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 eat_comment16("eat-comment"); 793282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 794282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Data creation tags. 795282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 bag16("bag"); 796282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 item16("item"); 797282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 798282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Attribute type constants. 799282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 enum16("enum"); 800282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 801282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // plural values 802282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 other16("other"); 803282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 quantityOther16("^other"); 804282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 zero16("zero"); 805282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 quantityZero16("^zero"); 806282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 one16("one"); 807282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 quantityOne16("^one"); 808282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 two16("two"); 809282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 quantityTwo16("^two"); 810282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 few16("few"); 811282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 quantityFew16("^few"); 812282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 many16("many"); 813282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 quantityMany16("^many"); 814282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 815282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // useful attribute names and special values 816282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 name16("name"); 817282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 translatable16("translatable"); 818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 formatted16("formatted"); 819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 false16("false"); 820282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 821282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 myPackage(assets->getPackage()); 822282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 823282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasErrors = false; 824282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 825282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool fileIsTranslatable = true; 826282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strstr(in->getPrintableSource().string(), "donottranslate") != NULL) { 827282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fileIsTranslatable = false; 828282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 829282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 830282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DefaultKeyedVector<String16, uint32_t> nextPublicId(0); 831282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 8328ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski // Stores the resource names that were skipped. Typically this happens when 8338ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski // AAPT is invoked without a product specified and a resource has no 8348ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski // 'default' product attribute. 8358ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski KeyedVector<type_ident_pair_t, bool> skippedResourceNames; 8368ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski 837282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree::event_code_t code; 838282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski do { 839282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski code = block.next(); 840282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } while (code == ResXMLTree::START_NAMESPACE); 841282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 842282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 843282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code != ResXMLTree::START_TAG) { 844282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "No start tag found\n"); 846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 848282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), resources16.string()) != 0) { 849282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 850282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Invalid start tag %s\n", String8(block.getElementName(&len)).string()); 851282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 852282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 853282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 854282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_config curParams(defParams); 855282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_config pseudoParams(curParams); 857a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin pseudoParams.language[0] = 'e'; 858a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin pseudoParams.language[1] = 'n'; 859a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin pseudoParams.country[0] = 'X'; 860a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin pseudoParams.country[1] = 'A'; 861a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin 862a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin ResTable_config pseudoBidiParams(curParams); 863a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin pseudoBidiParams.language[0] = 'a'; 864a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin pseudoBidiParams.language[1] = 'r'; 865a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin pseudoBidiParams.country[0] = 'X'; 866a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin pseudoBidiParams.country[1] = 'B'; 867282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 86847843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk // We should skip resources for pseudolocales if they were 86947843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk // already added automatically. This is a fix for a transition period when 87047843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk // manually pseudolocalized resources may be expected. 87147843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk // TODO: remove this check after next SDK version release. 87247843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk if ((bundle->getPseudolocalize() & PSEUDO_ACCENTED && 87347843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk curParams.locale == pseudoParams.locale) || 87447843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk (bundle->getPseudolocalize() & PSEUDO_BIDI && 87547843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk curParams.locale == pseudoBidiParams.locale)) { 87647843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk SourcePos(in->getPrintableSource(), 0).warning( 87747843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk "Resource file %s is skipped as pseudolocalization" 87847843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk " was done automatically.", 87947843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk in->getPrintableSource().string()); 88047843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk return NO_ERROR; 88147843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk } 88247843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk 883282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 884282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::START_TAG) { 885282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16* curTag = NULL; 886282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 curType; 887282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t curFormat = ResTable_map::TYPE_ANY; 888282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool curIsBag = false; 889282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool curIsBagReplaceOnOverwrite = false; 890282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool curIsStyled = false; 891282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool curIsPseudolocalizable = false; 892282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool curIsFormatted = fileIsTranslatable; 893282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool localHasErrors = false; 894282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 895282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), skip16.string()) == 0) { 896282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT 897282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski && code != ResXMLTree::BAD_DOCUMENT) { 898282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 899282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), skip16.string()) == 0) { 900282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 901282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 902282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 903282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 904282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 905282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 906282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) { 907282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT 908282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski && code != ResXMLTree::BAD_DOCUMENT) { 909282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 910282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) { 911282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 912282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 913282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 914282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 915282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 916282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 917282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), public16.string()) == 0) { 918282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos srcPos(in->getPrintableSource(), block.getLineNumber()); 919282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 920282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 type; 921282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t typeIdx = block.indexOfAttribute(NULL, "type"); 922282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (typeIdx < 0) { 923282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("A 'type' attribute is required for <public>\n"); 924282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 925282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 926282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type = String16(block.getAttributeStringValue(typeIdx, &len)); 927282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 928282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 name; 929282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t nameIdx = block.indexOfAttribute(NULL, "name"); 930282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (nameIdx < 0) { 931282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("A 'name' attribute is required for <public>\n"); 932282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 933282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 934282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name = String16(block.getAttributeStringValue(nameIdx, &len)); 935282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 936282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t ident = 0; 937282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t identIdx = block.indexOfAttribute(NULL, "id"); 938282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (identIdx >= 0) { 939282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* identStr = block.getAttributeStringValue(identIdx, &len); 940282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value identValue; 941282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!ResTable::stringToInt(identStr, len, &identValue)) { 942282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("Given 'id' attribute is not an integer: %s\n", 943282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getAttributeStringValue(identIdx, &len)).string()); 944282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 945282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 946282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ident = identValue.data; 947282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nextPublicId.replaceValueFor(type, ident+1); 948282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 949282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (nextPublicId.indexOfKey(type) < 0) { 950282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("No 'id' attribute supplied <public>," 951282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " and no previous id defined in this file.\n"); 952282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 953282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (!localHasErrors) { 954282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ident = nextPublicId.valueFor(type); 955282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nextPublicId.replaceValueFor(type, ident+1); 956282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 957282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 958282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!localHasErrors) { 959282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addPublic(srcPos, myPackage, type, name, ident); 960282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 961282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 962282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 963282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 964282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!localHasErrors) { 965282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R")); 966282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols != NULL) { 967282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols = symbols->addNestedSymbol(String8(type), srcPos); 968282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 969282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols != NULL) { 970282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols->makeSymbolPublic(String8(name), srcPos); 971282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment( 972282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.getComment(&len) ? block.getComment(&len) : nulStr); 973282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols->appendComment(String8(name), comment, srcPos); 974282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 975282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("Unable to create symbols!\n"); 976282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 977282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 978282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 979282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 980282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 981282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 982282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), public16.string()) == 0) { 983282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 984282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 985282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 986282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 987282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 988282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 989282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), public_padding16.string()) == 0) { 990282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos srcPos(in->getPrintableSource(), block.getLineNumber()); 991282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 992282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 type; 993282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t typeIdx = block.indexOfAttribute(NULL, "type"); 994282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (typeIdx < 0) { 995282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("A 'type' attribute is required for <public-padding>\n"); 996282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 997282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 998282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type = String16(block.getAttributeStringValue(typeIdx, &len)); 999282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1000282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 name; 1001282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t nameIdx = block.indexOfAttribute(NULL, "name"); 1002282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (nameIdx < 0) { 1003282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("A 'name' attribute is required for <public-padding>\n"); 1004282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1005282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1006282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name = String16(block.getAttributeStringValue(nameIdx, &len)); 1007282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1008282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t start = 0; 1009282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t startIdx = block.indexOfAttribute(NULL, "start"); 1010282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (startIdx >= 0) { 1011282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* startStr = block.getAttributeStringValue(startIdx, &len); 1012282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value startValue; 1013282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!ResTable::stringToInt(startStr, len, &startValue)) { 1014282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("Given 'start' attribute is not an integer: %s\n", 1015282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getAttributeStringValue(startIdx, &len)).string()); 1016282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1017282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1018282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski start = startValue.data; 1019282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1020282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (nextPublicId.indexOfKey(type) < 0) { 1021282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("No 'start' attribute supplied <public-padding>," 1022282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " and no previous id defined in this file.\n"); 1023282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1024282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (!localHasErrors) { 1025282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski start = nextPublicId.valueFor(type); 1026282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1027282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1028282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t end = 0; 1029282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t endIdx = block.indexOfAttribute(NULL, "end"); 1030282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (endIdx >= 0) { 1031282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* endStr = block.getAttributeStringValue(endIdx, &len); 1032282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value endValue; 1033282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!ResTable::stringToInt(endStr, len, &endValue)) { 1034282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("Given 'end' attribute is not an integer: %s\n", 1035282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getAttributeStringValue(endIdx, &len)).string()); 1036282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1037282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1038282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski end = endValue.data; 1039282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1040282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1041282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("No 'end' attribute supplied <public-padding>\n"); 1042282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1043282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1044282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1045282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (end >= start) { 1046282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nextPublicId.replaceValueFor(type, end+1); 1047282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1048282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("Padding start '%ul' is after end '%ul'\n", 1049282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski start, end); 1050282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1051282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1052282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1053282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment( 1054282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.getComment(&len) ? block.getComment(&len) : nulStr); 1055282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (uint32_t curIdent=start; curIdent<=end; curIdent++) { 1056282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (localHasErrors) { 1057282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1058282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1059282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 curName(name); 1060282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char buf[64]; 1061282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sprintf(buf, "%d", (int)(end-curIdent+1)); 1062282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curName.append(String16(buf)); 1063282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1064282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addEntry(srcPos, myPackage, type, curName, 1065282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16("padding"), NULL, &curParams, false, 1066282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_map::TYPE_STRING, overwrite); 1067282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 1068282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1069282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1070282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1071282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addPublic(srcPos, myPackage, type, 1072282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curName, curIdent); 1073282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 1074282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1075282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1076282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1077282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R")); 1078282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols != NULL) { 1079282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols = symbols->addNestedSymbol(String8(type), srcPos); 1080282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1081282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols != NULL) { 1082282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols->makeSymbolPublic(String8(curName), srcPos); 1083282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols->appendComment(String8(curName), comment, srcPos); 1084282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1085282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("Unable to create symbols!\n"); 1086282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1087282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1088282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1089282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1090282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 1091282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 1092282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), public_padding16.string()) == 0) { 1093282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1094282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1095282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1096282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1097282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1098282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1099282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), private_symbols16.string()) == 0) { 1100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 pkg; 1101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t pkgIdx = block.indexOfAttribute(NULL, "package"); 1102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pkgIdx < 0) { 1103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "A 'package' attribute is required for <private-symbols>\n"); 1105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pkg = String16(block.getAttributeStringValue(pkgIdx, &len)); 1108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!localHasErrors) { 1109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->setSymbolsPrivatePackage(String8(pkg)); 1110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 1113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 1114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), private_symbols16.string()) == 0) { 1115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), java_symbol16.string()) == 0) { 1122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos srcPos(in->getPrintableSource(), block.getLineNumber()); 1123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 type; 1125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t typeIdx = block.indexOfAttribute(NULL, "type"); 1126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (typeIdx < 0) { 1127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("A 'type' attribute is required for <public>\n"); 1128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type = String16(block.getAttributeStringValue(typeIdx, &len)); 1131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 name; 1133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t nameIdx = block.indexOfAttribute(NULL, "name"); 1134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (nameIdx < 0) { 1135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("A 'name' attribute is required for <public>\n"); 1136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name = String16(block.getAttributeStringValue(nameIdx, &len)); 1139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> symbols = assets->getJavaSymbolsFor(String8("R")); 1141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols != NULL) { 1142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols = symbols->addNestedSymbol(String8(type), srcPos); 1143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols != NULL) { 1145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols->makeSymbolJavaSymbol(String8(name), srcPos); 1146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment( 1147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.getComment(&len) ? block.getComment(&len) : nulStr); 1148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols->appendComment(String8(name), comment, srcPos); 1149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("Unable to create symbols!\n"); 1151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 1155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 1156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), java_symbol16.string()) == 0) { 1157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), add_resource16.string()) == 0) { 1165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos srcPos(in->getPrintableSource(), block.getLineNumber()); 1166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 typeName; 1168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t typeIdx = block.indexOfAttribute(NULL, "type"); 1169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (typeIdx < 0) { 1170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("A 'type' attribute is required for <add-resource>\n"); 1171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeName = String16(block.getAttributeStringValue(typeIdx, &len)); 1174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 name; 1176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t nameIdx = block.indexOfAttribute(NULL, "name"); 1177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (nameIdx < 0) { 1178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("A 'name' attribute is required for <add-resource>\n"); 1179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name = String16(block.getAttributeStringValue(nameIdx, &len)); 1182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outTable->canAddEntry(srcPos, myPackage, typeName, name); 1184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 1186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 1187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), add_resource16.string()) == 0) { 1188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), declare_styleable16.string()) == 0) { 1195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos srcPos(in->getPrintableSource(), block.getLineNumber()); 1196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 ident; 1198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t identIdx = block.indexOfAttribute(NULL, "name"); 1199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (identIdx < 0) { 1200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("A 'name' attribute is required for <declare-styleable>\n"); 1201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ident = String16(block.getAttributeStringValue(identIdx, &len)); 1204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R")); 1206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!localHasErrors) { 1207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols != NULL) { 1208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols = symbols->addNestedSymbol(String8("styleable"), srcPos); 1209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> styleSymbols = symbols; 1211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols != NULL) { 1212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols = symbols->addNestedSymbol(String8(ident), srcPos); 1213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols == NULL) { 1215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("Unable to create symbols!\n"); 1216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment( 1220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.getComment(&len) ? block.getComment(&len) : nulStr); 1221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski styleSymbols->appendComment(String8(ident), comment, srcPos); 1222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols = NULL; 1224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 1227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::START_TAG) { 1228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), skip16.string()) == 0) { 1229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT 1230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski && code != ResXMLTree::BAD_DOCUMENT) { 1231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 1232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), skip16.string()) == 0) { 1233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) { 1239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT 1240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski && code != ResXMLTree::BAD_DOCUMENT) { 1241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 1242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) { 1243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), attr16.string()) != 0) { 1249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Tag <%s> can not appear inside <declare-styleable>, only <attr>\n", 1251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getElementName(&len)).string()); 1252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment( 1256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.getComment(&len) ? block.getComment(&len) : nulStr); 1257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 itemIdent; 1258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = compileAttribute(in, block, myPackage, outTable, &itemIdent, true); 1259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols != NULL) { 1264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos srcPos(String8(in->getPrintableSource()), block.getLineNumber()); 1265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols->addSymbol(String8(itemIdent), 0, srcPos); 1266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols->appendComment(String8(itemIdent), comment, srcPos); 1267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Attribute %s comment: %s\n", String8(itemIdent).string(), 1268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(comment).string()); 1269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (code == ResXMLTree::END_TAG) { 1271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), declare_styleable16.string()) == 0) { 1272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Found tag </%s> where </attr> is expected\n", 1277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getElementName(&len)).string()); 1278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), attr16.string()) == 0) { 1284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = compileAttribute(in, block, myPackage, outTable, NULL); 1285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), item16.string()) == 0) { 1291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &item16; 1292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t attri = block.indexOfAttribute(NULL, "type"); 1293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (attri >= 0) { 1294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = String16(block.getAttributeStringValue(attri, &len)); 1295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t formatIdx = block.indexOfAttribute(NULL, "format"); 1296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (formatIdx >= 0) { 1297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 formatStr = String16(block.getAttributeStringValue( 1298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski formatIdx, &len)); 1299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = parse_flags(formatStr.string(), formatStr.size(), 1300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski gFormatFlags); 1301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (curFormat == 0) { 1302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Tag <item> 'format' attribute value \"%s\" not valid\n", 1304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(formatStr).string()); 1305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "A 'type' attribute is required for <item>\n"); 1311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsStyled = true; 1314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), string16.string()) == 0) { 1315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Note the existence and locale of every string we process 131691447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath char rawLocale[RESTABLE_MAX_LOCALE_LEN]; 131791447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath curParams.getBcp47Locale(rawLocale); 1318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 locale(rawLocale); 1319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 name; 1320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 translatable; 1321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 formatted; 1322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t n = block.getAttributeCount(); 1324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i = 0; i < n; i++) { 1325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t length; 1326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const uint16_t* attr = block.getAttributeName(i, &length); 1327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(attr, name16.string()) == 0) { 1328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name.setTo(block.getAttributeStringValue(i, &length)); 1329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(attr, translatable16.string()) == 0) { 1330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski translatable.setTo(block.getAttributeStringValue(i, &length)); 1331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(attr, formatted16.string()) == 0) { 1332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski formatted.setTo(block.getAttributeStringValue(i, &length)); 1333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name.size() > 0) { 1337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (translatable == false16) { 1338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsFormatted = false; 1339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Untranslatable strings must only exist in the default [empty] locale 1340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (locale.size() > 0) { 1341a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).warning( 1342a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski "string '%s' marked untranslatable but exists in locale '%s'\n", 1343a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski String8(name).string(), 1344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski locale.string()); 1345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // hasErrors = localHasErrors = true; 1346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Intentionally empty block: 1348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // 1349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Don't add untranslatable strings to the localization table; that 1350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // way if we later see localizations of them, they'll be flagged as 1351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // having no default translation. 1352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1354a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski outTable->addLocalization( 1355a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski name, 1356a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski locale, 1357a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber())); 1358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (formatted == false16) { 1361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsFormatted = false; 1362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &string16; 1366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = string16; 1367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_STRING; 1368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsStyled = true; 136984410b054c7db0b6685a0f15cb2d1ffcb264f6c9Igor Viarheichyk curIsPseudolocalizable = fileIsTranslatable && (translatable != false16); 1370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), drawable16.string()) == 0) { 1371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &drawable16; 1372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = drawable16; 1373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_COLOR; 1374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), color16.string()) == 0) { 1375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &color16; 1376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = color16; 1377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_COLOR; 1378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), bool16.string()) == 0) { 1379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &bool16; 1380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = bool16; 1381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_BOOLEAN; 1382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), integer16.string()) == 0) { 1383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &integer16; 1384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = integer16; 1385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_INTEGER; 1386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), dimen16.string()) == 0) { 1387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &dimen16; 1388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = dimen16; 1389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_DIMENSION; 1390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), fraction16.string()) == 0) { 1391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &fraction16; 1392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = fraction16; 1393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_FRACTION; 1394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), bag16.string()) == 0) { 1395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &bag16; 1396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsBag = true; 1397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t attri = block.indexOfAttribute(NULL, "type"); 1398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (attri >= 0) { 1399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = String16(block.getAttributeStringValue(attri, &len)); 1400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "A 'type' attribute is required for <bag>\n"); 1403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), style16.string()) == 0) { 1406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &style16; 1407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = style16; 1408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsBag = true; 1409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), plurals16.string()) == 0) { 1410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &plurals16; 1411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = plurals16; 1412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsBag = true; 1413a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin curIsPseudolocalizable = fileIsTranslatable; 1414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), array16.string()) == 0) { 1415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &array16; 1416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = array16; 1417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsBag = true; 1418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsBagReplaceOnOverwrite = true; 1419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t formatIdx = block.indexOfAttribute(NULL, "format"); 1420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (formatIdx >= 0) { 1421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 formatStr = String16(block.getAttributeStringValue( 1422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski formatIdx, &len)); 1423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = parse_flags(formatStr.string(), formatStr.size(), 1424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski gFormatFlags); 1425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (curFormat == 0) { 1426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Tag <array> 'format' attribute value \"%s\" not valid\n", 1428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(formatStr).string()); 1429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), string_array16.string()) == 0) { 1433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Check whether these strings need valid formats. 1434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // (simplified form of what string16 does above) 1435a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin bool isTranslatable = false; 1436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t n = block.getAttributeCount(); 14379a9fa163c384e7fff159d339dfcce3b3122bece5Narayan Kamath 14389a9fa163c384e7fff159d339dfcce3b3122bece5Narayan Kamath // Pseudolocalizable by default, unless this string array isn't 14399a9fa163c384e7fff159d339dfcce3b3122bece5Narayan Kamath // translatable. 1440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i = 0; i < n; i++) { 1441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t length; 1442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const uint16_t* attr = block.getAttributeName(i, &length); 1443a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin if (strcmp16(attr, formatted16.string()) == 0) { 14449a9fa163c384e7fff159d339dfcce3b3122bece5Narayan Kamath const uint16_t* value = block.getAttributeStringValue(i, &length); 14459a9fa163c384e7fff159d339dfcce3b3122bece5Narayan Kamath if (strcmp16(value, false16.string()) == 0) { 1446a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin curIsFormatted = false; 14479a9fa163c384e7fff159d339dfcce3b3122bece5Narayan Kamath } 1448a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin } else if (strcmp16(attr, translatable16.string()) == 0) { 1449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const uint16_t* value = block.getAttributeStringValue(i, &length); 1450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(value, false16.string()) == 0) { 1451a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin isTranslatable = false; 1452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &string_array16; 1457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = array16; 1458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_STRING; 1459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsBag = true; 1460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsBagReplaceOnOverwrite = true; 1461a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin curIsPseudolocalizable = isTranslatable && fileIsTranslatable; 1462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), integer_array16.string()) == 0) { 1463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &integer_array16; 1464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = array16; 1465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_INTEGER; 1466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsBag = true; 1467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsBagReplaceOnOverwrite = true; 1468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Found tag %s where item is expected\n", 1471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getElementName(&len)).string()); 1472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 ident; 1476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t identIdx = block.indexOfAttribute(NULL, "name"); 1477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (identIdx >= 0) { 1478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ident = String16(block.getAttributeStringValue(identIdx, &len)); 1479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "A 'name' attribute is required for <%s>\n", 1482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(*curTag).string()); 1483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 product; 1487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski identIdx = block.indexOfAttribute(NULL, "product"); 1488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (identIdx >= 0) { 1489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski product = String16(block.getAttributeStringValue(identIdx, &len)); 1490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment(block.getComment(&len) ? block.getComment(&len) : nulStr); 1493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (curIsBag) { 1495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Figure out the parent of this bag... 1496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 parentIdent; 1497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t parentIdentIdx = block.indexOfAttribute(NULL, "parent"); 1498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (parentIdentIdx >= 0) { 1499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski parentIdent = String16(block.getAttributeStringValue(parentIdentIdx, &len)); 1500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t sep = ident.findLast('.'); 1502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (sep >= 0) { 1503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski parentIdent.setTo(ident, sep); 1504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!localHasErrors) { 1508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->startBag(SourcePos(in->getPrintableSource(), 1509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.getLineNumber()), myPackage, curType, ident, 1510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski parentIdent, &curParams, 1511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski overwrite, curIsBagReplaceOnOverwrite); 1512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t elmIndex = 0; 1518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char elmIndexStr[14]; 1519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT 1520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski && code != ResXMLTree::BAD_DOCUMENT) { 1521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::START_TAG) { 1523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), item16.string()) != 0) { 1524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Tag <%s> can not appear inside <%s>, only <item>\n", 1526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getElementName(&len)).string(), 1527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(*curTag).string()); 1528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 itemIdent; 1532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (curType == array16) { 1533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sprintf(elmIndexStr, "^index_%d", (int)elmIndex++); 1534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent = String16(elmIndexStr); 1535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (curType == plurals16) { 1536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t itemIdentIdx = block.indexOfAttribute(NULL, "quantity"); 1537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (itemIdentIdx >= 0) { 1538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 quantity16(block.getAttributeStringValue(itemIdentIdx, &len)); 1539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (quantity16 == other16) { 1540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent = quantityOther16; 1541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (quantity16 == zero16) { 1543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent = quantityZero16; 1544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (quantity16 == one16) { 1546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent = quantityOne16; 1547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (quantity16 == two16) { 1549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent = quantityTwo16; 1550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (quantity16 == few16) { 1552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent = quantityFew16; 1553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (quantity16 == many16) { 1555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent = quantityMany16; 1556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else { 1558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Illegal 'quantity' attribute is <item> inside <plurals>\n"); 1560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "A 'quantity' attribute is required for <item> inside <plurals>\n"); 1565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t itemIdentIdx = block.indexOfAttribute(NULL, "name"); 1569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (itemIdentIdx >= 0) { 1570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent = String16(block.getAttributeStringValue(itemIdentIdx, &len)); 1571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "A 'name' attribute is required for <item>\n"); 1574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLParser::ResXMLPosition parserPosition; 1579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.getPosition(&parserPosition); 1580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = parseAndAddBag(bundle, in, &block, curParams, myPackage, curType, 1582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ident, parentIdent, itemIdent, curFormat, curIsFormatted, 1583a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin product, NO_PSEUDOLOCALIZATION, overwrite, outTable); 1584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err == NO_ERROR) { 1585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (curIsPseudolocalizable && localeIsDefined(curParams) 1586a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin && bundle->getPseudolocalize() > 0) { 1587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pseudolocalize here 1588a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin if ((PSEUDO_ACCENTED & bundle->getPseudolocalize()) == 1589a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin PSEUDO_ACCENTED) { 1590a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin block.setPosition(parserPosition); 1591a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin err = parseAndAddBag(bundle, in, &block, pseudoParams, myPackage, 1592a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin curType, ident, parentIdent, itemIdent, curFormat, 1593a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin curIsFormatted, product, PSEUDO_ACCENTED, 1594a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin overwrite, outTable); 1595a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin } 1596a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin if ((PSEUDO_BIDI & bundle->getPseudolocalize()) == 1597a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin PSEUDO_BIDI) { 1598a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin block.setPosition(parserPosition); 1599a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin err = parseAndAddBag(bundle, in, &block, pseudoBidiParams, myPackage, 1600a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin curType, ident, parentIdent, itemIdent, curFormat, 1601a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin curIsFormatted, product, PSEUDO_BIDI, 1602a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin overwrite, outTable); 1603a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin } 1604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1605a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin } 1606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (code == ResXMLTree::END_TAG) { 1610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), curTag->string()) != 0) { 1611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Found tag </%s> where </%s> is expected\n", 1613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getElementName(&len)).string(), 1614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(*curTag).string()); 1615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLParser::ResXMLPosition parserPosition; 1622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.getPosition(&parserPosition); 1623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = parseAndAddEntry(bundle, in, &block, curParams, myPackage, curType, ident, 1625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *curTag, curIsStyled, curFormat, curIsFormatted, 1626a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin product, NO_PSEUDOLOCALIZATION, overwrite, &skippedResourceNames, outTable); 1627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { // Why err < NO_ERROR instead of err != NO_ERROR? 1629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (err == NO_ERROR) { 1632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (curIsPseudolocalizable && localeIsDefined(curParams) 1633a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin && bundle->getPseudolocalize() > 0) { 1634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pseudolocalize here 1635a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin if ((PSEUDO_ACCENTED & bundle->getPseudolocalize()) == 1636a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin PSEUDO_ACCENTED) { 1637a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin block.setPosition(parserPosition); 1638a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin err = parseAndAddEntry(bundle, in, &block, pseudoParams, myPackage, curType, 1639a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin ident, *curTag, curIsStyled, curFormat, 1640a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin curIsFormatted, product, 1641a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin PSEUDO_ACCENTED, overwrite, &skippedResourceNames, outTable); 1642a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin } 1643a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin if ((PSEUDO_BIDI & bundle->getPseudolocalize()) == 1644a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin PSEUDO_BIDI) { 1645a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin block.setPosition(parserPosition); 1646a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin err = parseAndAddEntry(bundle, in, &block, pseudoBidiParams, 1647a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin myPackage, curType, ident, *curTag, curIsStyled, curFormat, 1648a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin curIsFormatted, product, 1649a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin PSEUDO_BIDI, overwrite, &skippedResourceNames, outTable); 1650a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin } 1651282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1653282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1654282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1655282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1656282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1657282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1658282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#if 0 1659282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() > 0) { 1660282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Comment for @%s:%s/%s: %s\n", String8(myPackage).string(), 1661282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(curType).string(), String8(ident).string(), 1662282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(comment).string()); 1663282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1664282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 1665282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!localHasErrors) { 1666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outTable->appendComment(myPackage, curType, ident, comment, false); 1667282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1668282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1669282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (code == ResXMLTree::END_TAG) { 1670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), resources16.string()) != 0) { 1671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Unexpected end tag %s\n", String8(block.getElementName(&len)).string()); 1673282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1675282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (code == ResXMLTree::START_NAMESPACE || code == ResXMLTree::END_NAMESPACE) { 1677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (code == ResXMLTree::TEXT) { 1679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (isWhitespace(block.getText(&len))) { 1680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1681282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Found text \"%s\" where item tag is expected\n", 1684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getText(&len)).string()); 1685282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 16898ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski // For every resource defined, there must be exist one variant with a product attribute 16908ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski // set to 'default' (or no product attribute at all). 16918ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski // We check to see that for every resource that was ignored because of a mismatched 16928ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski // product attribute, some product variant of that resource was processed. 16938ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski for (size_t i = 0; i < skippedResourceNames.size(); i++) { 16948ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski if (skippedResourceNames[i]) { 16958ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski const type_ident_pair_t& p = skippedResourceNames.keyAt(i); 16968ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski if (!outTable->hasBagOrEntry(myPackage, p.type, p.ident)) { 16978ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski const char* bundleProduct = 16988ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski (bundle->getProduct() == NULL) ? "" : bundle->getProduct(); 16998ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski fprintf(stderr, "In resource file %s: %s\n", 17008ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski in->getPrintableSource().string(), 17018ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski curParams.toString().string()); 17028ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski 17038ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski fprintf(stderr, "\t%s '%s' does not match product %s.\n" 17048ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski "\tYou may have forgotten to include a 'default' product variant" 17058ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski " of the resource.\n", 17068ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski String8(p.type).string(), String8(p.ident).string(), 17078ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski bundleProduct[0] == 0 ? "default" : bundleProduct); 17088ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski return UNKNOWN_ERROR; 17098ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski } 17108ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski } 17118ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski } 17128ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski 1713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return hasErrors ? UNKNOWN_ERROR : NO_ERROR; 1714282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1715282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1716282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiResourceTable::ResourceTable(Bundle* bundle, const String16& assetsPackage) 1717282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski : mAssetsPackage(assetsPackage), mNextPackageId(1), mHaveAppPackage(false), 1718de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski mIsAppPackage(!bundle->getExtending()), mIsSharedLibrary(bundle->getBuildSharedLibrary()), 1719282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mNumLocal(0), 1720282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mBundle(bundle) 1721282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1722282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1724282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::addIncludedResources(Bundle* bundle, const sp<AaptAssets>& assets) 1725282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1726282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = assets->buildIncludedResources(bundle); 1727282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1728282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 1729282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1730282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1731282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // For future reference to included resources. 1732282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mAssets = assets; 1733282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1734282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable& incl = assets->getIncludedResources(); 1735282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1736282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Retrieve all the packages. 1737282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = incl.getBasePackageCount(); 1738282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t phase=0; phase<2; phase++) { 1739282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 1740de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski const String16 name = incl.getBasePackageName(i); 1741282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t id = incl.getBasePackageId(i); 1742de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 1743282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // First time through: only add base packages (id 1744282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // is not 0); second time through add the other 1745282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // packages. 1746282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (phase != 0) { 1747282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (id != 0) { 1748282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Skip base packages -- already one. 1749282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski id = 0; 1750282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1751282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Assign a dynamic id. 1752282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski id = mNextPackageId; 1753282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1754282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (id != 0) { 1755282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (id == 127) { 1756282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mHaveAppPackage) { 1757282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "Included resources have two application packages!\n"); 1758282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1759282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1760282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mHaveAppPackage = true; 1761282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1762282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mNextPackageId > id) { 1763282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "Included base package ID %d already in use!\n", id); 1764282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1765282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1766282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1767282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (id != 0) { 1768de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski NOISY(fprintf(stderr, "Including package %s with ID=%d\n", 1769282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(name).string(), id)); 1770282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = new Package(name, id); 1771282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mPackages.add(name, p); 1772282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedPackages.add(p); 1773282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1774282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (id >= mNextPackageId) { 1775282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mNextPackageId = id+1; 1776282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1777282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1778282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1779282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1780282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1781282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Every resource table always has one first entry, the bag attributes. 1782282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const SourcePos unknown(String8("????"), 0); 1783282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> attr = getType(mAssetsPackage, String16("attr"), unknown); 1784282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1785282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 1786282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1787282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1788282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::addPublic(const SourcePos& sourcePos, 1789282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& package, 1790282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 1791282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 1792282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const uint32_t ident) 1793282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1794282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t rid = mAssets->getIncludedResources() 1795282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .identifierForName(name.string(), name.size(), 1796282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type.string(), type.size(), 1797282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski package.string(), package.size()); 1798282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (rid != 0) { 1799282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Error declaring public resource %s/%s for included package %s\n", 1800282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(type).string(), String8(name).string(), 1801282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(package).string()); 1802282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1803282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1804282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1805282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = getType(package, type, sourcePos); 1806282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) { 1807282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1808282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1809282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return t->addPublic(sourcePos, name, ident); 1810282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1811282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1812282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::addEntry(const SourcePos& sourcePos, 1813282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& package, 1814282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 1815282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 1816282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& value, 1817282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<StringPool::entry_style_span>* style, 1818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config* params, 1819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool doSetIndex, 1820282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const int32_t format, 1821282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool overwrite) 1822282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1823282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Check for adding entries in other packages... for now we do 1824282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // nothing. We need to do the right thing here to support skinning. 1825282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t rid = mAssets->getIncludedResources() 1826282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .identifierForName(name.string(), name.size(), 1827282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type.string(), type.size(), 1828282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski package.string(), package.size()); 1829282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (rid != 0) { 1830282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 1831282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1832282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1833282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#if 0 1834282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name == String16("left")) { 1835282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Adding entry left: file=%s, line=%d, type=%s, value=%s\n", 1836282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.file.string(), sourcePos.line, String8(type).string(), 1837282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(value).string()); 1838282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1839282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 1840282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1841282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = getEntry(package, type, name, sourcePos, overwrite, 1842282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski params, doSetIndex); 1843282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e == NULL) { 1844282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = e->setItem(sourcePos, value, style, format, overwrite); 1847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err == NO_ERROR) { 1848282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mNumLocal++; 1849282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1850282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 1851282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1852282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1853282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::startBag(const SourcePos& sourcePos, 1854282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& package, 1855282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 1856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 1857282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& bagParent, 1858282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config* params, 1859282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool overlay, 1860282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool replace, bool isId) 1861282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1862282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t result = NO_ERROR; 1863282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1864282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Check for adding entries in other packages... for now we do 1865282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // nothing. We need to do the right thing here to support skinning. 1866282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t rid = mAssets->getIncludedResources() 1867282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .identifierForName(name.string(), name.size(), 1868282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type.string(), type.size(), 1869282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski package.string(), package.size()); 1870282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (rid != 0) { 1871282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 1872282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1873282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1874282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#if 0 1875282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name == String16("left")) { 1876282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Adding bag left: file=%s, line=%d, type=%s\n", 1877282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.file.striing(), sourcePos.line, String8(type).string()); 1878282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1879282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 1880282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (overlay && !mBundle->getAutoAddOverlay() && !hasBagOrEntry(package, type, name)) { 1881282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool canAdd = false; 1882282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mPackages.valueFor(package); 1883282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p != NULL) { 1884282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getTypes().valueFor(type); 1885282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t != NULL) { 1886282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t->getCanAddEntries().indexOf(name) >= 0) { 1887282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski canAdd = true; 1888282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1889282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1890282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1891282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!canAdd) { 1892282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Resource does not already exist in overlay at '%s'; use <add-resource> to add.\n", 1893282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(name).string()); 1894282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1895282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1896282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1897282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = getEntry(package, type, name, sourcePos, overlay, params); 1898282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e == NULL) { 1899282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1900282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1901282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1902282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If a parent is explicitly specified, set it. 1903282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bagParent.size() > 0) { 1904282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski e->setParent(bagParent); 1905282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1906282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1907282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((result = e->makeItABag(sourcePos)) != NO_ERROR) { 1908282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return result; 1909282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1910282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1911282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (overlay && replace) { 1912282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return e->emptyBag(sourcePos); 1913282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1914282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return result; 1915282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1916282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1917282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::addBag(const SourcePos& sourcePos, 1918282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& package, 1919282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 1920282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 1921282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& bagParent, 1922282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& bagKey, 1923282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& value, 1924282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<StringPool::entry_style_span>* style, 1925282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config* params, 1926282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool replace, bool isId, const int32_t format) 1927282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1928282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Check for adding entries in other packages... for now we do 1929282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // nothing. We need to do the right thing here to support skinning. 1930282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t rid = mAssets->getIncludedResources() 1931282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .identifierForName(name.string(), name.size(), 1932282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type.string(), type.size(), 1933282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski package.string(), package.size()); 1934282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (rid != 0) { 1935282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 1936282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1937282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1938282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#if 0 1939282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name == String16("left")) { 1940282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Adding bag left: file=%s, line=%d, type=%s\n", 1941282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.file.striing(), sourcePos.line, String8(type).string()); 1942282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1943282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 1944282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = getEntry(package, type, name, sourcePos, replace, params); 1945282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e == NULL) { 1946282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1947282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1948282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1949282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If a parent is explicitly specified, set it. 1950282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bagParent.size() > 0) { 1951282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski e->setParent(bagParent); 1952282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1953282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1954282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool first = e->getBag().indexOfKey(bagKey) < 0; 1955282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = e->addToBag(sourcePos, bagKey, value, style, replace, isId, format); 1956282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err == NO_ERROR && first) { 1957282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mNumLocal++; 1958282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1959282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 1960282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1961282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1962282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::hasBagOrEntry(const String16& package, 1963282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 1964282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name) const 1965282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1966282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // First look for this in the included resources... 1967282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t rid = mAssets->getIncludedResources() 1968282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .identifierForName(name.string(), name.size(), 1969282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type.string(), type.size(), 1970282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski package.string(), package.size()); 1971282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (rid != 0) { 1972282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 1973282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1974282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1975282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mPackages.valueFor(package); 1976282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p != NULL) { 1977282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getTypes().valueFor(type); 1978282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t != NULL) { 1979282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getConfigs().valueFor(name); 1980282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c != NULL) return true; 1981282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1982282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1983282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1984282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 1985282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1986282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1987282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::hasBagOrEntry(const String16& package, 1988282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 1989282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 1990282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config& config) const 1991282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1992282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // First look for this in the included resources... 1993282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t rid = mAssets->getIncludedResources() 1994282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .identifierForName(name.string(), name.size(), 1995282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type.string(), type.size(), 1996282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski package.string(), package.size()); 1997282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (rid != 0) { 1998282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 1999282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2000282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2001282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mPackages.valueFor(package); 2002282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p != NULL) { 2003282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getTypes().valueFor(type); 2004282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t != NULL) { 2005282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getConfigs().valueFor(name); 2006282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c != NULL) { 2007282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = c->getEntries().valueFor(config); 2008282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e != NULL) { 2009282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2010282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2011282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2012282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2013282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2014282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2015282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2016282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2017282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2018282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::hasBagOrEntry(const String16& ref, 2019282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16* defType, 2020282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16* defPackage) 2021282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2022282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 package, type, name; 2023282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!ResTable::expandResourceRef(ref.string(), ref.size(), &package, &type, &name, 2024282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski defType, defPackage ? defPackage:&mAssetsPackage, NULL)) { 2025282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2026282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2027282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return hasBagOrEntry(package, type, name); 2028282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2029282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2030282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::appendComment(const String16& package, 2031282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 2032282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 2033282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& comment, 2034282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool onlyIfEmpty) 2035282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2036282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() <= 0) { 2037282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2038282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2039282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2040282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mPackages.valueFor(package); 2041282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p != NULL) { 2042282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getTypes().valueFor(type); 2043282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t != NULL) { 2044282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getConfigs().valueFor(name); 2045282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c != NULL) { 2046282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c->appendComment(comment, onlyIfEmpty); 2047282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2048282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2049282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2050282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2051282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2052282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2053282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2054282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::appendTypeComment(const String16& package, 2055282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 2056282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 2057282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& comment) 2058282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2059282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() <= 0) { 2060282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2061282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2062282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2063282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mPackages.valueFor(package); 2064282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p != NULL) { 2065282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getTypes().valueFor(type); 2066282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t != NULL) { 2067282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getConfigs().valueFor(name); 2068282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c != NULL) { 2069282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c->appendTypeComment(comment); 2070282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2071282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2072282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2073282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2074282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2075282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2076282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2077282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ResourceTable::canAddEntry(const SourcePos& pos, 2078282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& package, const String16& type, const String16& name) 2079282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2080282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = getType(package, type, pos); 2081282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t != NULL) { 2082282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski t->canAddEntry(name); 2083282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2084282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2085282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2086282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisize_t ResourceTable::size() const { 2087282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mPackages.size(); 2088282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2089282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2090282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisize_t ResourceTable::numLocalResources() const { 2091282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mNumLocal; 2092282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2093282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2094282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::hasResources() const { 2095282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mNumLocal > 0; 2096282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2097282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2098fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskisp<AaptFile> ResourceTable::flatten(Bundle* bundle, const sp<const ResourceFilter>& filter) 2099282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> data = new AaptFile(String8(), AaptGroupEntry(), String8()); 2101fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski status_t err = flatten(bundle, filter, data); 2102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err == NO_ERROR ? data : NULL; 2103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiinline uint32_t ResourceTable::getResId(const sp<Package>& p, 2106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<Type>& t, 2107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t nameId) 2108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return makeResId(p->getAssignedId(), t->getIndex(), nameId); 2110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiuint32_t ResourceTable::getResId(const String16& package, 2113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 2114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 2115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool onlyPublic) const 2116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t id = ResourceIdCache::lookup(package, type, name, onlyPublic); 2118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (id != 0) return id; // cache hit 2119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mPackages.valueFor(package); 2121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p == NULL) return 0; 2122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // First look for this in the included resources... 2124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t specFlags = 0; 2125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t rid = mAssets->getIncludedResources() 2126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .identifierForName(name.string(), name.size(), 2127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type.string(), type.size(), 2128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski package.string(), package.size(), 2129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski &specFlags); 2130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (rid != 0) { 2131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (onlyPublic) { 2132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((specFlags & ResTable_typeSpec::SPEC_PUBLIC) == 0) { 2133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 2134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (Res_INTERNALID(rid)) { 2138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ResourceIdCache::store(package, type, name, onlyPublic, rid); 2139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ResourceIdCache::store(package, type, name, onlyPublic, 2141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_MAKEID(p->getAssignedId()-1, Res_GETTYPE(rid), Res_GETENTRY(rid))); 2142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getTypes().valueFor(type); 2145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) return 0; 2146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getConfigs().valueFor(name); 2147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == NULL) return 0; 2148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t ei = c->getEntryIndex(); 2149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (ei < 0) return 0; 2150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ResourceIdCache::store(package, type, name, onlyPublic, 2152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getResId(p, t, ei)); 2153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiuint32_t ResourceTable::getResId(const String16& ref, 2156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16* defType, 2157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16* defPackage, 2158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char** outErrorMsg, 2159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool onlyPublic) const 2160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 package, type, name; 2162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool refOnlyPublic = true; 2163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!ResTable::expandResourceRef( 2164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ref.string(), ref.size(), &package, &type, &name, 2165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski defType, defPackage ? defPackage:&mAssetsPackage, 2166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outErrorMsg, &refOnlyPublic)) { 2167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Expanding resource: ref=%s\n", 2168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(ref).string())); 2169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Expanding resource: defType=%s\n", 2170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski defType ? String8(*defType).string() : "NULL")); 2171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Expanding resource: defPackage=%s\n", 2172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski defPackage ? String8(*defPackage).string() : "NULL")); 2173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Expanding resource: ref=%s\n", String8(ref).string())); 2174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Expanded resource: p=%s, t=%s, n=%s, res=0\n", 2175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(package).string(), String8(type).string(), 2176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(name).string())); 2177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 2178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t res = getResId(package, type, name, onlyPublic && refOnlyPublic); 2180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Expanded resource: p=%s, t=%s, n=%s, res=%d\n", 2181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(package).string(), String8(type).string(), 2182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(name).string(), res)); 2183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (res == 0) { 2184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outErrorMsg) 2185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outErrorMsg = "No resource found that matches the given name"; 2186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return res; 2188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::isValidResourceName(const String16& s) 2191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* p = s.string(); 2193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool first = true; 2194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (*p) { 2195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((*p >= 'a' && *p <= 'z') 2196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || (*p >= 'A' && *p <= 'Z') 2197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || *p == '_' 2198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || (!first && *p >= '0' && *p <= '9')) { 2199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski first = false; 2200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p++; 2201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::stringToValue(Res_value* outValue, StringPool* pool, 2209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& str, 2210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool preserveSpaces, bool coerceType, 2211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t attrID, 2212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<StringPool::entry_style_span>* style, 2213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16* outStr, void* accessorCookie, 2214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t attrType, const String8* configTypeName, 2215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ConfigDescription* config) 2216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 finalStr; 2218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool res = true; 2220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (style == NULL || style->size() == 0) { 2221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Text is not styled so it can be any type... let's figure it out. 2222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski res = mAssets->getIncludedResources() 2223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .stringToValue(outValue, &finalStr, str.string(), str.size(), preserveSpaces, 2224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski coerceType, attrID, NULL, &mAssetsPackage, this, 2225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski accessorCookie, attrType); 2226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Styled text can only be a string, and while collecting the style 2228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // information we have already processed that string! 2229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->size = sizeof(Res_value); 2230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->res0 = 0; 2231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->dataType = outValue->TYPE_STRING; 2232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->data = 0; 2233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski finalStr = str; 2234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!res) { 2237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outValue->dataType == outValue->TYPE_STRING) { 2241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Should do better merging styles. 2242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pool) { 2243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 configStr; 2244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (config != NULL) { 2245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski configStr = config->toString(); 2246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski configStr = "(null)"; 2248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Adding to pool string style #%d config %s: %s\n", 2250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski style != NULL ? style->size() : 0, 2251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski configStr.string(), String8(finalStr).string())); 2252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (style != NULL && style->size() > 0) { 2253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->data = pool->add(finalStr, *style, configTypeName, config); 2254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->data = pool->add(finalStr, true, configTypeName, config); 2256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Caller will fill this in later. 2259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->data = 0; 2260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outStr) { 2263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outStr = finalStr; 2264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiuint32_t ResourceTable::getCustomResource( 2272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& package, const String16& type, const String16& name) const 2273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("getCustomResource: %s %s %s\n", String8(package).string(), 2275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(type).string(), String8(name).string()); 2276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mPackages.valueFor(package); 2277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p == NULL) return 0; 2278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getTypes().valueFor(type); 2279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) return 0; 2280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getConfigs().valueFor(name); 2281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == NULL) return 0; 2282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t ei = c->getEntryIndex(); 2283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (ei < 0) return 0; 2284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return getResId(p, t, ei); 2285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiuint32_t ResourceTable::getCustomResourceWithCreation( 2288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& package, const String16& type, const String16& name, 2289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool createIfNotFound) 2290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t resId = getCustomResource(package, type, name); 2292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (resId != 0 || !createIfNotFound) { 2293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return resId; 2294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2296f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski if (mAssetsPackage != package) { 2297f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski mCurrentXmlPos.warning("creating resource for external package %s: %s/%s.", 2298f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski String8(package).string(), String8(type).string(), String8(name).string()); 2299f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski mCurrentXmlPos.printf("This will be an error in a future version of AAPT."); 2300f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski } 2301f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 2302f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski String16 value("false"); 2303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t status = addEntry(mCurrentXmlPos, package, type, name, value, NULL, NULL, true); 2304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (status == NO_ERROR) { 2305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resId = getResId(package, type, name); 2306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return resId; 2307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 2309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiuint32_t ResourceTable::getRemappedPackage(uint32_t origPackage) const 2312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return origPackage; 2314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::getAttributeType(uint32_t attrID, uint32_t* outType) 2317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("getAttributeType #%08x\n", attrID); 2319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value value; 2320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (getItemValue(attrID, ResTable_map::ATTR_TYPE, &value)) { 2321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("getAttributeType #%08x (%s): #%08x\n", attrID, 2322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(getEntry(attrID)->getName()).string(), value.data); 2323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outType = value.data; 2324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::getAttributeMin(uint32_t attrID, uint32_t* outMin) 2330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("getAttributeMin #%08x\n", attrID); 2332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value value; 2333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (getItemValue(attrID, ResTable_map::ATTR_MIN, &value)) { 2334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outMin = value.data; 2335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::getAttributeMax(uint32_t attrID, uint32_t* outMax) 2341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("getAttributeMax #%08x\n", attrID); 2343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value value; 2344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (getItemValue(attrID, ResTable_map::ATTR_MAX, &value)) { 2345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outMax = value.data; 2346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiuint32_t ResourceTable::getAttributeL10N(uint32_t attrID) 2352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("getAttributeL10N #%08x\n", attrID); 2354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value value; 2355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (getItemValue(attrID, ResTable_map::ATTR_L10N, &value)) { 2356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return value.data; 2357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ResTable_map::L10N_NOT_REQUIRED; 2359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::getLocalizationSetting() 2362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mBundle->getRequireLocalization(); 2364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ResourceTable::reportError(void* accessorCookie, const char* fmt, ...) 2367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (accessorCookie != NULL && fmt != NULL) { 2369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AccessorCookie* ac = (AccessorCookie*)accessorCookie; 2370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int retval=0; 2371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char buf[1024]; 2372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski va_list ap; 2373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski va_start(ap, fmt); 2374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski retval = vsnprintf(buf, sizeof(buf), fmt, ap); 2375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski va_end(ap); 2376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ac->sourcePos.error("Error: %s (at '%s' with value '%s').\n", 2377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski buf, ac->attr.string(), ac->value.string()); 2378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::getAttributeKeys( 2382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t attrID, Vector<String16>* outKeys) 2383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<const Entry> e = getEntry(attrID); 2385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e != NULL) { 2386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = e->getBag().size(); 2387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 2388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& key = e->getBag().keyAt(i); 2389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (key.size() > 0 && key.string()[0] != '^') { 2390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outKeys->add(key); 2391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::getAttributeEnum( 2399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t attrID, const char16_t* name, size_t nameLen, 2400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value* outValue) 2401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("getAttributeEnum #%08x %s\n", attrID, String8(name, nameLen).string()); 2403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 nameStr(name, nameLen); 2404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<const Entry> e = getEntry(attrID); 2405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e != NULL) { 2406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = e->getBag().size(); 2407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 2408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Comparing %s to %s\n", String8(name, nameLen).string(), 2409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(e->getBag().keyAt(i)).string()); 2410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e->getBag().keyAt(i) == nameStr) { 2411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return getItemValue(attrID, e->getBag().valueAt(i).bagKeyId, outValue); 2412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::getAttributeFlags( 2419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t attrID, const char16_t* name, size_t nameLen, 2420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value* outValue) 2421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->dataType = Res_value::TYPE_INT_HEX; 2423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->data = 0; 2424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("getAttributeFlags #%08x %s\n", attrID, String8(name, nameLen).string()); 2426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 nameStr(name, nameLen); 2427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<const Entry> e = getEntry(attrID); 2428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e != NULL) { 2429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = e->getBag().size(); 2430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* end = name + nameLen; 2432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* pos = name; 2433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (pos < end) { 2434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* start = pos; 2435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (pos < end && *pos != '|') { 2436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pos++; 2437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 nameStr(start, pos-start); 2440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 2441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 2442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Comparing \"%s\" to \"%s\"\n", String8(nameStr).string(), 2443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(e->getBag().keyAt(i)).string()); 2444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e->getBag().keyAt(i) == nameStr) { 2445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value val; 2446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool got = getItemValue(attrID, e->getBag().valueAt(i).bagKeyId, &val); 2447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!got) { 2448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Got value: 0x%08x\n", val.data); 2451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->data |= val.data; 2452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 2453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (i >= N) { 2457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Didn't find this flag identifier. 2458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pos++; 2461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::assignResourceIds() 2469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = mOrderedPackages.size(); 2471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t pi; 2472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t firstError = NO_ERROR; 2473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // First generate all bag attributes and assign indices. 2475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (pi=0; pi<N; pi++) { 2476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mOrderedPackages.itemAt(pi); 2477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p == NULL || p->getTypes().size() == 0) { 2478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Empty, skip! 2479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = p->applyPublicTypeOrder(); 2483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR && firstError == NO_ERROR) { 2484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski firstError = err; 2485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Generate attributes... 2488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = p->getOrderedTypes().size(); 2489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t ti; 2490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (ti=0; ti<N; ti++) { 2491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getOrderedTypes().itemAt(ti); 2492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) { 2493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = t->getOrderedConfigs().size(); 2496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ci=0; ci<N; ci++) { 2497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci); 2498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == NULL) { 2499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = c->getEntries().size(); 2502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ei=0; ei<N; ei++) { 2503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = c->getEntries().valueAt(ei); 2504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e == NULL) { 2505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = e->generateAttributes(this, p->getName()); 2508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR && firstError == NO_ERROR) { 2509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski firstError = err; 2510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const SourcePos unknown(String8("????"), 0); 2516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> attr = p->getType(String16("attr"), unknown); 2517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Assign indices... 2519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (ti=0; ti<N; ti++) { 2520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getOrderedTypes().itemAt(ti); 2521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) { 2522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = t->applyPublicEntryOrder(); 2525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR && firstError == NO_ERROR) { 2526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski firstError = err; 2527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = t->getOrderedConfigs().size(); 2530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski t->setIndex(ti+1); 2531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LOG_ALWAYS_FATAL_IF(ti == 0 && attr != t, 2533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "First type is not attr!"); 2534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ei=0; ei<N; ei++) { 2536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getOrderedConfigs().itemAt(ei); 2537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == NULL) { 2538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c->setEntryIndex(ei); 2541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Assign resource IDs to keys in bags... 2545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (ti=0; ti<N; ti++) { 2546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getOrderedTypes().itemAt(ti); 2547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) { 2548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = t->getOrderedConfigs().size(); 2551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ci=0; ci<N; ci++) { 2552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci); 2553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Ordered config #%d: %p\n", ci, c.get()); 2554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = c->getEntries().size(); 2555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ei=0; ei<N; ei++) { 2556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = c->getEntries().valueAt(ei); 2557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e == NULL) { 2558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = e->assignResourceIds(this, p->getName()); 2561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR && firstError == NO_ERROR) { 2562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski firstError = err; 2563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return firstError; 2569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::addSymbols(const sp<AaptSymbols>& outSymbols) { 2572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = mOrderedPackages.size(); 2573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t pi; 2574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (pi=0; pi<N; pi++) { 2576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mOrderedPackages.itemAt(pi); 2577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p->getTypes().size() == 0) { 2578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Empty, skip! 2579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = p->getOrderedTypes().size(); 2583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t ti; 2584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (ti=0; ti<N; ti++) { 2586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getOrderedTypes().itemAt(ti); 2587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) { 2588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = t->getOrderedConfigs().size(); 2591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> typeSymbols; 2592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeSymbols = outSymbols->addNestedSymbol(String8(t->getName()), t->getPos()); 2593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ci=0; ci<N; ci++) { 2594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci); 2595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == NULL) { 2596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t rid = getResId(p, t, ci); 2599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (rid == 0) { 2600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 2601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (Res_GETPACKAGE(rid) == (size_t)(p->getAssignedId()-1)) { 2603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeSymbols->addSymbol(String8(c->getName()), rid, c->getPos()); 2604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment(c->getComment()); 2606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeSymbols->appendComment(String8(c->getName()), comment, c->getPos()); 26078ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski //printf("Type symbol [%08x] %s comment: %s\n", rid, 26088ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski // String8(c->getName()).string(), String8(comment).string()); 2609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski comment = c->getTypeComment(); 2610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeSymbols->appendTypeComment(String8(c->getName()), comment); 2611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#if 0 2613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("**** NO MATCH: 0x%08x vs 0x%08x\n", 2614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_GETPACKAGE(rid), p->getAssignedId()); 2615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 2616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 2621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid 2625a01a9374fd386f3a8773528d7a49bc5315492dffAdam LesinskiResourceTable::addLocalization(const String16& name, const String8& locale, const SourcePos& src) 2626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2627a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski mLocalizations[name][locale] = src; 2628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/*! 2632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Flag various sorts of localization problems. '+' indicates checks already implemented; 2633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * '-' indicates checks that will be implemented in the future. 2634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 2635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * + A localized string for which no default-locale version exists => warning 2636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * + A string for which no version in an explicitly-requested locale exists => warning 2637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * + A localized translation of an translateable="false" string => warning 2638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * - A localized string not provided in every locale used by the table 2639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 2640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t 2641282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiResourceTable::validateLocalizations(void) 2642282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2643282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = NO_ERROR; 2644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String8 defaultLocale; 2645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2646282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // For all strings... 2647a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski for (map<String16, map<String8, SourcePos> >::iterator nameIter = mLocalizations.begin(); 2648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nameIter != mLocalizations.end(); 2649282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nameIter++) { 2650a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski const map<String8, SourcePos>& configSrcMap = nameIter->second; 2651282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Look for strings with no default localization 2653a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski if (configSrcMap.count(defaultLocale) == 0) { 2654a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski SourcePos().warning("string '%s' has no default translation.", 2655a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski String8(nameIter->first).string()); 2656a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski if (mBundle->getVerbose()) { 2657a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski for (map<String8, SourcePos>::const_iterator locales = configSrcMap.begin(); 2658a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski locales != configSrcMap.end(); 2659a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski locales++) { 2660a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski locales->second.printf("locale %s found", locales->first.string()); 2661a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski } 2662282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2663282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // !!! TODO: throw an error here in some circumstances 2664282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2665282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Check that all requested localizations are present for this string 2667fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (mBundle->getConfigurations().size() > 0 && mBundle->getRequireLocalization()) { 2668fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const char* allConfigs = mBundle->getConfigurations().string(); 2669282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* start = allConfigs; 2670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* comma; 2671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2672a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski set<String8> missingConfigs; 2673a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski AaptLocaleValue locale; 2674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski do { 2675282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 config; 2676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski comma = strchr(start, ','); 2677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comma != NULL) { 2678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.setTo(start, comma - start); 2679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski start = comma + 1; 2680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2681282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.setTo(start); 2682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2684a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski if (!locale.initFromFilterString(config)) { 2685a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski continue; 2686a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski } 2687a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski 2688a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin // don't bother with the pseudolocale "en_XA" or "ar_XB" 2689a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin if (config != "en_XA" && config != "ar_XB") { 2690a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski if (configSrcMap.find(config) == configSrcMap.end()) { 2691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // okay, no specific localization found. it's possible that we are 2692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // requiring a specific regional localization [e.g. de_DE] but there is an 2693282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // available string in the generic language localization [e.g. de]; 2694282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // consider that string to have fulfilled the localization requirement. 2695282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 region(config.string(), 2); 2696a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski if (configSrcMap.find(region) == configSrcMap.end() && 2697a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski configSrcMap.count(defaultLocale) == 0) { 2698a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski missingConfigs.insert(config); 2699282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2700282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2701282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2702a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski } while (comma != NULL); 2703a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski 2704a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski if (!missingConfigs.empty()) { 2705a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski String8 configStr; 2706a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski for (set<String8>::iterator iter = missingConfigs.begin(); 2707a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski iter != missingConfigs.end(); 2708a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski iter++) { 2709a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski configStr.appendFormat(" %s", iter->string()); 2710a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski } 2711a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski SourcePos().warning("string '%s' is missing %u required localizations:%s", 2712a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski String8(nameIter->first).string(), 2713a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski (unsigned int)missingConfigs.size(), 2714a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski configStr.string()); 2715a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski } 2716282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2717282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2718282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2719282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 2720282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2721282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2722fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskistatus_t ResourceTable::flatten(Bundle* bundle, const sp<const ResourceFilter>& filter, const sp<AaptFile>& dest) 2723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2724282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ConfigDescription nullConfig; 2725282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2726282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = mOrderedPackages.size(); 2727282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t pi; 2728282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2729282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const static String16 mipmap16("mipmap"); 2730282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2731282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool useUTF8 = !bundle->getUTF16StringsOption(); 2732282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2733de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski // The libraries this table references. 2734de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski Vector<sp<Package> > libraryPackages; 2735de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 2736282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Iterate through all data, collecting all values (strings, 2737282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // references, etc). 2738282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski StringPool valueStrings(useUTF8); 2739282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<sp<Entry> > allEntries; 2740282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (pi=0; pi<N; pi++) { 2741282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mOrderedPackages.itemAt(pi); 2742282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p->getTypes().size() == 0) { 2743de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski // Empty, this is an imported package being used as 2744de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski // a shared library. We do not flatten this package. 2745de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski if (p->getAssignedId() != 0x01 && p->getName() != String16("android")) { 2746de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski // This is not the base Android package, and it is a library 2747de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski // so we must add a reference to the library when flattening. 2748de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski libraryPackages.add(p); 2749de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski } 2750282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2751de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski } else if (p->getAssignedId() == 0x00) { 2752de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski if (!bundle->getBuildSharedLibrary()) { 2753de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski fprintf(stderr, "ERROR: Package %s can not have ID=0x00 unless building a shared library.", 2754de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski String8(p->getName()).string()); 2755de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski return UNKNOWN_ERROR; 2756de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski } 2757de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski // If this is a shared library, we also include ourselves as an entry. 2758de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski libraryPackages.add(p); 2759282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2760282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2761282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski StringPool typeStrings(useUTF8); 2762282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski StringPool keyStrings(useUTF8); 2763282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2764282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = p->getOrderedTypes().size(); 2765282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ti=0; ti<N; ti++) { 2766282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getOrderedTypes().itemAt(ti); 2767282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) { 2768282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeStrings.add(String16("<empty>"), false); 2769282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2770282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2771282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 typeName(t->getName()); 2772282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeStrings.add(typeName, false); 2773282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2774282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // This is a hack to tweak the sorting order of the final strings, 2775282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // to put stuff that is generally not language-specific first. 2776282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 configTypeName(typeName); 2777282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (configTypeName == "drawable" || configTypeName == "layout" 2778282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || configTypeName == "color" || configTypeName == "anim" 2779282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || configTypeName == "interpolator" || configTypeName == "animator" 2780282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || configTypeName == "xml" || configTypeName == "menu" 2781282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || configTypeName == "mipmap" || configTypeName == "raw") { 2782282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski configTypeName = "1complex"; 2783282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2784282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski configTypeName = "2value"; 2785282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2786282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2787282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool filterable = (typeName != mipmap16); 2788282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2789282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = t->getOrderedConfigs().size(); 2790282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ci=0; ci<N; ci++) { 2791282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci); 2792282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == NULL) { 2793282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2794282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2795282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = c->getEntries().size(); 2796282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ei=0; ei<N; ei++) { 2797282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ConfigDescription config = c->getEntries().keyAt(ei); 2798fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (filterable && !filter->match(config)) { 2799282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2800282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2801282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = c->getEntries().valueAt(ei); 2802282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e == NULL) { 2803282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2804282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2805282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski e->setNameIndex(keyStrings.add(e->getName(), true)); 2806282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2807282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If this entry has no values for other configs, 2808282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // and is the default config, then it is special. Otherwise 2809282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // we want to add it with the config info. 2810282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ConfigDescription* valueConfig = NULL; 2811282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (N != 1 || config == nullConfig) { 2812282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski valueConfig = &config; 2813282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2814282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2815282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = e->prepareFlatten(&valueStrings, this, 2816282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski &configTypeName, &config); 2817282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 2818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 2819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2820282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski allEntries.add(e); 2821282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2822282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2823282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2824282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2825282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p->setTypeStrings(typeStrings.createStringBlock()); 2826282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p->setKeyStrings(keyStrings.createStringBlock()); 2827282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2828282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2829282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getOutputAPKFile() != NULL) { 2830282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Now we want to sort the value strings for better locality. This will 2831282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // cause the positions of the strings to change, so we need to go back 2832282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // through out resource entries and update them accordingly. Only need 2833282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // to do this if actually writing the output file. 2834282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski valueStrings.sortByConfig(); 2835282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (pi=0; pi<allEntries.size(); pi++) { 2836282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski allEntries[pi]->remapStringValue(&valueStrings); 2837282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2838282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2839282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2840282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t strAmt = 0; 2841de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 2842282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Now build the array of package chunks. 2843282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<sp<AaptFile> > flatPackages; 2844282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (pi=0; pi<N; pi++) { 2845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mOrderedPackages.itemAt(pi); 2846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p->getTypes().size() == 0) { 2847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Empty, skip! 2848282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2849282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2850282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2851282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = p->getTypeStrings().size(); 2852282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2853282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t baseSize = sizeof(ResTable_package); 2854282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2855282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Start the package data. 2856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> data = new AaptFile(String8(), AaptGroupEntry(), String8()); 2857282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_package* header = (ResTable_package*)data->editData(baseSize); 2858282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (header == NULL) { 2859282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: out of memory creating ResTable_package\n"); 2860282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_MEMORY; 2861282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2862282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memset(header, 0, sizeof(*header)); 2863282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header->header.type = htods(RES_TABLE_PACKAGE_TYPE); 2864282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header->header.headerSize = htods(sizeof(*header)); 2865282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header->id = htodl(p->getAssignedId()); 2866282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski strcpy16_htod(header->name, p->getName().string()); 2867282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2868282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Write the string blocks. 2869282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t typeStringsStart = data->getSize(); 2870282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> strFile = p->getTypeStringsData(); 2871282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t amt = data->writeData(strFile->getData(), strFile->getSize()); 2872282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #if PRINT_STRING_METRICS 2873282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "**** type strings: %d\n", amt); 2874282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #endif 2875282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski strAmt += amt; 2876282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (amt < 0) { 2877282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return amt; 2878282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2879282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t keyStringsStart = data->getSize(); 2880282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski strFile = p->getKeyStringsData(); 2881282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski amt = data->writeData(strFile->getData(), strFile->getSize()); 2882282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #if PRINT_STRING_METRICS 2883282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "**** key strings: %d\n", amt); 2884282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #endif 2885282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski strAmt += amt; 2886282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (amt < 0) { 2887282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return amt; 2888282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2889282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2890fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski status_t err = flattenLibraryTable(data, libraryPackages); 2891de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski if (err != NO_ERROR) { 2892de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski fprintf(stderr, "ERROR: failed to write library table\n"); 2893de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski return err; 2894de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski } 2895de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 2896282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Build the type chunks inside of this package. 2897282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ti=0; ti<N; ti++) { 2898282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Retrieve them in the same order as the type string block. 2899282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 2900282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 typeName(p->getTypeStrings().stringAt(ti, &len)); 2901282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getTypes().valueFor(typeName); 2902282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LOG_ALWAYS_FATAL_IF(t == NULL && typeName != String16("<empty>"), 2903282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Type name %s not found", 2904282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(typeName).string()); 2905282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2906282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool filterable = (typeName != mipmap16); 2907282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2908282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = t != NULL ? t->getOrderedConfigs().size() : 0; 2909282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2910282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Until a non-NO_ENTRY value has been written for a resource, 2911282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // that resource is invalid; validResources[i] represents 2912282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the item at t->getOrderedConfigs().itemAt(i). 2913282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<bool> validResources; 2914282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski validResources.insertAt(false, 0, N); 2915282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2916282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // First write the typeSpec chunk, containing information about 2917282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // each resource entry in this type. 2918282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 2919282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t typeSpecSize = sizeof(ResTable_typeSpec) + sizeof(uint32_t)*N; 2920282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t typeSpecStart = data->getSize(); 2921282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_typeSpec* tsHeader = (ResTable_typeSpec*) 2922282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (((uint8_t*)data->editData(typeSpecStart+typeSpecSize)) + typeSpecStart); 2923282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tsHeader == NULL) { 2924282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: out of memory creating ResTable_typeSpec\n"); 2925282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_MEMORY; 2926282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2927282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memset(tsHeader, 0, sizeof(*tsHeader)); 2928282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tsHeader->header.type = htods(RES_TABLE_TYPE_SPEC_TYPE); 2929282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tsHeader->header.headerSize = htods(sizeof(*tsHeader)); 2930282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tsHeader->header.size = htodl(typeSpecSize); 2931282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tsHeader->id = ti+1; 2932282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tsHeader->entryCount = htodl(N); 2933282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2934282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t* typeSpecFlags = (uint32_t*) 2935282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (((uint8_t*)data->editData()) 2936282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski + typeSpecStart + sizeof(ResTable_typeSpec)); 2937282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memset(typeSpecFlags, 0, sizeof(uint32_t)*N); 2938282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2939282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ei=0; ei<N; ei++) { 2940282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> cl = t->getOrderedConfigs().itemAt(ei); 2941282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (cl->getPublic()) { 2942282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeSpecFlags[ei] |= htodl(ResTable_typeSpec::SPEC_PUBLIC); 2943282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2944282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t CN = cl->getEntries().size(); 2945282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ci=0; ci<CN; ci++) { 2946fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (filterable && !filter->match(cl->getEntries().keyAt(ci))) { 2947282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2948282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2949282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t cj=ci+1; cj<CN; cj++) { 2950fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (filterable && !filter->match(cl->getEntries().keyAt(cj))) { 2951282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2952282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2953282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeSpecFlags[ei] |= htodl( 2954282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski cl->getEntries().keyAt(ci).diff(cl->getEntries().keyAt(cj))); 2955282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2956282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2957282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2958282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2959282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2960282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // We need to write one type chunk for each configuration for 2961282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // which we have entries in this type. 2962282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NC = t->getUniqueConfigs().size(); 2963282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2964282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t typeSize = sizeof(ResTable_type) + sizeof(uint32_t)*N; 2965282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2966282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ci=0; ci<NC; ci++) { 2967282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ConfigDescription config = t->getUniqueConfigs().itemAt(ci); 2968282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2969282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Writing config %d config: imsi:%d/%d lang:%c%c cnt:%c%c " 2970282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d " 2971282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "sw%ddp w%ddp h%ddp dir:%d\n", 2972282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ti+1, 2973282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.mcc, config.mnc, 2974282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.language[0] ? config.language[0] : '-', 2975282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.language[1] ? config.language[1] : '-', 2976282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.country[0] ? config.country[0] : '-', 2977282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.country[1] ? config.country[1] : '-', 2978282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.orientation, 2979282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.uiMode, 2980282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.touchscreen, 2981282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.density, 2982282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.keyboard, 2983282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.inputFlags, 2984282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.navigation, 2985282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.screenWidth, 2986282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.screenHeight, 2987282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.smallestScreenWidthDp, 2988282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.screenWidthDp, 2989282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.screenHeightDp, 2990282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.layoutDirection)); 2991282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2992fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (filterable && !filter->match(config)) { 2993282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2994282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2995282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2996282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t typeStart = data->getSize(); 2997282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2998282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_type* tHeader = (ResTable_type*) 2999282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (((uint8_t*)data->editData(typeStart+typeSize)) + typeStart); 3000282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tHeader == NULL) { 3001282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: out of memory creating ResTable_type\n"); 3002282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_MEMORY; 3003282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3004282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3005282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memset(tHeader, 0, sizeof(*tHeader)); 3006282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->header.type = htods(RES_TABLE_TYPE_TYPE); 3007282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->header.headerSize = htods(sizeof(*tHeader)); 3008282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->id = ti+1; 3009282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->entryCount = htodl(N); 3010282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->entriesStart = htodl(typeSize); 3011282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config = config; 3012282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Writing type %d config: imsi:%d/%d lang:%c%c cnt:%c%c " 3013282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d " 3014282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "sw%ddp w%ddp h%ddp dir:%d\n", 3015282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ti+1, 3016282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.mcc, tHeader->config.mnc, 3017282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.language[0] ? tHeader->config.language[0] : '-', 3018282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.language[1] ? tHeader->config.language[1] : '-', 3019282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.country[0] ? tHeader->config.country[0] : '-', 3020282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.country[1] ? tHeader->config.country[1] : '-', 3021282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.orientation, 3022282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.uiMode, 3023282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.touchscreen, 3024282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.density, 3025282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.keyboard, 3026282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.inputFlags, 3027282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.navigation, 3028282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.screenWidth, 3029282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.screenHeight, 3030282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.smallestScreenWidthDp, 3031282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.screenWidthDp, 3032282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.screenHeightDp, 3033282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.layoutDirection)); 3034282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.swapHtoD(); 3035282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3036282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Build the entries inside of this type. 3037282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ei=0; ei<N; ei++) { 3038282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> cl = t->getOrderedConfigs().itemAt(ei); 3039282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = cl->getEntries().valueFor(config); 3040282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3041282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Set the offset for this entry in its type. 3042282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t* index = (uint32_t*) 3043282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (((uint8_t*)data->editData()) 3044282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski + typeStart + sizeof(ResTable_type)); 3045282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e != NULL) { 3046282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski index[ei] = htodl(data->getSize()-typeStart-typeSize); 3047282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3048282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Create the entry. 3049282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t amt = e->flatten(bundle, data, cl->getPublic()); 3050282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (amt < 0) { 3051282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return amt; 3052282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3053282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski validResources.editItemAt(ei) = true; 3054282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 3055282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski index[ei] = htodl(ResTable_type::NO_ENTRY); 3056282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3057282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3058282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3059282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Fill in the rest of the type information. 3060282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader = (ResTable_type*) 3061282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (((uint8_t*)data->editData()) + typeStart); 3062282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->header.size = htodl(data->getSize()-typeStart); 3063282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3064282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3065cd28bd37ea2d88dd72930f032ca73daaad5744b4Ying Wang bool missing_entry = false; 3066cd28bd37ea2d88dd72930f032ca73daaad5744b4Ying Wang const char* log_prefix = bundle->getErrorOnMissingConfigEntry() ? 3067cd28bd37ea2d88dd72930f032ca73daaad5744b4Ying Wang "error" : "warning"; 3068282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i = 0; i < N; ++i) { 3069282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!validResources[i]) { 3070282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getOrderedConfigs().itemAt(i); 3071f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski fprintf(stderr, "%s: no entries written for %s/%s (0x%08x)\n", log_prefix, 3072f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski String8(typeName).string(), String8(c->getName()).string(), 3073f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski Res_MAKEID(p->getAssignedId() - 1, ti, i)); 3074cd28bd37ea2d88dd72930f032ca73daaad5744b4Ying Wang missing_entry = true; 3075282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3076282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3077cd28bd37ea2d88dd72930f032ca73daaad5744b4Ying Wang if (bundle->getErrorOnMissingConfigEntry() && missing_entry) { 3078cd28bd37ea2d88dd72930f032ca73daaad5744b4Ying Wang fprintf(stderr, "Error: Missing entries, quit!\n"); 3079cd28bd37ea2d88dd72930f032ca73daaad5744b4Ying Wang return NOT_ENOUGH_DATA; 3080cd28bd37ea2d88dd72930f032ca73daaad5744b4Ying Wang } 3081282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3082282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3083282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Fill in the rest of the package information. 3084282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header = (ResTable_package*)data->editData(); 3085282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header->header.size = htodl(data->getSize()); 3086282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header->typeStrings = htodl(typeStringsStart); 3087282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header->lastPublicType = htodl(p->getTypeStrings().size()); 3088282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header->keyStrings = htodl(keyStringsStart); 3089282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header->lastPublicKey = htodl(p->getKeyStrings().size()); 3090282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3091282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski flatPackages.add(data); 3092282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3093282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3094282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // And now write out the final chunks. 3095282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t dataStart = dest->getSize(); 3096282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3097282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 3098282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // blah 3099282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_header header; 3100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memset(&header, 0, sizeof(header)); 3101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header.header.type = htods(RES_TABLE_TYPE); 3102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header.header.headerSize = htods(sizeof(header)); 3103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header.packageCount = htodl(flatPackages.size()); 3104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = dest->writeData(&header, sizeof(header)); 3105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: out of memory creating ResTable_header\n"); 3107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t strStart = dest->getSize(); 3112fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski status_t err = valueStrings.writeStringBlock(dest); 3113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t amt = (dest->getSize()-strStart); 3118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski strAmt += amt; 3119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #if PRINT_STRING_METRICS 3120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "**** value strings: %d\n", amt); 3121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "**** total strings: %d\n", strAmt); 3122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #endif 3123de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 3124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (pi=0; pi<flatPackages.size(); pi++) { 3125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = dest->writeData(flatPackages[pi]->getData(), 3126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski flatPackages[pi]->getSize()); 3127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: out of memory creating package chunk for ResTable_header\n"); 3129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_header* header = (ResTable_header*) 3134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (((uint8_t*)dest->getData()) + dataStart); 3135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header->header.size = htodl(dest->getSize() - dataStart); 3136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(aout << "Resource table:" 3138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski << HexDump(dest->getData(), dest->getSize()) << endl); 3139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #if PRINT_STRING_METRICS 3141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "**** total resource table size: %d / %d%% strings\n", 3142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest->getSize(), (strAmt*100)/dest->getSize()); 3143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #endif 3144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3148de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinskistatus_t ResourceTable::flattenLibraryTable(const sp<AaptFile>& dest, const Vector<sp<Package> >& libs) { 3149de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski // Write out the library table if necessary 3150de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski if (libs.size() > 0) { 3151de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski NOISY(fprintf(stderr, "Writing library reference table\n")); 3152de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 3153de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski const size_t libStart = dest->getSize(); 3154de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski const size_t count = libs.size(); 3155de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski ResTable_lib_header* libHeader = (ResTable_lib_header*) dest->editDataInRange(libStart, sizeof(ResTable_lib_header)); 3156de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 3157de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski memset(libHeader, 0, sizeof(*libHeader)); 3158de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski libHeader->header.type = htods(RES_TABLE_LIBRARY_TYPE); 3159de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski libHeader->header.headerSize = htods(sizeof(*libHeader)); 3160de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski libHeader->header.size = htodl(sizeof(*libHeader) + (sizeof(ResTable_lib_entry) * count)); 3161de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski libHeader->count = htodl(count); 3162de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 3163de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski // Write the library entries 3164de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski for (size_t i = 0; i < count; i++) { 3165de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski const size_t entryStart = dest->getSize(); 3166de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski sp<Package> libPackage = libs[i]; 3167de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski NOISY(fprintf(stderr, " Entry %s -> 0x%02x\n", 3168de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski String8(libPackage->getName()).string(), 3169de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski (uint8_t)libPackage->getAssignedId())); 3170de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 3171de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski ResTable_lib_entry* entry = (ResTable_lib_entry*) dest->editDataInRange(entryStart, sizeof(ResTable_lib_entry)); 3172de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski memset(entry, 0, sizeof(*entry)); 3173de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski entry->packageId = htodl(libPackage->getAssignedId()); 3174de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski strcpy16_htod(entry->packageName, libPackage->getName().string()); 3175de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski } 3176de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski } 3177de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski return NO_ERROR; 3178de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski} 3179de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 3180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ResourceTable::writePublicDefinitions(const String16& package, FILE* fp) 3181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, 3183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "<!-- This file contains <public> resource definitions for all\n" 3184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " resources that were generated from the source data. -->\n" 3185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "\n" 3186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "<resources>\n"); 3187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski writePublicDefinitions(package, fp, true); 3189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski writePublicDefinitions(package, fp, false); 3190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, 3192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "\n" 3193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "</resources>\n"); 3194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ResourceTable::writePublicDefinitions(const String16& package, FILE* fp, bool pub) 3197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool didHeader = false; 3199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> pkg = mPackages.valueFor(package); 3201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pkg != NULL) { 3202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NT = pkg->getOrderedTypes().size(); 3203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<NT; i++) { 3204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = pkg->getOrderedTypes().itemAt(i); 3205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) { 3206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 3207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool didType = false; 3210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NC = t->getOrderedConfigs().size(); 3212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t j=0; j<NC; j++) { 3213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getOrderedConfigs().itemAt(j); 3214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == NULL) { 3215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 3216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c->getPublic() != pub) { 3219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 3220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!didType) { 3223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "\n"); 3224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski didType = true; 3225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!didHeader) { 3227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pub) { 3228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp," <!-- PUBLIC SECTION. These resources have been declared public.\n"); 3229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp," Changes to these definitions will break binary compatibility. -->\n\n"); 3230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 3231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp," <!-- PRIVATE SECTION. These resources have not been declared public.\n"); 3232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp," You can make them public my moving these lines into a file in res/values. -->\n\n"); 3233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski didHeader = true; 3235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!pub) { 3237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NE = c->getEntries().size(); 3238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t k=0; k<NE; k++) { 3239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const SourcePos& pos = c->getEntries().valueAt(k)->getPos(); 3240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pos.file != "") { 3241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp," <!-- Declared at %s:%d -->\n", 3242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pos.file.string(), pos.line); 3243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, " <public type=\"%s\" name=\"%s\" id=\"0x%08x\" />\n", 3247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(t->getName()).string(), 3248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(c->getName()).string(), 3249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getResId(pkg, t, c->getEntryIndex())); 3250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3255282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiResourceTable::Item::Item(const SourcePos& _sourcePos, 3256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool _isId, 3257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& _value, 3258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<StringPool::entry_style_span>* _style, 3259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t _format) 3260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski : sourcePos(_sourcePos) 3261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , isId(_isId) 3262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , value(_value) 3263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , format(_format) 3264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , bagKeyId(0) 3265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , evaluating(false) 3266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (_style) { 3268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski style = *_style; 3269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Entry::makeItABag(const SourcePos& sourcePos) 3273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mType == TYPE_BAG) { 3275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mType == TYPE_UNKNOWN) { 3278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mType = TYPE_BAG; 3279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Resource entry %s is already defined as a single item.\n" 3282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s:%d: Originally defined here.\n", 3283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string(), 3284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mItem.sourcePos.file.string(), mItem.sourcePos.line); 3285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Entry::setItem(const SourcePos& sourcePos, 3289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& value, 3290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<StringPool::entry_style_span>* style, 3291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t format, 3292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool overwrite) 3293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Item item(sourcePos, false, value, style); 3295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mType == TYPE_BAG) { 3297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Item& item(mBag.valueAt(0)); 3298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Resource entry %s is already defined as a bag.\n" 3299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s:%d: Originally defined here.\n", 3300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string(), 3301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski item.sourcePos.file.string(), item.sourcePos.line); 3302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ( (mType != TYPE_UNKNOWN) && (overwrite == false) ) { 3305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Resource entry %s is already defined.\n" 3306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s:%d: Originally defined here.\n", 3307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string(), 3308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mItem.sourcePos.file.string(), mItem.sourcePos.line); 3309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mType = TYPE_ITEM; 3313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mItem = item; 3314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mItemFormat = format; 3315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Entry::addToBag(const SourcePos& sourcePos, 3319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& key, const String16& value, 3320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<StringPool::entry_style_span>* style, 3321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool replace, bool isId, int32_t format) 3322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = makeItABag(sourcePos); 3324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Item item(sourcePos, isId, value, style, format); 3329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // XXX NOTE: there is an error if you try to have a bag with two keys, 3331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // one an attr and one an id, with the same name. Not something we 3332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // currently ever have to worry about. 3333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t origKey = mBag.indexOfKey(key); 3334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (origKey >= 0) { 3335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!replace) { 3336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Item& item(mBag.valueAt(origKey)); 3337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Resource entry %s already has bag item %s.\n" 3338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s:%d: Originally defined here.\n", 3339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string(), String8(key).string(), 3340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski item.sourcePos.file.string(), item.sourcePos.line); 3341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Replacing %s with %s\n", 3344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(mBag.valueFor(key).value).string(), String8(value).string()); 3345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mBag.replaceValueFor(key, item); 3346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mBag.add(key, item); 3349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Entry::emptyBag(const SourcePos& sourcePos) 3353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = makeItABag(sourcePos); 3355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mBag.clear(); 3360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Entry::generateAttributes(ResourceTable* table, 3364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& package) 3365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 attr16("attr"); 3367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 id16("id"); 3368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = mBag.size(); 3369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 3370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& key = mBag.keyAt(i); 3371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Item& it = mBag.valueAt(i); 3372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (it.isId) { 3373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!table->hasBagOrEntry(key, &id16, &package)) { 3374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 value("false"); 3375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = table->addEntry(SourcePos(String8("<generated>"), 0), package, 3376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski id16, key, value); 3377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (!table->hasBagOrEntry(key, &attr16, &package)) { 3382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#if 1 3384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// fprintf(stderr, "ERROR: Bag attribute '%s' has not been defined.\n", 3385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// String8(key).string()); 3386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// const Item& item(mBag.valueAt(i)); 3387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// fprintf(stderr, "Referenced from file %s line %d\n", 3388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// item.sourcePos.file.string(), item.sourcePos.line); 3389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// return UNKNOWN_ERROR; 3390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#else 3391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char numberStr[16]; 3392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sprintf(numberStr, "%d", ResTable_map::TYPE_ANY); 3393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = table->addBag(SourcePos("<generated>", 0), package, 3394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr16, key, String16(""), 3395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16("^type"), 3396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16(numberStr), NULL, NULL); 3397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 3401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Entry::assignResourceIds(ResourceTable* table, 3407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& package) 3408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasErrors = false; 3410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mType == TYPE_BAG) { 3412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* errorMsg; 3413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 style16("style"); 3414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 attr16("attr"); 3415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 id16("id"); 3416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentId = 0; 3417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mParent.size() > 0) { 3418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentId = table->getResId(mParent, &style16, NULL, &errorMsg); 3419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mParentId == 0) { 3420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mPos.error("Error retrieving parent for item: %s '%s'.\n", 3421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski errorMsg, String8(mParent).string()); 3422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 3423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = mBag.size(); 3426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 3427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& key = mBag.keyAt(i); 3428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Item& it = mBag.editValueAt(i); 3429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it.bagKeyId = table->getResId(key, 3430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it.isId ? &id16 : &attr16, NULL, &errorMsg); 3431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Bag key of %s: #%08x\n", String8(key).string(), it.bagKeyId); 3432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (it.bagKeyId == 0) { 3433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it.sourcePos.error("Error: %s: %s '%s'.\n", errorMsg, 3434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(it.isId ? id16 : attr16).string(), 3435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(key).string()); 3436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 3437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return hasErrors ? UNKNOWN_ERROR : NO_ERROR; 3441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Entry::prepareFlatten(StringPool* strings, ResourceTable* table, 3444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String8* configTypeName, const ConfigDescription* config) 3445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mType == TYPE_ITEM) { 3447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Item& it = mItem; 3448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AccessorCookie ac(it.sourcePos, String8(mName), String8(it.value)); 3449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!table->stringToValue(&it.parsedValue, strings, 3450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it.value, false, true, 0, 3451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski &it.style, NULL, &ac, mItemFormat, 3452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski configTypeName, config)) { 3453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (mType == TYPE_BAG) { 3456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = mBag.size(); 3457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 3458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& key = mBag.keyAt(i); 3459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Item& it = mBag.editValueAt(i); 3460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AccessorCookie ac(it.sourcePos, String8(key), String8(it.value)); 3461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!table->stringToValue(&it.parsedValue, strings, 3462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it.value, false, true, it.bagKeyId, 3463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski &it.style, NULL, &ac, it.format, 3464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski configTypeName, config)) { 3465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 3469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mPos.error("Error: entry %s is not a single item or a bag.\n", 3470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string()); 3471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Entry::remapStringValue(StringPool* strings) 3477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mType == TYPE_ITEM) { 3479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Item& it = mItem; 3480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (it.parsedValue.dataType == Res_value::TYPE_STRING) { 3481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it.parsedValue.data = strings->mapOriginalPosToNewPos(it.parsedValue.data); 3482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (mType == TYPE_BAG) { 3484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = mBag.size(); 3485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 3486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Item& it = mBag.editValueAt(i); 3487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (it.parsedValue.dataType == Res_value::TYPE_STRING) { 3488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it.parsedValue.data = strings->mapOriginalPosToNewPos(it.parsedValue.data); 3489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 3492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mPos.error("Error: entry %s is not a single item or a bag.\n", 3493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string()); 3494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskissize_t ResourceTable::Entry::flatten(Bundle* bundle, const sp<AaptFile>& data, bool isPublic) 3500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t amt = 0; 3502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_entry header; 3503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memset(&header, 0, sizeof(header)); 3504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header.size = htods(sizeof(header)); 3505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const type ty = this != NULL ? mType : TYPE_ITEM; 3506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (this != NULL) { 3507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (ty == TYPE_BAG) { 3508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header.flags |= htods(header.FLAG_COMPLEX); 3509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (isPublic) { 3511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header.flags |= htods(header.FLAG_PUBLIC); 3512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header.key.index = htodl(mNameIndex); 3514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (ty != TYPE_BAG) { 3516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = data->writeData(&header, sizeof(header)); 3517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: out of memory creating ResTable_entry\n"); 3519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Item& it = mItem; 3523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value par; 3524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memset(&par, 0, sizeof(par)); 3525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski par.size = htods(it.parsedValue.size); 3526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski par.dataType = it.parsedValue.dataType; 3527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski par.res0 = it.parsedValue.res0; 3528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski par.data = htodl(it.parsedValue.data); 3529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #if 0 3530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Writing item (%s): type=%d, data=0x%x, res0=0x%x\n", 3531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string(), it.parsedValue.dataType, 3532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it.parsedValue.data, par.res0); 3533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #endif 3534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = data->writeData(&par, it.parsedValue.size); 3535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: out of memory creating Res_value\n"); 3537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski amt += it.parsedValue.size; 3540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 3541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t N = mBag.size(); 3542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 3543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Create correct ordering of items. 3544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski KeyedVector<uint32_t, const Item*> items; 3545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 3546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Item& it = mBag.valueAt(i); 3547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski items.add(it.bagKeyId, &it); 3548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski N = items.size(); 3550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_map_entry mapHeader; 3552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memcpy(&mapHeader, &header, sizeof(header)); 3553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mapHeader.size = htods(sizeof(mapHeader)); 3554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mapHeader.parent.ident = htodl(mParentId); 3555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mapHeader.count = htodl(N); 3556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = data->writeData(&mapHeader, sizeof(mapHeader)); 3557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: out of memory creating ResTable_entry\n"); 3559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 3563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Item& it = *items.valueAt(i); 3564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_map map; 3565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski map.name.ident = htodl(it.bagKeyId); 3566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski map.value.size = htods(it.parsedValue.size); 3567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski map.value.dataType = it.parsedValue.dataType; 3568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski map.value.res0 = it.parsedValue.res0; 3569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski map.value.data = htodl(it.parsedValue.data); 3570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = data->writeData(&map, sizeof(map)); 3571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: out of memory creating Res_value\n"); 3573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski amt += sizeof(map); 3576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return amt; 3579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ResourceTable::ConfigList::appendComment(const String16& comment, 3582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool onlyIfEmpty) 3583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() <= 0) { 3585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 3586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (onlyIfEmpty && mComment.size() > 0) { 3588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 3589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mComment.size() > 0) { 3591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mComment.append(String16("\n")); 3592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mComment.append(comment); 3594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ResourceTable::ConfigList::appendTypeComment(const String16& comment) 3597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() <= 0) { 3599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 3600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mTypeComment.size() > 0) { 3602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mTypeComment.append(String16("\n")); 3603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mTypeComment.append(comment); 3605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Type::addPublic(const SourcePos& sourcePos, 3608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 3609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const uint32_t ident) 3610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #if 0 3612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t entryIdx = Res_GETENTRY(ident); 3613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (entryIdx < 0) { 3614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Public resource %s/%s has an invalid 0 identifier (0x%08x).\n", 3615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string(), String8(name).string(), ident); 3616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #endif 3619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t typeIdx = Res_GETTYPE(ident); 3621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (typeIdx >= 0) { 3622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeIdx++; 3623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mPublicIndex > 0 && mPublicIndex != typeIdx) { 3624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Public resource %s/%s has conflicting type codes for its" 3625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " public identifiers (0x%x vs 0x%x).\n", 3626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string(), String8(name).string(), 3627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mPublicIndex, typeIdx); 3628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mPublicIndex = typeIdx; 3631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mFirstPublicSourcePos == NULL) { 3634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mFirstPublicSourcePos = new SourcePos(sourcePos); 3635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mPublic.indexOfKey(name) < 0) { 3638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mPublic.add(name, Public(sourcePos, String16(), ident)); 3639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 3640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Public& p = mPublic.editValueFor(name); 3641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p.ident != ident) { 3642282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Public resource %s/%s has conflicting public identifiers" 3643282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " (0x%08x vs 0x%08x).\n" 3644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s:%d: Originally defined here.\n", 3645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string(), String8(name).string(), p.ident, ident, 3646282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p.sourcePos.file.string(), p.sourcePos.line); 3647282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3649282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3650282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3651282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3653282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3654282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ResourceTable::Type::canAddEntry(const String16& name) 3655282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3656282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCanAddEntries.add(name); 3657282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3658282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3659282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<ResourceTable::Entry> ResourceTable::Type::getEntry(const String16& entry, 3660282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const SourcePos& sourcePos, 3661282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config* config, 3662282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool doSetIndex, 3663282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool overlay, 3664282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool autoAddOverlay) 3665282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int pos = -1; 3667282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = mConfigs.valueFor(entry); 3668282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == NULL) { 3669282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (overlay && !autoAddOverlay && mCanAddEntries.indexOf(entry) < 0) { 3670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Resource at %s appears in overlay but not" 3671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " in the base package; use <add-resource> to add.\n", 3672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(entry).string()); 3673282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 3674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3675282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c = new ConfigList(entry, sourcePos); 3676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mConfigs.add(entry, c); 3677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pos = (int)mOrderedConfigs.size(); 3678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedConfigs.add(c); 3679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (doSetIndex) { 3680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c->setEntryIndex(pos); 3681282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ConfigDescription cdesc; 3685282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (config) cdesc = *config; 3686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = c->getEntries().valueFor(cdesc); 3688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e == NULL) { 3689282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (config != NULL) { 3690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("New entry at %s:%d: imsi:%d/%d lang:%c%c cnt:%c%c " 3691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "orien:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d " 3692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "sw%ddp w%ddp h%ddp dir:%d\n", 3693282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.file.string(), sourcePos.line, 3694282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->mcc, config->mnc, 3695282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->language[0] ? config->language[0] : '-', 3696282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->language[1] ? config->language[1] : '-', 3697282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->country[0] ? config->country[0] : '-', 3698282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->country[1] ? config->country[1] : '-', 3699282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->orientation, 3700282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->touchscreen, 3701282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->density, 3702282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->keyboard, 3703282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->inputFlags, 3704282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->navigation, 3705282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->screenWidth, 3706282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->screenHeight, 3707282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->smallestScreenWidthDp, 3708282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->screenWidthDp, 3709282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->screenHeightDp, 3710282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->layoutDirection)); 3711282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 3712282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("New entry at %s:%d: NULL config\n", 3713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.file.string(), sourcePos.line)); 3714282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3715282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski e = new Entry(entry, sourcePos); 3716282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c->addEntry(cdesc, e); 3717282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 3718282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (doSetIndex) { 3719282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pos < 0) { 3720282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (pos=0; pos<(int)mOrderedConfigs.size(); pos++) { 3721282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mOrderedConfigs[pos] == c) { 3722282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 3723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3724282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3725282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pos >= (int)mOrderedConfigs.size()) { 3726282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Internal error: config not found in mOrderedConfigs when adding entry"); 3727282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 3728282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3729282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3730282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski e->setEntryIndex(pos); 3731282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3732282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 3733282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3734282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3735282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mUniqueConfigs.add(cdesc); 3736282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3737282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return e; 3738282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3739282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3740282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Type::applyPublicEntryOrder() 3741282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3742282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t N = mOrderedConfigs.size(); 3743282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<sp<ConfigList> > origOrder(mOrderedConfigs); 3744282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasError = false; 3745282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3746282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 3747282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 3748282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedConfigs.replaceAt(NULL, i); 3749282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3750282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3751282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NP = mPublic.size(); 3752282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Ordering %d configs from %d public defs\n", N, NP); 3753282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t j; 3754282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (j=0; j<NP; j++) { 3755282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name = mPublic.keyAt(j); 3756282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Public& p = mPublic.valueAt(j); 3757282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t idx = Res_GETENTRY(p.ident); 3758282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Looking for entry \"%s\"/\"%s\" (0x%08x) in %d...\n", 3759282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(mName).string(), String8(name).string(), p.ident, N); 3760282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool found = false; 3761282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 3762282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> e = origOrder.itemAt(i); 3763282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("#%d: \"%s\"\n", i, String8(e->getName()).string()); 3764282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e->getName() == name) { 3765282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (idx >= (int32_t)mOrderedConfigs.size()) { 3766282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p.sourcePos.error("Public entry identifier 0x%x entry index " 3767282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "is larger than available symbols (index %d, total symbols %d).\n", 3768282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p.ident, idx, mOrderedConfigs.size()); 3769282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasError = true; 3770282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (mOrderedConfigs.itemAt(idx) == NULL) { 3771282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski e->setPublic(true); 3772282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski e->setPublicSourcePos(p.sourcePos); 3773282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedConfigs.replaceAt(e, idx); 3774282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski origOrder.removeAt(i); 3775282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski N--; 3776282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski found = true; 3777282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 3778282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 3779282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> oe = mOrderedConfigs.itemAt(idx); 3780282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3781282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p.sourcePos.error("Multiple entry names declared for public entry" 3782282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " identifier 0x%x in type %s (%s vs %s).\n" 3783282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s:%d: Originally defined here.", 3784282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski idx+1, String8(mName).string(), 3785282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(oe->getName()).string(), 3786282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(name).string(), 3787282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski oe->getPublicSourcePos().file.string(), 3788282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski oe->getPublicSourcePos().line); 3789282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasError = true; 3790282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3791282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3792282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3793282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3794282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!found) { 3795282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p.sourcePos.error("Public symbol %s/%s declared here is not defined.", 3796282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string(), String8(name).string()); 3797282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasError = true; 3798282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3799282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3800282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3801282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Copying back in %d non-public configs, have %d\n", N, origOrder.size()); 3802282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3803282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (N != origOrder.size()) { 3804282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Internal error: remaining private symbol count mismatch\n"); 3805282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski N = origOrder.size(); 3806282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3807282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3808282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski j = 0; 3809282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 3810282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> e = origOrder.itemAt(i); 3811282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // There will always be enough room for the remaining entries. 3812282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (mOrderedConfigs.itemAt(j) != NULL) { 3813282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski j++; 3814282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3815282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedConfigs.replaceAt(e, j); 3816282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski j++; 3817282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return hasError ? UNKNOWN_ERROR : NO_ERROR; 3820282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3821282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3822282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiResourceTable::Package::Package(const String16& name, ssize_t includedId) 3823282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski : mName(name), mIncludedId(includedId), 3824282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mTypeStringsMapping(0xffffffff), 3825282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mKeyStringsMapping(0xffffffff) 3826282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3827282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3828282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3829282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<ResourceTable::Type> ResourceTable::Package::getType(const String16& type, 3830282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const SourcePos& sourcePos, 3831282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool doSetIndex) 3832282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3833282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = mTypes.valueFor(type); 3834282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) { 3835282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski t = new Type(type, sourcePos); 3836282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mTypes.add(type, t); 3837282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedTypes.add(t); 3838282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (doSetIndex) { 3839282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // For some reason the type's index is set to one plus the index 3840282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // in the mOrderedTypes list, rather than just the index. 3841282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski t->setIndex(mOrderedTypes.size()); 3842282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3843282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3844282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return t; 3845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Package::setTypeStrings(const sp<AaptFile>& data) 3848282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3849282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mTypeStringsData = data; 3850282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = setStrings(data, &mTypeStrings, &mTypeStringsMapping); 3851282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3852282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: Type string data is corrupt!\n"); 3853282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3854282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3855282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3857282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Package::setKeyStrings(const sp<AaptFile>& data) 3858282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3859282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mKeyStringsData = data; 3860282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = setStrings(data, &mKeyStrings, &mKeyStringsMapping); 3861282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3862282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: Key string data is corrupt!\n"); 3863282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3864282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3865282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3866282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3867282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Package::setStrings(const sp<AaptFile>& data, 3868282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResStringPool* strings, 3869282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DefaultKeyedVector<String16, uint32_t>* mappings) 3870282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3871282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (data->getData() == NULL) { 3872282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3873282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3874282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3875282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(aout << "Setting restable string pool: " 3876282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski << HexDump(data->getData(), data->getSize()) << endl); 3877282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3878282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = strings->setTo(data->getData(), data->getSize()); 3879282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err == NO_ERROR) { 3880282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = strings->size(); 3881282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 3882282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 3883282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mappings->add(String16(strings->stringAt(i, &len)), i); 3884282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3885282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3886282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3887282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3888282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3889282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Package::applyPublicTypeOrder() 3890282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3891282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t N = mOrderedTypes.size(); 3892282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<sp<Type> > origOrder(mOrderedTypes); 3893282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3894282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 3895282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 3896282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedTypes.replaceAt(NULL, i); 3897282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3898282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3899282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 3900282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = origOrder.itemAt(i); 3901282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t idx = t->getPublicIndex(); 3902282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (idx > 0) { 3903282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski idx--; 3904282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (idx >= (int32_t)mOrderedTypes.size()) { 3905282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedTypes.add(); 3906282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3907282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mOrderedTypes.itemAt(idx) != NULL) { 3908282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> ot = mOrderedTypes.itemAt(idx); 3909282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski t->getFirstPublicSourcePos().error("Multiple type names declared for public type" 3910282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " identifier 0x%x (%s vs %s).\n" 3911282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s:%d: Originally defined here.", 3912282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski idx, String8(ot->getName()).string(), 3913282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(t->getName()).string(), 3914282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ot->getFirstPublicSourcePos().file.string(), 3915282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ot->getFirstPublicSourcePos().line); 3916282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3917282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3918282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedTypes.replaceAt(t, idx); 3919282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski origOrder.removeAt(i); 3920282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski i--; 3921282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski N--; 3922282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3923282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3924282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3925282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t j=0; 3926282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 3927282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = origOrder.itemAt(i); 3928282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // There will always be enough room for the remaining types. 3929282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (mOrderedTypes.itemAt(j) != NULL) { 3930282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski j++; 3931282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3932282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedTypes.replaceAt(t, j); 3933282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3934282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3935282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3936282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3937282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3938282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<ResourceTable::Package> ResourceTable::getPackage(const String16& package) 3939282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3940282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mPackages.valueFor(package); 3941282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p == NULL) { 3942282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mIsAppPackage) { 3943282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mHaveAppPackage) { 3944282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "Adding multiple application package resources; only one is allowed.\n" 3945282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Use -x to create extended resources.\n"); 3946282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 3947282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3948282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mHaveAppPackage = true; 3949de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski p = new Package(package, mIsSharedLibrary ? 0 : 127); 3950282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 3951282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p = new Package(package, mNextPackageId); 3952282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3953282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("*** NEW PACKAGE: \"%s\" id=%d\n", 3954282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(package).string(), p->getAssignedId()); 3955282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mPackages.add(package, p); 3956282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedPackages.add(p); 3957282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mNextPackageId++; 3958282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3959282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return p; 3960282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3961282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3962282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<ResourceTable::Type> ResourceTable::getType(const String16& package, 3963282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 3964282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const SourcePos& sourcePos, 3965282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool doSetIndex) 3966282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3967282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = getPackage(package); 3968282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p == NULL) { 3969282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 3970282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3971282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return p->getType(type, sourcePos, doSetIndex); 3972282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3973282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3974282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<ResourceTable::Entry> ResourceTable::getEntry(const String16& package, 3975282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 3976282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 3977282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const SourcePos& sourcePos, 3978282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool overlay, 3979282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config* config, 3980282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool doSetIndex) 3981282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3982282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = getType(package, type, sourcePos, doSetIndex); 3983282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) { 3984282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 3985282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3986282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return t->getEntry(name, sourcePos, config, doSetIndex, overlay, mBundle->getAutoAddOverlay()); 3987282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3988282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3989282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<const ResourceTable::Entry> ResourceTable::getEntry(uint32_t resID, 3990282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config* config) const 3991282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3992282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int pid = Res_GETPACKAGE(resID)+1; 3993282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = mOrderedPackages.size(); 3994282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 3995282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p; 3996282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 3997282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> check = mOrderedPackages[i]; 3998282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (check->getAssignedId() == pid) { 3999282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p = check; 4000282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 4001282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4002282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4003282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4004282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p == NULL) { 4005282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "warning: Package not found for resource #%08x\n", resID); 4006282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 4007282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4008282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4009282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int tid = Res_GETTYPE(resID); 4010282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tid < 0 || tid >= (int)p->getOrderedTypes().size()) { 4011282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "warning: Type not found for resource #%08x\n", resID); 4012282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 4013282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4014282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getOrderedTypes()[tid]; 4015282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4016282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int eid = Res_GETENTRY(resID); 4017282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (eid < 0 || eid >= (int)t->getOrderedConfigs().size()) { 4018282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "warning: Entry not found for resource #%08x\n", resID); 4019282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 4020282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4021282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4022282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getOrderedConfigs()[eid]; 4023282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == NULL) { 4024282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "warning: Entry not found for resource #%08x\n", resID); 4025282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 4026282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4027282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4028282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ConfigDescription cdesc; 4029282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (config) cdesc = *config; 4030282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = c->getEntries().valueFor(cdesc); 4031282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == NULL) { 4032282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "warning: Entry configuration not found for resource #%08x\n", resID); 4033282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 4034282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4035282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4036282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return e; 4037282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 4038282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4039282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiconst ResourceTable::Item* ResourceTable::getItem(uint32_t resID, uint32_t attrID) const 4040282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 4041282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<const Entry> e = getEntry(resID); 4042282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e == NULL) { 4043282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 4044282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4045282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4046282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = e->getBag().size(); 4047282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 4048282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Item& it = e->getBag().valueAt(i); 4049282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (it.bagKeyId == 0) { 4050282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "warning: ID not yet assigned to '%s' in bag '%s'\n", 4051282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(e->getName()).string(), 4052282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(e->getBag().keyAt(i)).string()); 4053282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4054282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (it.bagKeyId == attrID) { 4055282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ⁢ 4056282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4057282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4058282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4059282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 4060282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 4061282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4062282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::getItemValue( 4063282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t resID, uint32_t attrID, Res_value* outValue) 4064282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 4065282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Item* item = getItem(resID, attrID); 4066282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4067282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool res = false; 4068282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (item != NULL) { 4069282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (item->evaluating) { 4070282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<const Entry> e = getEntry(resID); 4071282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = e->getBag().size(); 4072282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 4073282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 4074282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (&e->getBag().valueAt(i) == item) { 4075282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 4076282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4077282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4078282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "warning: Circular reference detected in key '%s' of bag '%s'\n", 4079282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(e->getName()).string(), 4080282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(e->getBag().keyAt(i)).string()); 4081282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 4082282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4083282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski item->evaluating = true; 4084282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski res = stringToValue(outValue, NULL, item->value, false, false, item->bagKeyId); 4085282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY( 4086282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (res) { 4087282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("getItemValue of #%08x[#%08x] (%s): type=#%08x, data=#%08x\n", 4088282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resID, attrID, String8(getEntry(resID)->getName()).string(), 4089282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->dataType, outValue->data); 4090282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 4091282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("getItemValue of #%08x[#%08x]: failed\n", 4092282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resID, attrID); 4093282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4094282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ); 4095282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski item->evaluating = false; 4096282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4097282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return res; 4098282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 4099