ResourceTable.cpp revision e572c011feabf6319ba836cf5bc4c3baa0ba6a85
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> 1582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski#include <utils/TypeHelpers.h> 16282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <stdarg.h> 17282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 18282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#define NOISY(x) //x 19282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 20e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinskistatus_t compileXmlFile(const Bundle* bundle, 21e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const sp<AaptAssets>& assets, 22e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const String16& resourceName, 23282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptFile>& target, 24282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceTable* table, 25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int options) 26282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 27282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<XMLNode> root = XMLNode::parse(target); 28282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (root == NULL) { 29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 31a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin 32e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski return compileXmlFile(bundle, assets, resourceName, root, target, table, options); 33282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 34282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 35e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinskistatus_t compileXmlFile(const Bundle* bundle, 36e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const sp<AaptAssets>& assets, 37e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const String16& resourceName, 38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptFile>& target, 39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptFile>& outTarget, 40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceTable* table, 41282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int options) 42282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<XMLNode> root = XMLNode::parse(target); 44282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (root == NULL) { 45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 48e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski return compileXmlFile(bundle, assets, resourceName, root, outTarget, table, options); 49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 51e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinskistatus_t compileXmlFile(const Bundle* bundle, 52e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const sp<AaptAssets>& assets, 53e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const String16& resourceName, 54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<XMLNode>& root, 55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptFile>& target, 56282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceTable* table, 57282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int options) 58282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((options&XML_COMPILE_STRIP_WHITESPACE) != 0) { 60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski root->removeWhitespace(true, NULL); 61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if ((options&XML_COMPILE_COMPACT_WHITESPACE) != 0) { 62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski root->removeWhitespace(false, NULL); 63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((options&XML_COMPILE_UTF8) != 0) { 66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski root->setUTF8(true); 67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasErrors = false; 70282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 71282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((options&XML_COMPILE_ASSIGN_ATTRIBUTE_IDS) != 0) { 72282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = root->assignResourceIds(assets, table); 73282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 74282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 75282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 77282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 78282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = root->parseValues(assets, table); 79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasErrors) { 84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 86e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 87e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski if (table->modifyForCompat(bundle, resourceName, target, root) != NO_ERROR) { 88e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski return UNKNOWN_ERROR; 89e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Input XML Resource:\n")); 92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(root->print()); 93282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = root->flatten(target, 94282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (options&XML_COMPILE_STRIP_COMMENTS) != 0, 95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (options&XML_COMPILE_STRIP_RAW_VALUES) != 0); 96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Output XML Resource:\n")); 101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(ResXMLTree tree; 102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tree.setTo(target->getData(), target->getSize()); 103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printXMLBlock(&tree)); 104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski target->setCompressionMethod(ZipEntry::kCompressDeflated); 106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#undef NOISY 111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#define NOISY(x) //x 112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistruct flag_entry 114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* name; 116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t nameLen; 117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t value; 118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* description; 119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}; 120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t referenceArray[] = 122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 'r', 'e', 'f', 'e', 'r', 'e', 'n', 'c', 'e' }; 123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t stringArray[] = 124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 's', 't', 'r', 'i', 'n', 'g' }; 125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t integerArray[] = 126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 'i', 'n', 't', 'e', 'g', 'e', 'r' }; 127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t booleanArray[] = 128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 'b', 'o', 'o', 'l', 'e', 'a', 'n' }; 129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t colorArray[] = 130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 'c', 'o', 'l', 'o', 'r' }; 131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t floatArray[] = 132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 'f', 'l', 'o', 'a', 't' }; 133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t dimensionArray[] = 134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n' }; 135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t fractionArray[] = 136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 'f', 'r', 'a', 'c', 't', 'i', 'o', 'n' }; 137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t enumArray[] = 138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 'e', 'n', 'u', 'm' }; 139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t flagsArray[] = 140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 'f', 'l', 'a', 'g', 's' }; 141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const flag_entry gFormatFlags[] = { 143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { referenceArray, sizeof(referenceArray)/2, ResTable_map::TYPE_REFERENCE, 144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "a reference to another resource, in the form \"<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>\"\n" 145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "or to a theme attribute in the form \"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>\"."}, 146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { stringArray, sizeof(stringArray)/2, ResTable_map::TYPE_STRING, 147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "a string value, using '\\\\;' to escape characters such as '\\\\n' or '\\\\uxxxx' for a unicode character." }, 148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { integerArray, sizeof(integerArray)/2, ResTable_map::TYPE_INTEGER, 149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "an integer value, such as \"<code>100</code>\"." }, 150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { booleanArray, sizeof(booleanArray)/2, ResTable_map::TYPE_BOOLEAN, 151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "a boolean value, either \"<code>true</code>\" or \"<code>false</code>\"." }, 152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { colorArray, sizeof(colorArray)/2, ResTable_map::TYPE_COLOR, 153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "a color value, in the form of \"<code>#<i>rgb</i></code>\", \"<code>#<i>argb</i></code>\",\n" 154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "\"<code>#<i>rrggbb</i></code>\", or \"<code>#<i>aarrggbb</i></code>\"." }, 155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { floatArray, sizeof(floatArray)/2, ResTable_map::TYPE_FLOAT, 156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "a floating point value, such as \"<code>1.2</code>\"."}, 157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { dimensionArray, sizeof(dimensionArray)/2, ResTable_map::TYPE_DIMENSION, 158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "a dimension value, which is a floating point number appended with a unit such as \"<code>14.5sp</code>\".\n" 159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size),\n" 160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "in (inches), mm (millimeters)." }, 161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { fractionArray, sizeof(fractionArray)/2, ResTable_map::TYPE_FRACTION, 162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "a fractional value, which is a floating point number appended with either % or %p, such as \"<code>14.5%</code>\".\n" 163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "The % suffix always means a percentage of the base size; the optional %p suffix provides a size relative to\n" 164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "some parent container." }, 165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { enumArray, sizeof(enumArray)/2, ResTable_map::TYPE_ENUM, NULL }, 166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { flagsArray, sizeof(flagsArray)/2, ResTable_map::TYPE_FLAGS, NULL }, 167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { NULL, 0, 0, NULL } 168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}; 169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t suggestedArray[] = { 's', 'u', 'g', 'g', 'e', 's', 't', 'e', 'd' }; 171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const flag_entry l10nRequiredFlags[] = { 173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { suggestedArray, sizeof(suggestedArray)/2, ResTable_map::L10N_SUGGESTED, NULL }, 174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { NULL, 0, 0, NULL } 175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}; 176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char16_t nulStr[] = { 0 }; 178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic uint32_t parse_flags(const char16_t* str, size_t len, 180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const flag_entry* flags, bool* outError = NULL) 181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (len > 0 && isspace(*str)) { 183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski str++; 184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski len--; 185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (len > 0 && isspace(str[len-1])) { 187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski len--; 188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* const end = str + len; 191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t value = 0; 192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (str < end) { 194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* div = str; 195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (div < end && *div != '|') { 196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski div++; 197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const flag_entry* cur = flags; 200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (cur->name) { 201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strzcmp16(cur->name, cur->nameLen, str, div-str) == 0) { 202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski value |= cur->value; 203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski cur++; 206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!cur->name) { 209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outError) *outError = true; 210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski str = div < end ? div+1 : div; 214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outError) *outError = false; 217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return value; 218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic String16 mayOrMust(int type, int flags) 221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((type&(~flags)) == 0) { 223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return String16("<p>Must"); 224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return String16("<p>May"); 227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic void appendTypeInfo(ResourceTable* outTable, const String16& pkg, 230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& typeName, const String16& ident, int type, 231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const flag_entry* flags) 232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hadType = false; 234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (flags->name) { 235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((type&flags->value) != 0 && flags->description != NULL) { 236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 fullMsg(mayOrMust(type, flags->value)); 237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fullMsg.append(String16(" be ")); 238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fullMsg.append(String16(flags->description)); 239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outTable->appendTypeComment(pkg, typeName, ident, fullMsg); 240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hadType = true; 241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski flags++; 243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hadType && (type&ResTable_map::TYPE_REFERENCE) == 0) { 245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outTable->appendTypeComment(pkg, typeName, ident, 246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16("<p>This may also be a reference to a resource (in the form\n" 247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "\"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>\") or\n" 248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "theme attribute (in the form\n" 249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "\"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>\")\n" 250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "containing a value of this type.")); 251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistruct PendingAttribute 255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 myPackage; 257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const SourcePos sourcePos; 258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool appendComment; 259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t type; 260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 ident; 261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment; 262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasErrors; 263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool added; 264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski PendingAttribute(String16 _package, const sp<AaptFile>& in, 266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree& block, bool _appendComment) 267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski : myPackage(_package) 268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , sourcePos(in->getPrintableSource(), block.getLineNumber()) 269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , appendComment(_appendComment) 270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , type(ResTable_map::TYPE_ANY) 271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , hasErrors(false) 272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , added(false) 273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t createIfNeeded(ResourceTable* outTable) 277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (added || hasErrors) { 279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski added = true; 282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 attr16("attr"); 284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outTable->hasBagOrEntry(myPackage, attr16, ident)) { 286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Attribute \"%s\" has already been defined\n", 287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(ident).string()); 288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char numberStr[16]; 293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sprintf(numberStr, "%d", type); 294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = outTable->addBag(sourcePos, myPackage, 295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr16, ident, String16(""), 296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16("^type"), 297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16(numberStr), NULL, NULL); 298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outTable->appendComment(myPackage, attr16, ident, comment, appendComment); 303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Attribute %s comment: %s\n", String8(ident).string(), 304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(comment).string()); 305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}; 308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic status_t compileAttribute(const sp<AaptFile>& in, 310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree& block, 311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& myPackage, 312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceTable* outTable, 313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16* outIdent = NULL, 314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool inStyleable = false) 315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski PendingAttribute attr(myPackage, in, block, inStyleable); 317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 attr16("attr"); 319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 id16("id"); 320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Attribute type constants. 322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 enum16("enum"); 323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 flag16("flag"); 324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree::event_code_t code; 326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err; 328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t identIdx = block.indexOfAttribute(NULL, "name"); 330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (identIdx >= 0) { 331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.ident = String16(block.getAttributeStringValue(identIdx, &len)); 332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outIdent) { 333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outIdent = attr.ident; 334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.sourcePos.error("A 'name' attribute is required for <attr>\n"); 337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.comment = String16( 341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.getComment(&len) ? block.getComment(&len) : nulStr); 342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t typeIdx = block.indexOfAttribute(NULL, "format"); 344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (typeIdx >= 0) { 345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 typeStr = String16(block.getAttributeStringValue(typeIdx, &len)); 346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.type = parse_flags(typeStr.string(), typeStr.size(), gFormatFlags); 347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (attr.type == 0) { 348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.sourcePos.error("Tag <attr> 'format' attribute value \"%s\" not valid\n", 349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(typeStr).string()); 350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.createIfNeeded(outTable); 353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (!inStyleable) { 354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Attribute definitions outside of styleables always define the 355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // attribute as a generic value. 356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.createIfNeeded(outTable); 357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Attribute %s: type=0x%08x\n", String8(attr.ident).string(), attr.type); 360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t minIdx = block.indexOfAttribute(NULL, "min"); 362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (minIdx >= 0) { 363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 val = String16(block.getAttributeStringValue(minIdx, &len)); 364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!ResTable::stringToInt(val.string(), val.size(), NULL)) { 365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.sourcePos.error("Tag <attr> 'min' attribute must be a number, not \"%s\"\n", 366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(val).string()); 367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.createIfNeeded(outTable); 370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!attr.hasErrors) { 371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident, 372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16(""), String16("^min"), String16(val), NULL, NULL); 373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t maxIdx = block.indexOfAttribute(NULL, "max"); 380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (maxIdx >= 0) { 381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 val = String16(block.getAttributeStringValue(maxIdx, &len)); 382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!ResTable::stringToInt(val.string(), val.size(), NULL)) { 383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.sourcePos.error("Tag <attr> 'max' attribute must be a number, not \"%s\"\n", 384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(val).string()); 385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.createIfNeeded(outTable); 388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!attr.hasErrors) { 389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident, 390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16(""), String16("^max"), String16(val), NULL, NULL); 391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((minIdx >= 0 || maxIdx >= 0) && (attr.type&ResTable_map::TYPE_INTEGER) == 0) { 396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.sourcePos.error("Tag <attr> must have format=integer attribute if using max or min\n"); 397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t l10nIdx = block.indexOfAttribute(NULL, "localization"); 401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (l10nIdx >= 0) { 402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const uint16_t* str = block.getAttributeStringValue(l10nIdx, &len); 403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool error; 404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t l10n_required = parse_flags(str, len, l10nRequiredFlags, &error); 405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (error) { 406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.sourcePos.error("Tag <attr> 'localization' attribute value \"%s\" not valid\n", 407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(str).string()); 408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.createIfNeeded(outTable); 411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!attr.hasErrors) { 412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char buf[11]; 413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sprintf(buf, "%d", l10n_required); 414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident, 415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16(""), String16("^l10n"), String16(buf), NULL, NULL); 416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 enumOrFlagsComment; 423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::START_TAG) { 426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t localType = 0; 427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), enum16.string()) == 0) { 428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski localType = ResTable_map::TYPE_ENUM; 429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), flag16.string()) == 0) { 430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski localType = ResTable_map::TYPE_FLAGS; 431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()) 433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .error("Tag <%s> can not appear inside <attr>, only <enum> or <flag>\n", 434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getElementName(&len)).string()); 435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.createIfNeeded(outTable); 439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (attr.type == ResTable_map::TYPE_ANY) { 441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // No type was explicitly stated, so supplying enum tags 442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // implicitly creates an enum or flag. 443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.type = 0; 444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((attr.type&(ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS)) == 0) { 447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Wasn't originally specified as an enum, so update its type. 448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.type |= localType; 449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!attr.hasErrors) { 450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char numberStr[16]; 451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sprintf(numberStr, "%d", attr.type); 452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addBag(SourcePos(in->getPrintableSource(), block.getLineNumber()), 453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski myPackage, attr16, attr.ident, String16(""), 454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16("^type"), String16(numberStr), NULL, NULL, true); 455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if ((uint32_t)(attr.type&(ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS)) != localType) { 460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (localType == ResTable_map::TYPE_ENUM) { 461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()) 462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .error("<enum> attribute can not be used inside a flags format\n"); 463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()) 466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .error("<flag> attribute can not be used inside a enum format\n"); 467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 itemIdent; 472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t itemIdentIdx = block.indexOfAttribute(NULL, "name"); 473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (itemIdentIdx >= 0) { 474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent = String16(block.getAttributeStringValue(itemIdentIdx, &len)); 475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()) 477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .error("A 'name' attribute is required for <enum> or <flag>\n"); 478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 value; 482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t valueIdx = block.indexOfAttribute(NULL, "value"); 483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (valueIdx >= 0) { 484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski value = String16(block.getAttributeStringValue(valueIdx, &len)); 485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()) 487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .error("A 'value' attribute is required for <enum> or <flag>\n"); 488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!attr.hasErrors && !ResTable::stringToInt(value.string(), value.size(), NULL)) { 491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()) 492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .error("Tag <enum> or <flag> 'value' attribute must be a number," 493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " not \"%s\"\n", 494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(value).string()); 495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!attr.hasErrors) { 499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (enumOrFlagsComment.size() == 0) { 500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(mayOrMust(attr.type, 501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS)); 502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append((attr.type&ResTable_map::TYPE_ENUM) 503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ? String16(" be one of the following constant values.") 504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski : String16(" be one or more (separated by '|') of the following constant values.")); 505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(String16("</p>\n<table>\n" 506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "<colgroup align=\"left\" />\n" 507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "<colgroup align=\"left\" />\n" 508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "<colgroup align=\"left\" />\n" 509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "<tr><th>Constant</th><th>Value</th><th>Description</th></tr>")); 510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(String16("\n<tr><td><code>")); 513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(itemIdent); 514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(String16("</code></td><td>")); 515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(value); 516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(String16("</td><td>")); 517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (block.getComment(&len)) { 518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(String16(block.getComment(&len))); 519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(String16("</td></tr>")); 521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addBag(SourcePos(in->getPrintableSource(), block.getLineNumber()), 523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski myPackage, 524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr16, attr.ident, String16(""), 525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent, value, NULL, NULL, false, true); 526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr.hasErrors = true; 528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (code == ResXMLTree::END_TAG) { 531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), attr16.string()) == 0) { 532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((attr.type&ResTable_map::TYPE_ENUM) != 0) { 535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), enum16.string()) != 0) { 536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()) 537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .error("Found tag </%s> where </enum> is expected\n", 538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getElementName(&len)).string()); 539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), flag16.string()) != 0) { 543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()) 544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .error("Found tag </%s> where </flag> is expected\n", 545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getElementName(&len)).string()); 546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!attr.hasErrors && attr.added) { 553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski appendTypeInfo(outTable, myPackage, attr16, attr.ident, attr.type, gFormatFlags); 554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!attr.hasErrors && enumOrFlagsComment.size() > 0) { 557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enumOrFlagsComment.append(String16("\n</table>")); 558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outTable->appendTypeComment(myPackage, attr16, attr.ident, enumOrFlagsComment); 559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool localeIsDefined(const ResTable_config& config) 566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return config.locale == 0; 568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t parseAndAddBag(Bundle* bundle, 571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptFile>& in, 572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree* block, 573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config& config, 574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& myPackage, 575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& curType, 576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& ident, 577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& parentIdent, 578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& itemIdent, 579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t curFormat, 580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool isFormatted, 581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& product, 582a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin PseudolocalizationMethod pseudolocalize, 583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool overwrite, 584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceTable* outTable) 585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err; 587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 item16("item"); 588a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin 589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 str; 590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<StringPool::entry_style_span> spans; 591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = parseStyledString(bundle, in->getPrintableSource().string(), 592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block, item16, &str, &spans, isFormatted, 593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pseudolocalize); 594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Adding resource bag entry l=%c%c c=%c%c orien=%d d=%d " 599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " pid=%s, bag=%s, id=%s: %s\n", 600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.language[0], config.language[1], 601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.country[0], config.country[1], 602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.orientation, config.density, 603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(parentIdent).string(), 604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(ident).string(), 605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(itemIdent).string(), 606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(str).string())); 607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addBag(SourcePos(in->getPrintableSource(), block->getLineNumber()), 609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski myPackage, curType, ident, parentIdent, itemIdent, str, 610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski &spans, &config, overwrite, false, curFormat); 611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Returns true if needle is one of the elements in the comma-separated list 616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * haystack, false otherwise. 617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool isInProductList(const String16& needle, const String16& haystack) { 619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t *needle2 = needle.string(); 620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t *haystack2 = haystack.string(); 621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t needlesize = needle.size(); 622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (*haystack2 != '\0') { 624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strncmp16(haystack2, needle2, needlesize) == 0) { 625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (haystack2[needlesize] == '\0' || haystack2[needlesize] == ',') { 626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (*haystack2 != '\0' && *haystack2 != ',') { 631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski haystack2++; 632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (*haystack2 == ',') { 634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski haystack2++; 635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 6418ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski/* 6428ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski * A simple container that holds a resource type and name. It is ordered first by type then 6438ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski * by name. 6448ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski */ 6458ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinskistruct type_ident_pair_t { 6468ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski String16 type; 6478ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski String16 ident; 6488ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski 6498ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski type_ident_pair_t() { }; 6508ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski type_ident_pair_t(const String16& t, const String16& i) : type(t), ident(i) { } 6518ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski type_ident_pair_t(const type_ident_pair_t& o) : type(o.type), ident(o.ident) { } 6528ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski inline bool operator < (const type_ident_pair_t& o) const { 6538ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski int cmp = compare_type(type, o.type); 6548ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski if (cmp < 0) { 6558ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski return true; 6568ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski } else if (cmp > 0) { 6578ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski return false; 6588ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski } else { 6598ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski return strictly_order_type(ident, o.ident); 6608ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski } 6618ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski } 6628ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski}; 6638ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski 6648ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski 665282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t parseAndAddEntry(Bundle* bundle, 666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptFile>& in, 667282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree* block, 668282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config& config, 669282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& myPackage, 670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& curType, 671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& ident, 672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& curTag, 673282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool curIsStyled, 674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t curFormat, 675282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool isFormatted, 676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& product, 677a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin PseudolocalizationMethod pseudolocalize, 678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool overwrite, 6798ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski KeyedVector<type_ident_pair_t, bool>* skippedResourceNames, 680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceTable* outTable) 681282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err; 683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 str; 685282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<StringPool::entry_style_span> spans; 686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = parseStyledString(bundle, in->getPrintableSource().string(), block, 687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag, &str, curIsStyled ? &spans : NULL, 688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski isFormatted, pseudolocalize); 689282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 693282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 694282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 695282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * If a product type was specified on the command line 696282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * and also in the string, and the two are not the same, 697282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * return without adding the string. 698282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 699282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 700282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char *bundleProduct = bundle->getProduct(); 701282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundleProduct == NULL) { 702282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bundleProduct = ""; 703282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 704282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 705282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (product.size() != 0) { 706282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 707282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * If the command-line-specified product is empty, only "default" 708282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * matches. Other variants are skipped. This is so generation 709282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * of the R.java file when the product is not known is predictable. 710282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 711282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 712282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundleProduct[0] == '\0') { 713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(String16("default").string(), product.string()) != 0) { 7148ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski /* 7158ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski * This string has a product other than 'default'. Do not add it, 7168ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski * but record it so that if we do not see the same string with 7178ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski * product 'default' or no product, then report an error. 7188ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski */ 7198ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski skippedResourceNames->replaceValueFor( 7208ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski type_ident_pair_t(curType, ident), true); 721282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 722282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 724282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 725282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * The command-line product is not empty. 726282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * If the product for this string is on the command-line list, 727282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * it matches. "default" also matches, but only if nothing 728282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * else has matched already. 729282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 730282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 731282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (isInProductList(product, String16(bundleProduct))) { 732282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ; 733282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(String16("default").string(), product.string()) == 0 && 734282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski !outTable->hasBagOrEntry(myPackage, curType, ident, config)) { 735282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ; 736282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 737282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 738282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 739282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 740282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 741282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 742282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Adding resource entry l=%c%c c=%c%c orien=%d d=%d id=%s: %s\n", 743282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.language[0], config.language[1], 744282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.country[0], config.country[1], 745282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.orientation, config.density, 746282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(ident).string(), String8(str).string())); 747282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 748282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addEntry(SourcePos(in->getPrintableSource(), block->getLineNumber()), 749282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski myPackage, curType, ident, str, &spans, &config, 750282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski false, curFormat, overwrite); 751282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 752282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 753282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 754282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 755282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t compileResourceFile(Bundle* bundle, 756282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptAssets>& assets, 757282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<AaptFile>& in, 758282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config& defParams, 759282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool overwrite, 760282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceTable* outTable) 761282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 762282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree block; 763282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = parseXMLResource(in, &block, false, true); 764282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 765282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 766282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 767282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 768282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Top-level tag. 769282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 resources16("resources"); 770282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 771282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Identifier declaration tags. 772282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 declare_styleable16("declare-styleable"); 773282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 attr16("attr"); 774282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 775282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Data creation organizational tags. 776282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 string16("string"); 777282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 drawable16("drawable"); 778282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 color16("color"); 779282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 bool16("bool"); 780282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 integer16("integer"); 781282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 dimen16("dimen"); 782282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 fraction16("fraction"); 783282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 style16("style"); 784282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 plurals16("plurals"); 785282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 array16("array"); 786282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 string_array16("string-array"); 787282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 integer_array16("integer-array"); 788282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 public16("public"); 789282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 public_padding16("public-padding"); 790282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 private_symbols16("private-symbols"); 791282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 java_symbol16("java-symbol"); 792282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 add_resource16("add-resource"); 793282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 skip16("skip"); 794282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 eat_comment16("eat-comment"); 795282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 796282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Data creation tags. 797282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 bag16("bag"); 798282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 item16("item"); 799282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 800282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Attribute type constants. 801282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 enum16("enum"); 802282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 803282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // plural values 804282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 other16("other"); 805282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 quantityOther16("^other"); 806282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 zero16("zero"); 807282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 quantityZero16("^zero"); 808282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 one16("one"); 809282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 quantityOne16("^one"); 810282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 two16("two"); 811282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 quantityTwo16("^two"); 812282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 few16("few"); 813282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 quantityFew16("^few"); 814282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 many16("many"); 815282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 quantityMany16("^many"); 816282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 817282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // useful attribute names and special values 818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 name16("name"); 819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 translatable16("translatable"); 820282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 formatted16("formatted"); 821282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 false16("false"); 822282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 823282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 myPackage(assets->getPackage()); 824282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 825282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasErrors = false; 826282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 827282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool fileIsTranslatable = true; 828282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strstr(in->getPrintableSource().string(), "donottranslate") != NULL) { 829282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fileIsTranslatable = false; 830282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 831282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 832282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DefaultKeyedVector<String16, uint32_t> nextPublicId(0); 833282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 8348ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski // Stores the resource names that were skipped. Typically this happens when 8358ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski // AAPT is invoked without a product specified and a resource has no 8368ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski // 'default' product attribute. 8378ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski KeyedVector<type_ident_pair_t, bool> skippedResourceNames; 8388ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski 839282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLTree::event_code_t code; 840282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski do { 841282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski code = block.next(); 842282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } while (code == ResXMLTree::START_NAMESPACE); 843282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 844282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code != ResXMLTree::START_TAG) { 846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "No start tag found\n"); 848282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 849282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 850282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), resources16.string()) != 0) { 851282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 852282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Invalid start tag %s\n", String8(block.getElementName(&len)).string()); 853282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 854282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 855282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_config curParams(defParams); 857282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 858282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_config pseudoParams(curParams); 859a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin pseudoParams.language[0] = 'e'; 860a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin pseudoParams.language[1] = 'n'; 861a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin pseudoParams.country[0] = 'X'; 862a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin pseudoParams.country[1] = 'A'; 863a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin 864a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin ResTable_config pseudoBidiParams(curParams); 865a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin pseudoBidiParams.language[0] = 'a'; 866a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin pseudoBidiParams.language[1] = 'r'; 867a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin pseudoBidiParams.country[0] = 'X'; 868a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin pseudoBidiParams.country[1] = 'B'; 869282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 87047843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk // We should skip resources for pseudolocales if they were 87147843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk // already added automatically. This is a fix for a transition period when 87247843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk // manually pseudolocalized resources may be expected. 87347843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk // TODO: remove this check after next SDK version release. 87447843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk if ((bundle->getPseudolocalize() & PSEUDO_ACCENTED && 87547843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk curParams.locale == pseudoParams.locale) || 87647843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk (bundle->getPseudolocalize() & PSEUDO_BIDI && 87747843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk curParams.locale == pseudoBidiParams.locale)) { 87847843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk SourcePos(in->getPrintableSource(), 0).warning( 87947843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk "Resource file %s is skipped as pseudolocalization" 88047843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk " was done automatically.", 88147843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk in->getPrintableSource().string()); 88247843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk return NO_ERROR; 88347843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk } 88447843df11fe88b30abcac324173b6c15f16cc797Igor Viarheichyk 885282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 886282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::START_TAG) { 887282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16* curTag = NULL; 888282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 curType; 889282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t curFormat = ResTable_map::TYPE_ANY; 890282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool curIsBag = false; 891282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool curIsBagReplaceOnOverwrite = false; 892282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool curIsStyled = false; 893282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool curIsPseudolocalizable = false; 894282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool curIsFormatted = fileIsTranslatable; 895282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool localHasErrors = false; 896282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 897282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), skip16.string()) == 0) { 898282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT 899282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski && code != ResXMLTree::BAD_DOCUMENT) { 900282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 901282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), skip16.string()) == 0) { 902282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 903282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 904282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 905282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 906282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 907282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 908282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) { 909282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT 910282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski && code != ResXMLTree::BAD_DOCUMENT) { 911282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 912282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) { 913282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 914282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 915282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 916282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 917282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 918282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 919282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), public16.string()) == 0) { 920282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos srcPos(in->getPrintableSource(), block.getLineNumber()); 921282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 922282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 type; 923282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t typeIdx = block.indexOfAttribute(NULL, "type"); 924282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (typeIdx < 0) { 925282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("A 'type' attribute is required for <public>\n"); 926282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 927282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 928282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type = String16(block.getAttributeStringValue(typeIdx, &len)); 929282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 930282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 name; 931282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t nameIdx = block.indexOfAttribute(NULL, "name"); 932282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (nameIdx < 0) { 933282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("A 'name' attribute is required for <public>\n"); 934282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 935282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 936282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name = String16(block.getAttributeStringValue(nameIdx, &len)); 937282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 938282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t ident = 0; 939282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t identIdx = block.indexOfAttribute(NULL, "id"); 940282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (identIdx >= 0) { 941282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* identStr = block.getAttributeStringValue(identIdx, &len); 942282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value identValue; 943282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!ResTable::stringToInt(identStr, len, &identValue)) { 944282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("Given 'id' attribute is not an integer: %s\n", 945282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getAttributeStringValue(identIdx, &len)).string()); 946282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 947282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 948282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ident = identValue.data; 949282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nextPublicId.replaceValueFor(type, ident+1); 950282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 951282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (nextPublicId.indexOfKey(type) < 0) { 952282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("No 'id' attribute supplied <public>," 953282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " and no previous id defined in this file.\n"); 954282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 955282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (!localHasErrors) { 956282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ident = nextPublicId.valueFor(type); 957282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nextPublicId.replaceValueFor(type, ident+1); 958282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 959282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 960282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!localHasErrors) { 961282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addPublic(srcPos, myPackage, type, name, ident); 962282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 963282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 964282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 965282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 966282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!localHasErrors) { 967282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R")); 968282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols != NULL) { 969282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols = symbols->addNestedSymbol(String8(type), srcPos); 970282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 971282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols != NULL) { 972282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols->makeSymbolPublic(String8(name), srcPos); 973282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment( 974282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.getComment(&len) ? block.getComment(&len) : nulStr); 975282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols->appendComment(String8(name), comment, srcPos); 976282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 977282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("Unable to create symbols!\n"); 978282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 979282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 980282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 981282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 982282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 983282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 984282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), public16.string()) == 0) { 985282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 986282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 987282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 988282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 989282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 990282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 991282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), public_padding16.string()) == 0) { 992282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos srcPos(in->getPrintableSource(), block.getLineNumber()); 993282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 994282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 type; 995282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t typeIdx = block.indexOfAttribute(NULL, "type"); 996282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (typeIdx < 0) { 997282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("A 'type' attribute is required for <public-padding>\n"); 998282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 999282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1000282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type = String16(block.getAttributeStringValue(typeIdx, &len)); 1001282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1002282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 name; 1003282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t nameIdx = block.indexOfAttribute(NULL, "name"); 1004282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (nameIdx < 0) { 1005282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("A 'name' attribute is required for <public-padding>\n"); 1006282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1007282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1008282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name = String16(block.getAttributeStringValue(nameIdx, &len)); 1009282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1010282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t start = 0; 1011282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t startIdx = block.indexOfAttribute(NULL, "start"); 1012282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (startIdx >= 0) { 1013282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* startStr = block.getAttributeStringValue(startIdx, &len); 1014282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value startValue; 1015282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!ResTable::stringToInt(startStr, len, &startValue)) { 1016282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("Given 'start' attribute is not an integer: %s\n", 1017282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getAttributeStringValue(startIdx, &len)).string()); 1018282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1019282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1020282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski start = startValue.data; 1021282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1022282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (nextPublicId.indexOfKey(type) < 0) { 1023282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("No 'start' attribute supplied <public-padding>," 1024282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " and no previous id defined in this file.\n"); 1025282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1026282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (!localHasErrors) { 1027282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski start = nextPublicId.valueFor(type); 1028282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1029282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1030282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t end = 0; 1031282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t endIdx = block.indexOfAttribute(NULL, "end"); 1032282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (endIdx >= 0) { 1033282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* endStr = block.getAttributeStringValue(endIdx, &len); 1034282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value endValue; 1035282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!ResTable::stringToInt(endStr, len, &endValue)) { 1036282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("Given 'end' attribute is not an integer: %s\n", 1037282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getAttributeStringValue(endIdx, &len)).string()); 1038282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1039282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1040282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski end = endValue.data; 1041282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1042282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1043282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("No 'end' attribute supplied <public-padding>\n"); 1044282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1045282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1046282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1047282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (end >= start) { 1048282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nextPublicId.replaceValueFor(type, end+1); 1049282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1050282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("Padding start '%ul' is after end '%ul'\n", 1051282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski start, end); 1052282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1053282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1054282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1055282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment( 1056282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.getComment(&len) ? block.getComment(&len) : nulStr); 1057282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (uint32_t curIdent=start; curIdent<=end; curIdent++) { 1058282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (localHasErrors) { 1059282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1060282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1061282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 curName(name); 1062282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char buf[64]; 1063282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sprintf(buf, "%d", (int)(end-curIdent+1)); 1064282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curName.append(String16(buf)); 1065282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1066282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addEntry(srcPos, myPackage, type, curName, 1067282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16("padding"), NULL, &curParams, false, 1068282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_map::TYPE_STRING, overwrite); 1069282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 1070282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1071282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1072282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1073282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->addPublic(srcPos, myPackage, type, 1074282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curName, curIdent); 1075282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { 1076282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1077282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1078282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1079282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R")); 1080282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols != NULL) { 1081282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols = symbols->addNestedSymbol(String8(type), srcPos); 1082282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1083282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols != NULL) { 1084282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols->makeSymbolPublic(String8(curName), srcPos); 1085282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols->appendComment(String8(curName), comment, srcPos); 1086282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1087282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("Unable to create symbols!\n"); 1088282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1089282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1090282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1091282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1092282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 1093282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 1094282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), public_padding16.string()) == 0) { 1095282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1096282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1097282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1098282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1099282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), private_symbols16.string()) == 0) { 1102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 pkg; 1103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t pkgIdx = block.indexOfAttribute(NULL, "package"); 1104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pkgIdx < 0) { 1105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "A 'package' attribute is required for <private-symbols>\n"); 1107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pkg = String16(block.getAttributeStringValue(pkgIdx, &len)); 1110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!localHasErrors) { 1111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assets->setSymbolsPrivatePackage(String8(pkg)); 1112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 1115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 1116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), private_symbols16.string()) == 0) { 1117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), java_symbol16.string()) == 0) { 1124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos srcPos(in->getPrintableSource(), block.getLineNumber()); 1125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 type; 1127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t typeIdx = block.indexOfAttribute(NULL, "type"); 1128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (typeIdx < 0) { 1129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("A 'type' attribute is required for <public>\n"); 1130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type = String16(block.getAttributeStringValue(typeIdx, &len)); 1133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 name; 1135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t nameIdx = block.indexOfAttribute(NULL, "name"); 1136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (nameIdx < 0) { 1137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("A 'name' attribute is required for <public>\n"); 1138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name = String16(block.getAttributeStringValue(nameIdx, &len)); 1141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> symbols = assets->getJavaSymbolsFor(String8("R")); 1143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols != NULL) { 1144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols = symbols->addNestedSymbol(String8(type), srcPos); 1145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols != NULL) { 1147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols->makeSymbolJavaSymbol(String8(name), srcPos); 1148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment( 1149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.getComment(&len) ? block.getComment(&len) : nulStr); 1150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols->appendComment(String8(name), comment, srcPos); 1151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("Unable to create symbols!\n"); 1153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 1157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 1158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), java_symbol16.string()) == 0) { 1159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), add_resource16.string()) == 0) { 1167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos srcPos(in->getPrintableSource(), block.getLineNumber()); 1168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 typeName; 1170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t typeIdx = block.indexOfAttribute(NULL, "type"); 1171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (typeIdx < 0) { 1172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("A 'type' attribute is required for <add-resource>\n"); 1173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeName = String16(block.getAttributeStringValue(typeIdx, &len)); 1176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 name; 1178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t nameIdx = block.indexOfAttribute(NULL, "name"); 1179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (nameIdx < 0) { 1180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("A 'name' attribute is required for <add-resource>\n"); 1181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name = String16(block.getAttributeStringValue(nameIdx, &len)); 1184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outTable->canAddEntry(srcPos, myPackage, typeName, name); 1186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 1188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 1189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), add_resource16.string()) == 0) { 1190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), declare_styleable16.string()) == 0) { 1197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos srcPos(in->getPrintableSource(), block.getLineNumber()); 1198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 ident; 1200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t identIdx = block.indexOfAttribute(NULL, "name"); 1201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (identIdx < 0) { 1202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("A 'name' attribute is required for <declare-styleable>\n"); 1203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ident = String16(block.getAttributeStringValue(identIdx, &len)); 1206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R")); 1208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!localHasErrors) { 1209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols != NULL) { 1210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols = symbols->addNestedSymbol(String8("styleable"), srcPos); 1211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptSymbols> styleSymbols = symbols; 1213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols != NULL) { 1214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols = symbols->addNestedSymbol(String8(ident), srcPos); 1215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols == NULL) { 1217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcPos.error("Unable to create symbols!\n"); 1218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment( 1222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.getComment(&len) ? block.getComment(&len) : nulStr); 1223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski styleSymbols->appendComment(String8(ident), comment, srcPos); 1224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols = NULL; 1226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { 1229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::START_TAG) { 1230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), skip16.string()) == 0) { 1231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT 1232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski && code != ResXMLTree::BAD_DOCUMENT) { 1233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 1234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), skip16.string()) == 0) { 1235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) { 1241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT 1242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski && code != ResXMLTree::BAD_DOCUMENT) { 1243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::END_TAG) { 1244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) { 1245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), attr16.string()) != 0) { 1251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Tag <%s> can not appear inside <declare-styleable>, only <attr>\n", 1253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getElementName(&len)).string()); 1254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment( 1258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.getComment(&len) ? block.getComment(&len) : nulStr); 1259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 itemIdent; 1260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = compileAttribute(in, block, myPackage, outTable, &itemIdent, true); 1261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (symbols != NULL) { 1266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos srcPos(String8(in->getPrintableSource()), block.getLineNumber()); 1267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols->addSymbol(String8(itemIdent), 0, srcPos); 1268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski symbols->appendComment(String8(itemIdent), comment, srcPos); 1269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Attribute %s comment: %s\n", String8(itemIdent).string(), 1270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(comment).string()); 1271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (code == ResXMLTree::END_TAG) { 1273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), declare_styleable16.string()) == 0) { 1274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Found tag </%s> where </attr> is expected\n", 1279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getElementName(&len)).string()); 1280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), attr16.string()) == 0) { 1286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = compileAttribute(in, block, myPackage, outTable, NULL); 1287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 1289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), item16.string()) == 0) { 1293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &item16; 1294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t attri = block.indexOfAttribute(NULL, "type"); 1295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (attri >= 0) { 1296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = String16(block.getAttributeStringValue(attri, &len)); 1297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t formatIdx = block.indexOfAttribute(NULL, "format"); 1298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (formatIdx >= 0) { 1299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 formatStr = String16(block.getAttributeStringValue( 1300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski formatIdx, &len)); 1301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = parse_flags(formatStr.string(), formatStr.size(), 1302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski gFormatFlags); 1303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (curFormat == 0) { 1304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Tag <item> 'format' attribute value \"%s\" not valid\n", 1306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(formatStr).string()); 1307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "A 'type' attribute is required for <item>\n"); 1313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsStyled = true; 1316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), string16.string()) == 0) { 1317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Note the existence and locale of every string we process 131891447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath char rawLocale[RESTABLE_MAX_LOCALE_LEN]; 131991447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath curParams.getBcp47Locale(rawLocale); 1320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 locale(rawLocale); 1321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 name; 1322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 translatable; 1323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 formatted; 1324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t n = block.getAttributeCount(); 1326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i = 0; i < n; i++) { 1327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t length; 1328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const uint16_t* attr = block.getAttributeName(i, &length); 1329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(attr, name16.string()) == 0) { 1330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski name.setTo(block.getAttributeStringValue(i, &length)); 1331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(attr, translatable16.string()) == 0) { 1332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski translatable.setTo(block.getAttributeStringValue(i, &length)); 1333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(attr, formatted16.string()) == 0) { 1334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski formatted.setTo(block.getAttributeStringValue(i, &length)); 1335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name.size() > 0) { 1339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (translatable == false16) { 1340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsFormatted = false; 1341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Untranslatable strings must only exist in the default [empty] locale 1342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (locale.size() > 0) { 1343a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).warning( 1344a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski "string '%s' marked untranslatable but exists in locale '%s'\n", 1345a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski String8(name).string(), 1346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski locale.string()); 1347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // hasErrors = localHasErrors = true; 1348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Intentionally empty block: 1350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // 1351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Don't add untranslatable strings to the localization table; that 1352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // way if we later see localizations of them, they'll be flagged as 1353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // having no default translation. 1354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1356a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski outTable->addLocalization( 1357a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski name, 1358a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski locale, 1359a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber())); 1360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (formatted == false16) { 1363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsFormatted = false; 1364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &string16; 1368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = string16; 1369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_STRING; 1370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsStyled = true; 137184410b054c7db0b6685a0f15cb2d1ffcb264f6c9Igor Viarheichyk curIsPseudolocalizable = fileIsTranslatable && (translatable != false16); 1372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), drawable16.string()) == 0) { 1373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &drawable16; 1374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = drawable16; 1375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_COLOR; 1376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), color16.string()) == 0) { 1377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &color16; 1378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = color16; 1379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_COLOR; 1380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), bool16.string()) == 0) { 1381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &bool16; 1382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = bool16; 1383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_BOOLEAN; 1384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), integer16.string()) == 0) { 1385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &integer16; 1386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = integer16; 1387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_INTEGER; 1388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), dimen16.string()) == 0) { 1389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &dimen16; 1390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = dimen16; 1391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_DIMENSION; 1392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), fraction16.string()) == 0) { 1393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &fraction16; 1394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = fraction16; 1395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_FRACTION; 1396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), bag16.string()) == 0) { 1397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &bag16; 1398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsBag = true; 1399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t attri = block.indexOfAttribute(NULL, "type"); 1400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (attri >= 0) { 1401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = String16(block.getAttributeStringValue(attri, &len)); 1402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "A 'type' attribute is required for <bag>\n"); 1405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), style16.string()) == 0) { 1408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &style16; 1409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = style16; 1410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsBag = true; 1411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), plurals16.string()) == 0) { 1412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &plurals16; 1413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = plurals16; 1414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsBag = true; 1415a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin curIsPseudolocalizable = fileIsTranslatable; 1416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), array16.string()) == 0) { 1417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &array16; 1418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = array16; 1419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsBag = true; 1420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsBagReplaceOnOverwrite = true; 1421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t formatIdx = block.indexOfAttribute(NULL, "format"); 1422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (formatIdx >= 0) { 1423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 formatStr = String16(block.getAttributeStringValue( 1424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski formatIdx, &len)); 1425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = parse_flags(formatStr.string(), formatStr.size(), 1426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski gFormatFlags); 1427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (curFormat == 0) { 1428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Tag <array> 'format' attribute value \"%s\" not valid\n", 1430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(formatStr).string()); 1431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), string_array16.string()) == 0) { 1435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Check whether these strings need valid formats. 1436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // (simplified form of what string16 does above) 1437a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin bool isTranslatable = false; 1438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t n = block.getAttributeCount(); 14399a9fa163c384e7fff159d339dfcce3b3122bece5Narayan Kamath 14409a9fa163c384e7fff159d339dfcce3b3122bece5Narayan Kamath // Pseudolocalizable by default, unless this string array isn't 14419a9fa163c384e7fff159d339dfcce3b3122bece5Narayan Kamath // translatable. 1442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i = 0; i < n; i++) { 1443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t length; 1444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const uint16_t* attr = block.getAttributeName(i, &length); 1445a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin if (strcmp16(attr, formatted16.string()) == 0) { 14469a9fa163c384e7fff159d339dfcce3b3122bece5Narayan Kamath const uint16_t* value = block.getAttributeStringValue(i, &length); 14479a9fa163c384e7fff159d339dfcce3b3122bece5Narayan Kamath if (strcmp16(value, false16.string()) == 0) { 1448a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin curIsFormatted = false; 14499a9fa163c384e7fff159d339dfcce3b3122bece5Narayan Kamath } 1450a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin } else if (strcmp16(attr, translatable16.string()) == 0) { 1451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const uint16_t* value = block.getAttributeStringValue(i, &length); 1452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(value, false16.string()) == 0) { 1453a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin isTranslatable = false; 1454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &string_array16; 1459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = array16; 1460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_STRING; 1461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsBag = true; 1462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsBagReplaceOnOverwrite = true; 1463a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin curIsPseudolocalizable = isTranslatable && fileIsTranslatable; 1464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (strcmp16(block.getElementName(&len), integer_array16.string()) == 0) { 1465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curTag = &integer_array16; 1466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curType = array16; 1467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_INTEGER; 1468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsBag = true; 1469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski curIsBagReplaceOnOverwrite = true; 1470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Found tag %s where item is expected\n", 1473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getElementName(&len)).string()); 1474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 ident; 1478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t identIdx = block.indexOfAttribute(NULL, "name"); 1479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (identIdx >= 0) { 1480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ident = String16(block.getAttributeStringValue(identIdx, &len)); 1481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "A 'name' attribute is required for <%s>\n", 1484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(*curTag).string()); 1485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 product; 1489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski identIdx = block.indexOfAttribute(NULL, "product"); 1490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (identIdx >= 0) { 1491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski product = String16(block.getAttributeStringValue(identIdx, &len)); 1492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment(block.getComment(&len) ? block.getComment(&len) : nulStr); 1495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (curIsBag) { 1497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Figure out the parent of this bag... 1498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 parentIdent; 1499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t parentIdentIdx = block.indexOfAttribute(NULL, "parent"); 1500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (parentIdentIdx >= 0) { 1501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski parentIdent = String16(block.getAttributeStringValue(parentIdentIdx, &len)); 1502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t sep = ident.findLast('.'); 1504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (sep >= 0) { 1505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski parentIdent.setTo(ident, sep); 1506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!localHasErrors) { 1510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = outTable->startBag(SourcePos(in->getPrintableSource(), 1511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.getLineNumber()), myPackage, curType, ident, 1512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski parentIdent, &curParams, 1513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski overwrite, curIsBagReplaceOnOverwrite); 1514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t elmIndex = 0; 1520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char elmIndexStr[14]; 1521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((code=block.next()) != ResXMLTree::END_DOCUMENT 1522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski && code != ResXMLTree::BAD_DOCUMENT) { 1523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (code == ResXMLTree::START_TAG) { 1525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), item16.string()) != 0) { 1526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Tag <%s> can not appear inside <%s>, only <item>\n", 1528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getElementName(&len)).string(), 1529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(*curTag).string()); 1530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 itemIdent; 1534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (curType == array16) { 1535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sprintf(elmIndexStr, "^index_%d", (int)elmIndex++); 1536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent = String16(elmIndexStr); 1537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (curType == plurals16) { 1538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t itemIdentIdx = block.indexOfAttribute(NULL, "quantity"); 1539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (itemIdentIdx >= 0) { 1540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 quantity16(block.getAttributeStringValue(itemIdentIdx, &len)); 1541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (quantity16 == other16) { 1542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent = quantityOther16; 1543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (quantity16 == zero16) { 1545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent = quantityZero16; 1546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (quantity16 == one16) { 1548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent = quantityOne16; 1549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (quantity16 == two16) { 1551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent = quantityTwo16; 1552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (quantity16 == few16) { 1554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent = quantityFew16; 1555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (quantity16 == many16) { 1557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent = quantityMany16; 1558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else { 1560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Illegal 'quantity' attribute is <item> inside <plurals>\n"); 1562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "A 'quantity' attribute is required for <item> inside <plurals>\n"); 1567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t itemIdentIdx = block.indexOfAttribute(NULL, "name"); 1571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (itemIdentIdx >= 0) { 1572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itemIdent = String16(block.getAttributeStringValue(itemIdentIdx, &len)); 1573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "A 'name' attribute is required for <item>\n"); 1576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLParser::ResXMLPosition parserPosition; 1581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.getPosition(&parserPosition); 1582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = parseAndAddBag(bundle, in, &block, curParams, myPackage, curType, 1584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ident, parentIdent, itemIdent, curFormat, curIsFormatted, 1585a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin product, NO_PSEUDOLOCALIZATION, overwrite, outTable); 1586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err == NO_ERROR) { 1587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (curIsPseudolocalizable && localeIsDefined(curParams) 1588a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin && bundle->getPseudolocalize() > 0) { 1589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pseudolocalize here 1590a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin if ((PSEUDO_ACCENTED & bundle->getPseudolocalize()) == 1591a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin PSEUDO_ACCENTED) { 1592a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin block.setPosition(parserPosition); 1593a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin err = parseAndAddBag(bundle, in, &block, pseudoParams, myPackage, 1594a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin curType, ident, parentIdent, itemIdent, curFormat, 1595a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin curIsFormatted, product, PSEUDO_ACCENTED, 1596a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin overwrite, outTable); 1597a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin } 1598a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin if ((PSEUDO_BIDI & bundle->getPseudolocalize()) == 1599a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin PSEUDO_BIDI) { 1600a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin block.setPosition(parserPosition); 1601a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin err = parseAndAddBag(bundle, in, &block, pseudoBidiParams, myPackage, 1602a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin curType, ident, parentIdent, itemIdent, curFormat, 1603a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin curIsFormatted, product, PSEUDO_BIDI, 1604a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin overwrite, outTable); 1605a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin } 1606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1607a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin } 1608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (code == ResXMLTree::END_TAG) { 1612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), curTag->string()) != 0) { 1613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Found tag </%s> where </%s> is expected\n", 1615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getElementName(&len)).string(), 1616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(*curTag).string()); 1617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 1620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResXMLParser::ResXMLPosition parserPosition; 1624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski block.getPosition(&parserPosition); 1625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = parseAndAddEntry(bundle, in, &block, curParams, myPackage, curType, ident, 1627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *curTag, curIsStyled, curFormat, curIsFormatted, 1628a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin product, NO_PSEUDOLOCALIZATION, overwrite, &skippedResourceNames, outTable); 1629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err < NO_ERROR) { // Why err < NO_ERROR instead of err != NO_ERROR? 1631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (err == NO_ERROR) { 1634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (curIsPseudolocalizable && localeIsDefined(curParams) 1635a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin && bundle->getPseudolocalize() > 0) { 1636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pseudolocalize here 1637a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin if ((PSEUDO_ACCENTED & bundle->getPseudolocalize()) == 1638a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin PSEUDO_ACCENTED) { 1639a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin block.setPosition(parserPosition); 1640a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin err = parseAndAddEntry(bundle, in, &block, pseudoParams, myPackage, curType, 1641a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin ident, *curTag, curIsStyled, curFormat, 1642a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin curIsFormatted, product, 1643a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin PSEUDO_ACCENTED, overwrite, &skippedResourceNames, outTable); 1644a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin } 1645a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin if ((PSEUDO_BIDI & bundle->getPseudolocalize()) == 1646a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin PSEUDO_BIDI) { 1647a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin block.setPosition(parserPosition); 1648a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin err = parseAndAddEntry(bundle, in, &block, pseudoBidiParams, 1649a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin myPackage, curType, ident, *curTag, curIsStyled, curFormat, 1650a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin curIsFormatted, product, 1651a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin PSEUDO_BIDI, overwrite, &skippedResourceNames, outTable); 1652a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin } 1653282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1654282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = localHasErrors = true; 1655282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1656282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1657282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1658282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1659282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1660282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#if 0 1661282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() > 0) { 1662282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Comment for @%s:%s/%s: %s\n", String8(myPackage).string(), 1663282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(curType).string(), String8(ident).string(), 1664282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(comment).string()); 1665282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 1667282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!localHasErrors) { 1668282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outTable->appendComment(myPackage, curType, ident, comment, false); 1669282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (code == ResXMLTree::END_TAG) { 1672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp16(block.getElementName(&len), resources16.string()) != 0) { 1673282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Unexpected end tag %s\n", String8(block.getElementName(&len)).string()); 1675282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (code == ResXMLTree::START_NAMESPACE || code == ResXMLTree::END_NAMESPACE) { 1679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (code == ResXMLTree::TEXT) { 1681282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (isWhitespace(block.getText(&len))) { 1682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 1683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SourcePos(in->getPrintableSource(), block.getLineNumber()).error( 1685282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Found text \"%s\" where item tag is expected\n", 1686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(block.getText(&len)).string()); 1687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1689282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 16918ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski // For every resource defined, there must be exist one variant with a product attribute 16928ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski // set to 'default' (or no product attribute at all). 16938ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski // We check to see that for every resource that was ignored because of a mismatched 16948ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski // product attribute, some product variant of that resource was processed. 16958ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski for (size_t i = 0; i < skippedResourceNames.size(); i++) { 16968ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski if (skippedResourceNames[i]) { 16978ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski const type_ident_pair_t& p = skippedResourceNames.keyAt(i); 16988ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski if (!outTable->hasBagOrEntry(myPackage, p.type, p.ident)) { 16998ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski const char* bundleProduct = 17008ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski (bundle->getProduct() == NULL) ? "" : bundle->getProduct(); 17018ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski fprintf(stderr, "In resource file %s: %s\n", 17028ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski in->getPrintableSource().string(), 17038ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski curParams.toString().string()); 17048ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski 17058ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski fprintf(stderr, "\t%s '%s' does not match product %s.\n" 17068ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski "\tYou may have forgotten to include a 'default' product variant" 17078ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski " of the resource.\n", 17088ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski String8(p.type).string(), String8(p.ident).string(), 17098ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski bundleProduct[0] == 0 ? "default" : bundleProduct); 17108ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski return UNKNOWN_ERROR; 17118ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski } 17128ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski } 17138ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski } 17148ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski 1715282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return hasErrors ? UNKNOWN_ERROR : NO_ERROR; 1716282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1717282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1718833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam LesinskiResourceTable::ResourceTable(Bundle* bundle, const String16& assetsPackage, ResourceTable::PackageType type) 1719833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski : mAssetsPackage(assetsPackage) 1720833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski , mPackageType(type) 1721833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski , mTypeIdOffset(0) 1722833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski , mNumLocal(0) 1723833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski , mBundle(bundle) 1724833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski{ 1725833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski ssize_t packageId = -1; 1726833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski switch (mPackageType) { 1727833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski case App: 1728833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski case AppFeature: 1729833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski packageId = 0x7f; 1730833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski break; 1731833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 1732833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski case System: 1733833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski packageId = 0x01; 1734833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski break; 1735833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 1736833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski case SharedLibrary: 1737833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski packageId = 0x00; 1738833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski break; 1739833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 1740833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski default: 1741833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski assert(0); 1742833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski break; 1743833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 1744833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski sp<Package> package = new Package(mAssetsPackage, packageId); 1745833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski mPackages.add(assetsPackage, package); 1746833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski mOrderedPackages.add(package); 1747833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 1748833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski // Every resource table always has one first entry, the bag attributes. 1749833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski const SourcePos unknown(String8("????"), 0); 1750833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski getType(mAssetsPackage, String16("attr"), unknown); 1751833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski} 1752833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 1753833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinskistatic uint32_t findLargestTypeIdForPackage(const ResTable& table, const String16& packageName) { 1754833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski const size_t basePackageCount = table.getBasePackageCount(); 1755833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski for (size_t i = 0; i < basePackageCount; i++) { 1756833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (packageName == table.getBasePackageName(i)) { 1757833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski return table.getLastTypeIdForPackage(i); 1758833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 1759833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 1760833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski return 0; 1761282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1762282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1763282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::addIncludedResources(Bundle* bundle, const sp<AaptAssets>& assets) 1764282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1765282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = assets->buildIncludedResources(bundle); 1766282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 1767282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 1768282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1769282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1770282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mAssets = assets; 1771833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski mTypeIdOffset = findLargestTypeIdForPackage(assets->getIncludedResources(), mAssetsPackage); 1772833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 1773833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski const String8& featureAfter = bundle->getFeatureAfterPackage(); 1774833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (!featureAfter.isEmpty()) { 1775833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski AssetManager featureAssetManager; 1776833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (!featureAssetManager.addAssetPath(featureAfter, NULL)) { 1777833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski fprintf(stderr, "ERROR: Feature package '%s' not found.\n", 1778833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski featureAfter.string()); 1779833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski return UNKNOWN_ERROR; 1780282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1781282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1782833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski const ResTable& featureTable = featureAssetManager.getResources(false); 1783833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski mTypeIdOffset = max(mTypeIdOffset, 1784833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski findLargestTypeIdForPackage(featureTable, mAssetsPackage)); 1785833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 1786282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1787282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 1788282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1789282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1790282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::addPublic(const SourcePos& sourcePos, 1791282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& package, 1792282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 1793282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 1794282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const uint32_t ident) 1795282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1796282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t rid = mAssets->getIncludedResources() 1797282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .identifierForName(name.string(), name.size(), 1798282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type.string(), type.size(), 1799282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski package.string(), package.size()); 1800282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (rid != 0) { 1801282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Error declaring public resource %s/%s for included package %s\n", 1802282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(type).string(), String8(name).string(), 1803282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(package).string()); 1804282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1805282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1806282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1807282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = getType(package, type, sourcePos); 1808282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) { 1809282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1810282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1811282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return t->addPublic(sourcePos, name, ident); 1812282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1813282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1814282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::addEntry(const SourcePos& sourcePos, 1815282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& package, 1816282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 1817282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 1818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& value, 1819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<StringPool::entry_style_span>* style, 1820282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config* params, 1821282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool doSetIndex, 1822282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const int32_t format, 1823282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool overwrite) 1824282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 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) { 1830833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski sourcePos.error("Resource entry %s/%s is already defined in package %s.", 1831833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski String8(type).string(), String8(name).string(), String8(package).string()); 1832833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski return UNKNOWN_ERROR; 1833282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1834282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1835282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = getEntry(package, type, name, sourcePos, overwrite, 1836282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski params, doSetIndex); 1837282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e == NULL) { 1838282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1839282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1840282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = e->setItem(sourcePos, value, style, format, overwrite); 1841282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err == NO_ERROR) { 1842282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mNumLocal++; 1843282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1844282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 1845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::startBag(const SourcePos& sourcePos, 1848282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& package, 1849282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 1850282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 1851282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& bagParent, 1852282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config* params, 1853282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool overlay, 1854282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool replace, bool isId) 1855282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t result = NO_ERROR; 1857282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1858282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Check for adding entries in other packages... for now we do 1859282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // nothing. We need to do the right thing here to support skinning. 1860282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t rid = mAssets->getIncludedResources() 1861282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .identifierForName(name.string(), name.size(), 1862282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type.string(), type.size(), 1863282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski package.string(), package.size()); 1864282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (rid != 0) { 1865833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski sourcePos.error("Resource entry %s/%s is already defined in package %s.", 1866833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski String8(type).string(), String8(name).string(), String8(package).string()); 1867833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski return UNKNOWN_ERROR; 1868282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1869833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 1870282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (overlay && !mBundle->getAutoAddOverlay() && !hasBagOrEntry(package, type, name)) { 1871282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool canAdd = false; 1872282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mPackages.valueFor(package); 1873282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p != NULL) { 1874282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getTypes().valueFor(type); 1875282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t != NULL) { 1876282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t->getCanAddEntries().indexOf(name) >= 0) { 1877282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski canAdd = true; 1878282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1879282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1880282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1881282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!canAdd) { 1882282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Resource does not already exist in overlay at '%s'; use <add-resource> to add.\n", 1883282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(name).string()); 1884282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1885282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1886282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1887282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = getEntry(package, type, name, sourcePos, overlay, params); 1888282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e == NULL) { 1889282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1890282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1891282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1892282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If a parent is explicitly specified, set it. 1893282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bagParent.size() > 0) { 1894282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski e->setParent(bagParent); 1895282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1896282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1897282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((result = e->makeItABag(sourcePos)) != NO_ERROR) { 1898282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return result; 1899282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1900282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1901282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (overlay && replace) { 1902282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return e->emptyBag(sourcePos); 1903282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1904282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return result; 1905282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1906282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1907282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::addBag(const SourcePos& sourcePos, 1908282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& package, 1909282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 1910282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 1911282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& bagParent, 1912282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& bagKey, 1913282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& value, 1914282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<StringPool::entry_style_span>* style, 1915282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config* params, 1916282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool replace, bool isId, const int32_t format) 1917282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1918282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Check for adding entries in other packages... for now we do 1919282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // nothing. We need to do the right thing here to support skinning. 1920282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t rid = mAssets->getIncludedResources() 1921282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .identifierForName(name.string(), name.size(), 1922282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type.string(), type.size(), 1923282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski package.string(), package.size()); 1924282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (rid != 0) { 1925282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 1926282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1927282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1928282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#if 0 1929282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (name == String16("left")) { 1930282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Adding bag left: file=%s, line=%d, type=%s\n", 1931282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.file.striing(), sourcePos.line, String8(type).string()); 1932282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1933282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 1934282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = getEntry(package, type, name, sourcePos, replace, params); 1935282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e == NULL) { 1936282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 1937282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1938282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1939282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If a parent is explicitly specified, set it. 1940282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bagParent.size() > 0) { 1941282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski e->setParent(bagParent); 1942282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1943282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1944282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool first = e->getBag().indexOfKey(bagKey) < 0; 1945282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = e->addToBag(sourcePos, bagKey, value, style, replace, isId, format); 1946282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err == NO_ERROR && first) { 1947282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mNumLocal++; 1948282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1949282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 1950282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1951282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1952282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::hasBagOrEntry(const String16& package, 1953282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 1954282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name) const 1955282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1956282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // First look for this in the included resources... 1957282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t rid = mAssets->getIncludedResources() 1958282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .identifierForName(name.string(), name.size(), 1959282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type.string(), type.size(), 1960282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski package.string(), package.size()); 1961282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (rid != 0) { 1962282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 1963282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1964282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1965282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mPackages.valueFor(package); 1966282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p != NULL) { 1967282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getTypes().valueFor(type); 1968282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t != NULL) { 1969282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getConfigs().valueFor(name); 1970282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c != NULL) return true; 1971282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1972282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1973282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1974282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 1975282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1976282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1977282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::hasBagOrEntry(const String16& package, 1978282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 1979282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 1980282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config& config) const 1981282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 1982282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // First look for this in the included resources... 1983282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t rid = mAssets->getIncludedResources() 1984282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .identifierForName(name.string(), name.size(), 1985282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type.string(), type.size(), 1986282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski package.string(), package.size()); 1987282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (rid != 0) { 1988282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 1989282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1990282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1991282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mPackages.valueFor(package); 1992282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p != NULL) { 1993282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getTypes().valueFor(type); 1994282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t != NULL) { 1995282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getConfigs().valueFor(name); 1996282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c != NULL) { 1997282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = c->getEntries().valueFor(config); 1998282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e != NULL) { 1999282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2000282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2001282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2002282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2003282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2004282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2005282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2006282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2007282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2008282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::hasBagOrEntry(const String16& ref, 2009282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16* defType, 2010282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16* defPackage) 2011282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2012282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 package, type, name; 2013282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!ResTable::expandResourceRef(ref.string(), ref.size(), &package, &type, &name, 2014282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski defType, defPackage ? defPackage:&mAssetsPackage, NULL)) { 2015282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2016282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2017282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return hasBagOrEntry(package, type, name); 2018282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2019282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2020282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::appendComment(const String16& package, 2021282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 2022282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 2023282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& comment, 2024282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool onlyIfEmpty) 2025282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2026282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() <= 0) { 2027282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2028282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2029282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2030282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mPackages.valueFor(package); 2031282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p != NULL) { 2032282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getTypes().valueFor(type); 2033282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t != NULL) { 2034282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getConfigs().valueFor(name); 2035282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c != NULL) { 2036282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c->appendComment(comment, onlyIfEmpty); 2037282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2038282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2039282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2040282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2041282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2042282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2043282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2044282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::appendTypeComment(const String16& package, 2045282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 2046282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 2047282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& comment) 2048282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2049282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() <= 0) { 2050282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2051282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2052282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2053282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mPackages.valueFor(package); 2054282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p != NULL) { 2055282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getTypes().valueFor(type); 2056282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t != NULL) { 2057282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getConfigs().valueFor(name); 2058282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c != NULL) { 2059282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c->appendTypeComment(comment); 2060282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2061282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2062282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2063282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2064282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2065282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2066282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2067282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ResourceTable::canAddEntry(const SourcePos& pos, 2068282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& package, const String16& type, const String16& name) 2069282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2070282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = getType(package, type, pos); 2071282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t != NULL) { 2072282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski t->canAddEntry(name); 2073282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2074282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2075282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2076282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisize_t ResourceTable::size() const { 2077282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mPackages.size(); 2078282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2079282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2080282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisize_t ResourceTable::numLocalResources() const { 2081282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mNumLocal; 2082282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2083282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2084282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::hasResources() const { 2085282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mNumLocal > 0; 2086282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2087282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 208827f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinskisp<AaptFile> ResourceTable::flatten(Bundle* bundle, const sp<const ResourceFilter>& filter, 208927f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski const bool isBase) 2090282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2091282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> data = new AaptFile(String8(), AaptGroupEntry(), String8()); 209227f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski status_t err = flatten(bundle, filter, data, isBase); 2093282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err == NO_ERROR ? data : NULL; 2094282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2095282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2096282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiinline uint32_t ResourceTable::getResId(const sp<Package>& p, 2097282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const sp<Type>& t, 2098282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t nameId) 2099282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return makeResId(p->getAssignedId(), t->getIndex(), nameId); 2101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiuint32_t ResourceTable::getResId(const String16& package, 2104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 2105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 2106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool onlyPublic) const 2107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t id = ResourceIdCache::lookup(package, type, name, onlyPublic); 2109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (id != 0) return id; // cache hit 2110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // First look for this in the included resources... 2112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t specFlags = 0; 2113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t rid = mAssets->getIncludedResources() 2114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .identifierForName(name.string(), name.size(), 2115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski type.string(), type.size(), 2116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski package.string(), package.size(), 2117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski &specFlags); 2118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (rid != 0) { 2119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (onlyPublic) { 2120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((specFlags & ResTable_typeSpec::SPEC_PUBLIC) == 0) { 2121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 2122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2125833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski return ResourceIdCache::store(package, type, name, onlyPublic, rid); 2126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2128833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski sp<Package> p = mPackages.valueFor(package); 2129833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (p == NULL) return 0; 2130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getTypes().valueFor(type); 2131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) return 0; 2132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getConfigs().valueFor(name); 2133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == NULL) return 0; 2134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t ei = c->getEntryIndex(); 2135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (ei < 0) return 0; 2136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ResourceIdCache::store(package, type, name, onlyPublic, 2138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getResId(p, t, ei)); 2139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiuint32_t ResourceTable::getResId(const String16& ref, 2142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16* defType, 2143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16* defPackage, 2144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char** outErrorMsg, 2145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool onlyPublic) const 2146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 package, type, name; 2148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool refOnlyPublic = true; 2149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!ResTable::expandResourceRef( 2150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ref.string(), ref.size(), &package, &type, &name, 2151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski defType, defPackage ? defPackage:&mAssetsPackage, 2152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outErrorMsg, &refOnlyPublic)) { 2153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Expanding resource: ref=%s\n", 2154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(ref).string())); 2155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Expanding resource: defType=%s\n", 2156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski defType ? String8(*defType).string() : "NULL")); 2157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Expanding resource: defPackage=%s\n", 2158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski defPackage ? String8(*defPackage).string() : "NULL")); 2159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Expanding resource: ref=%s\n", String8(ref).string())); 2160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Expanded resource: p=%s, t=%s, n=%s, res=0\n", 2161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(package).string(), String8(type).string(), 2162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(name).string())); 2163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 2164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t res = getResId(package, type, name, onlyPublic && refOnlyPublic); 2166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Expanded resource: p=%s, t=%s, n=%s, res=%d\n", 2167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(package).string(), String8(type).string(), 2168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(name).string(), res)); 2169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (res == 0) { 2170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outErrorMsg) 2171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outErrorMsg = "No resource found that matches the given name"; 2172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return res; 2174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::isValidResourceName(const String16& s) 2177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* p = s.string(); 2179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool first = true; 2180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (*p) { 2181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((*p >= 'a' && *p <= 'z') 2182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || (*p >= 'A' && *p <= 'Z') 2183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || *p == '_' 2184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || (!first && *p >= '0' && *p <= '9')) { 2185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski first = false; 2186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p++; 2187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::stringToValue(Res_value* outValue, StringPool* pool, 2195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& str, 2196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool preserveSpaces, bool coerceType, 2197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t attrID, 2198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<StringPool::entry_style_span>* style, 2199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16* outStr, void* accessorCookie, 2200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t attrType, const String8* configTypeName, 2201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ConfigDescription* config) 2202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 finalStr; 2204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool res = true; 2206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (style == NULL || style->size() == 0) { 2207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Text is not styled so it can be any type... let's figure it out. 2208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski res = mAssets->getIncludedResources() 2209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .stringToValue(outValue, &finalStr, str.string(), str.size(), preserveSpaces, 2210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski coerceType, attrID, NULL, &mAssetsPackage, this, 2211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski accessorCookie, attrType); 2212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Styled text can only be a string, and while collecting the style 2214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // information we have already processed that string! 2215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->size = sizeof(Res_value); 2216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->res0 = 0; 2217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->dataType = outValue->TYPE_STRING; 2218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->data = 0; 2219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski finalStr = str; 2220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!res) { 2223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outValue->dataType == outValue->TYPE_STRING) { 2227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Should do better merging styles. 2228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pool) { 2229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 configStr; 2230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (config != NULL) { 2231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski configStr = config->toString(); 2232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski configStr = "(null)"; 2234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Adding to pool string style #%d config %s: %s\n", 2236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski style != NULL ? style->size() : 0, 2237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski configStr.string(), String8(finalStr).string())); 2238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (style != NULL && style->size() > 0) { 2239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->data = pool->add(finalStr, *style, configTypeName, config); 2240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->data = pool->add(finalStr, true, configTypeName, config); 2242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Caller will fill this in later. 2245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->data = 0; 2246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (outStr) { 2249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outStr = finalStr; 2250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiuint32_t ResourceTable::getCustomResource( 2258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& package, const String16& type, const String16& name) const 2259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("getCustomResource: %s %s %s\n", String8(package).string(), 2261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(type).string(), String8(name).string()); 2262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mPackages.valueFor(package); 2263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p == NULL) return 0; 2264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getTypes().valueFor(type); 2265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) return 0; 2266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getConfigs().valueFor(name); 2267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == NULL) return 0; 2268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t ei = c->getEntryIndex(); 2269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (ei < 0) return 0; 2270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return getResId(p, t, ei); 2271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiuint32_t ResourceTable::getCustomResourceWithCreation( 2274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& package, const String16& type, const String16& name, 2275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool createIfNotFound) 2276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t resId = getCustomResource(package, type, name); 2278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (resId != 0 || !createIfNotFound) { 2279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return resId; 2280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2282f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski if (mAssetsPackage != package) { 2283833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski mCurrentXmlPos.error("creating resource for external package %s: %s/%s.", 2284f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski String8(package).string(), String8(type).string(), String8(name).string()); 2285833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (package == String16("android")) { 2286833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski mCurrentXmlPos.printf("did you mean to use @+id instead of @+android:id?"); 2287833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 2288833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski return 0; 2289f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski } 2290f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 2291f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski String16 value("false"); 2292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t status = addEntry(mCurrentXmlPos, package, type, name, value, NULL, NULL, true); 2293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (status == NO_ERROR) { 2294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resId = getResId(package, type, name); 2295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return resId; 2296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 2298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiuint32_t ResourceTable::getRemappedPackage(uint32_t origPackage) const 2301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return origPackage; 2303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::getAttributeType(uint32_t attrID, uint32_t* outType) 2306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("getAttributeType #%08x\n", attrID); 2308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value value; 2309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (getItemValue(attrID, ResTable_map::ATTR_TYPE, &value)) { 2310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("getAttributeType #%08x (%s): #%08x\n", attrID, 2311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(getEntry(attrID)->getName()).string(), value.data); 2312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outType = value.data; 2313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::getAttributeMin(uint32_t attrID, uint32_t* outMin) 2319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("getAttributeMin #%08x\n", attrID); 2321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value value; 2322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (getItemValue(attrID, ResTable_map::ATTR_MIN, &value)) { 2323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outMin = value.data; 2324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::getAttributeMax(uint32_t attrID, uint32_t* outMax) 2330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("getAttributeMax #%08x\n", attrID); 2332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value value; 2333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (getItemValue(attrID, ResTable_map::ATTR_MAX, &value)) { 2334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *outMax = value.data; 2335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiuint32_t ResourceTable::getAttributeL10N(uint32_t attrID) 2341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("getAttributeL10N #%08x\n", attrID); 2343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value value; 2344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (getItemValue(attrID, ResTable_map::ATTR_L10N, &value)) { 2345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return value.data; 2346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ResTable_map::L10N_NOT_REQUIRED; 2348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::getLocalizationSetting() 2351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mBundle->getRequireLocalization(); 2353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ResourceTable::reportError(void* accessorCookie, const char* fmt, ...) 2356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (accessorCookie != NULL && fmt != NULL) { 2358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AccessorCookie* ac = (AccessorCookie*)accessorCookie; 2359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int retval=0; 2360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char buf[1024]; 2361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski va_list ap; 2362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski va_start(ap, fmt); 2363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski retval = vsnprintf(buf, sizeof(buf), fmt, ap); 2364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski va_end(ap); 2365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ac->sourcePos.error("Error: %s (at '%s' with value '%s').\n", 2366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski buf, ac->attr.string(), ac->value.string()); 2367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::getAttributeKeys( 2371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t attrID, Vector<String16>* outKeys) 2372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<const Entry> e = getEntry(attrID); 2374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e != NULL) { 2375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = e->getBag().size(); 2376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 2377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& key = e->getBag().keyAt(i); 2378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (key.size() > 0 && key.string()[0] != '^') { 2379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outKeys->add(key); 2380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::getAttributeEnum( 2388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t attrID, const char16_t* name, size_t nameLen, 2389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value* outValue) 2390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("getAttributeEnum #%08x %s\n", attrID, String8(name, nameLen).string()); 2392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 nameStr(name, nameLen); 2393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<const Entry> e = getEntry(attrID); 2394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e != NULL) { 2395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = e->getBag().size(); 2396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 2397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Comparing %s to %s\n", String8(name, nameLen).string(), 2398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(e->getBag().keyAt(i)).string()); 2399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e->getBag().keyAt(i) == nameStr) { 2400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return getItemValue(attrID, e->getBag().valueAt(i).bagKeyId, outValue); 2401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::getAttributeFlags( 2408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t attrID, const char16_t* name, size_t nameLen, 2409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value* outValue) 2410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->dataType = Res_value::TYPE_INT_HEX; 2412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->data = 0; 2413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("getAttributeFlags #%08x %s\n", attrID, String8(name, nameLen).string()); 2415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 nameStr(name, nameLen); 2416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<const Entry> e = getEntry(attrID); 2417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e != NULL) { 2418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = e->getBag().size(); 2419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* end = name + nameLen; 2421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* pos = name; 2422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (pos < end) { 2423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char16_t* start = pos; 2424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (pos < end && *pos != '|') { 2425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pos++; 2426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 nameStr(start, pos-start); 2429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 2430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 2431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Comparing \"%s\" to \"%s\"\n", String8(nameStr).string(), 2432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(e->getBag().keyAt(i)).string()); 2433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e->getBag().keyAt(i) == nameStr) { 2434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value val; 2435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool got = getItemValue(attrID, e->getBag().valueAt(i).bagKeyId, &val); 2436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!got) { 2437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Got value: 0x%08x\n", val.data); 2440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->data |= val.data; 2441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 2442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (i >= N) { 2446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Didn't find this flag identifier. 2447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pos++; 2450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 2453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 2455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::assignResourceIds() 2458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = mOrderedPackages.size(); 2460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t pi; 2461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t firstError = NO_ERROR; 2462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // First generate all bag attributes and assign indices. 2464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (pi=0; pi<N; pi++) { 2465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mOrderedPackages.itemAt(pi); 2466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p == NULL || p->getTypes().size() == 0) { 2467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Empty, skip! 2468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2471833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski // This has no sense for packages being built as AppFeature (aka with a non-zero offset). 2472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = p->applyPublicTypeOrder(); 2473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR && firstError == NO_ERROR) { 2474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski firstError = err; 2475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Generate attributes... 2478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = p->getOrderedTypes().size(); 2479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t ti; 2480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (ti=0; ti<N; ti++) { 2481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getOrderedTypes().itemAt(ti); 2482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) { 2483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = t->getOrderedConfigs().size(); 2486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ci=0; ci<N; ci++) { 2487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci); 2488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == NULL) { 2489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = c->getEntries().size(); 2492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ei=0; ei<N; ei++) { 2493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = c->getEntries().valueAt(ei); 2494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e == NULL) { 2495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = e->generateAttributes(this, p->getName()); 2498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR && firstError == NO_ERROR) { 2499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski firstError = err; 2500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2505833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski uint32_t typeIdOffset = 0; 2506833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (mPackageType == AppFeature && p->getName() == mAssetsPackage) { 2507833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski typeIdOffset = mTypeIdOffset; 2508833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 2509833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 2510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const SourcePos unknown(String8("????"), 0); 2511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> attr = p->getType(String16("attr"), unknown); 2512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Assign indices... 251443a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski const size_t typeCount = p->getOrderedTypes().size(); 251543a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski for (size_t ti = 0; ti < typeCount; ti++) { 2516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getOrderedTypes().itemAt(ti); 2517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) { 2518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 252043a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski 2521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = t->applyPublicEntryOrder(); 2522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR && firstError == NO_ERROR) { 2523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski firstError = err; 2524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = t->getOrderedConfigs().size(); 2527833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski t->setIndex(ti + 1 + typeIdOffset); 2528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LOG_ALWAYS_FATAL_IF(ti == 0 && attr != t, 2530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "First type is not attr!"); 2531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ei=0; ei<N; ei++) { 2533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getOrderedConfigs().itemAt(ei); 2534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == NULL) { 2535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c->setEntryIndex(ei); 2538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Assign resource IDs to keys in bags... 254243a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski for (size_t ti = 0; ti < typeCount; ti++) { 2543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getOrderedTypes().itemAt(ti); 2544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) { 2545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = t->getOrderedConfigs().size(); 2548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ci=0; ci<N; ci++) { 2549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci); 2550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Ordered config #%d: %p\n", ci, c.get()); 2551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = c->getEntries().size(); 2552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ei=0; ei<N; ei++) { 2553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = c->getEntries().valueAt(ei); 2554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e == NULL) { 2555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = e->assignResourceIds(this, p->getName()); 2558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR && firstError == NO_ERROR) { 2559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski firstError = err; 2560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return firstError; 2566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::addSymbols(const sp<AaptSymbols>& outSymbols) { 2569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = mOrderedPackages.size(); 2570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t pi; 2571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (pi=0; pi<N; pi++) { 2573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mOrderedPackages.itemAt(pi); 2574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p->getTypes().size() == 0) { 2575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Empty, skip! 2576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = p->getOrderedTypes().size(); 2580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t ti; 2581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (ti=0; ti<N; ti++) { 2583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getOrderedTypes().itemAt(ti); 2584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) { 2585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = t->getOrderedConfigs().size(); 25883fb8c9b50ef1873454acf3a4e7fd33ad182c03d7Adam Lesinski sp<AaptSymbols> typeSymbols = 25893fb8c9b50ef1873454acf3a4e7fd33ad182c03d7Adam Lesinski outSymbols->addNestedSymbol(String8(t->getName()), t->getPos()); 25903fb8c9b50ef1873454acf3a4e7fd33ad182c03d7Adam Lesinski if (typeSymbols == NULL) { 25913fb8c9b50ef1873454acf3a4e7fd33ad182c03d7Adam Lesinski return UNKNOWN_ERROR; 25923fb8c9b50ef1873454acf3a4e7fd33ad182c03d7Adam Lesinski } 25933fb8c9b50ef1873454acf3a4e7fd33ad182c03d7Adam Lesinski 2594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ci=0; ci<N; ci++) { 2595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci); 2596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == NULL) { 2597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t rid = getResId(p, t, ci); 2600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (rid == 0) { 2601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 2602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2603833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (Res_GETPACKAGE(rid) + 1 == p->getAssignedId()) { 2604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeSymbols->addSymbol(String8(c->getName()), rid, c->getPos()); 2605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 comment(c->getComment()); 2607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeSymbols->appendComment(String8(c->getName()), comment, c->getPos()); 26088ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski //printf("Type symbol [%08x] %s comment: %s\n", rid, 26098ff15b4cada7998e78c93934ab2c869c322d7e07Adam Lesinski // String8(c->getName()).string(), String8(comment).string()); 2610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski comment = c->getTypeComment(); 2611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeSymbols->appendTypeComment(String8(c->getName()), comment); 2612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 2617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid 2621a01a9374fd386f3a8773528d7a49bc5315492dffAdam LesinskiResourceTable::addLocalization(const String16& name, const String8& locale, const SourcePos& src) 2622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2623a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski mLocalizations[name][locale] = src; 2624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/*! 2628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Flag various sorts of localization problems. '+' indicates checks already implemented; 2629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * '-' indicates checks that will be implemented in the future. 2630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 2631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * + A localized string for which no default-locale version exists => warning 2632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * + A string for which no version in an explicitly-requested locale exists => warning 2633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * + A localized translation of an translateable="false" string => warning 2634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * - A localized string not provided in every locale used by the table 2635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 2636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t 2637282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiResourceTable::validateLocalizations(void) 2638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = NO_ERROR; 2640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String8 defaultLocale; 2641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2642282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // For all strings... 2643a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski for (map<String16, map<String8, SourcePos> >::iterator nameIter = mLocalizations.begin(); 2644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nameIter != mLocalizations.end(); 2645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nameIter++) { 2646a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski const map<String8, SourcePos>& configSrcMap = nameIter->second; 2647282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Look for strings with no default localization 2649a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski if (configSrcMap.count(defaultLocale) == 0) { 2650a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski SourcePos().warning("string '%s' has no default translation.", 2651a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski String8(nameIter->first).string()); 2652a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski if (mBundle->getVerbose()) { 2653a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski for (map<String8, SourcePos>::const_iterator locales = configSrcMap.begin(); 2654a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski locales != configSrcMap.end(); 2655a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski locales++) { 2656a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski locales->second.printf("locale %s found", locales->first.string()); 2657a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski } 2658282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2659282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // !!! TODO: throw an error here in some circumstances 2660282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2661282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2662282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Check that all requested localizations are present for this string 2663fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (mBundle->getConfigurations().size() > 0 && mBundle->getRequireLocalization()) { 2664fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski const char* allConfigs = mBundle->getConfigurations().string(); 2665282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* start = allConfigs; 2666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* comma; 2667282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2668a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski set<String8> missingConfigs; 2669a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski AaptLocaleValue locale; 2670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski do { 2671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 config; 2672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski comma = strchr(start, ','); 2673282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comma != NULL) { 2674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.setTo(start, comma - start); 2675282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski start = comma + 1; 2676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.setTo(start); 2678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2680a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski if (!locale.initFromFilterString(config)) { 2681a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski continue; 2682a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski } 2683a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski 2684a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin // don't bother with the pseudolocale "en_XA" or "ar_XB" 2685a2ef5c0d4fb863c0382e77ae00f986a019b11cbeAnton Krumin if (config != "en_XA" && config != "ar_XB") { 2686a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski if (configSrcMap.find(config) == configSrcMap.end()) { 2687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // okay, no specific localization found. it's possible that we are 2688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // requiring a specific regional localization [e.g. de_DE] but there is an 2689282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // available string in the generic language localization [e.g. de]; 2690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // consider that string to have fulfilled the localization requirement. 2691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 region(config.string(), 2); 2692a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski if (configSrcMap.find(region) == configSrcMap.end() && 2693a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski configSrcMap.count(defaultLocale) == 0) { 2694a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski missingConfigs.insert(config); 2695282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2696282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2697282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2698a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski } while (comma != NULL); 2699a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski 2700a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski if (!missingConfigs.empty()) { 2701a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski String8 configStr; 2702a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski for (set<String8>::iterator iter = missingConfigs.begin(); 2703a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski iter != missingConfigs.end(); 2704a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski iter++) { 2705a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski configStr.appendFormat(" %s", iter->string()); 2706a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski } 2707a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski SourcePos().warning("string '%s' is missing %u required localizations:%s", 2708a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski String8(nameIter->first).string(), 2709a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski (unsigned int)missingConfigs.size(), 2710a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski configStr.string()); 2711a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski } 2712282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2714282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2715282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 2716282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2717282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 271827f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinskistatus_t ResourceTable::flatten(Bundle* bundle, const sp<const ResourceFilter>& filter, 271927f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski const sp<AaptFile>& dest, 272027f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski const bool isBase) 2721282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 2722282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ConfigDescription nullConfig; 2723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2724282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = mOrderedPackages.size(); 2725282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t pi; 2726282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2727282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const static String16 mipmap16("mipmap"); 2728282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2729282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool useUTF8 = !bundle->getUTF16StringsOption(); 2730282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2731de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski // The libraries this table references. 2732de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski Vector<sp<Package> > libraryPackages; 27336022debdbcc4498736580640c6287b57872617a2Adam Lesinski const ResTable& table = mAssets->getIncludedResources(); 27346022debdbcc4498736580640c6287b57872617a2Adam Lesinski const size_t basePackageCount = table.getBasePackageCount(); 27356022debdbcc4498736580640c6287b57872617a2Adam Lesinski for (size_t i = 0; i < basePackageCount; i++) { 27366022debdbcc4498736580640c6287b57872617a2Adam Lesinski size_t packageId = table.getBasePackageId(i); 27376022debdbcc4498736580640c6287b57872617a2Adam Lesinski String16 packageName(table.getBasePackageName(i)); 27386022debdbcc4498736580640c6287b57872617a2Adam Lesinski if (packageId > 0x01 && packageId != 0x7f && 27396022debdbcc4498736580640c6287b57872617a2Adam Lesinski packageName != String16("android")) { 27406022debdbcc4498736580640c6287b57872617a2Adam Lesinski libraryPackages.add(sp<Package>(new Package(packageName, packageId))); 27416022debdbcc4498736580640c6287b57872617a2Adam Lesinski } 27426022debdbcc4498736580640c6287b57872617a2Adam Lesinski } 2743de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 2744282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Iterate through all data, collecting all values (strings, 2745282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // references, etc). 2746282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski StringPool valueStrings(useUTF8); 2747282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<sp<Entry> > allEntries; 2748282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (pi=0; pi<N; pi++) { 2749282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mOrderedPackages.itemAt(pi); 2750282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p->getTypes().size() == 0) { 2751282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2752282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2753282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2754282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski StringPool typeStrings(useUTF8); 2755282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski StringPool keyStrings(useUTF8); 2756282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2757833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski ssize_t stringsAdded = 0; 2758282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = p->getOrderedTypes().size(); 2759282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ti=0; ti<N; ti++) { 2760282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getOrderedTypes().itemAt(ti); 2761282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) { 2762282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeStrings.add(String16("<empty>"), false); 2763833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski stringsAdded++; 2764282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2765282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2766833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 2767833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski while (stringsAdded < t->getIndex() - 1) { 2768833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski typeStrings.add(String16("<empty>"), false); 2769833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski stringsAdded++; 2770833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 2771833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski 2772282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 typeName(t->getName()); 2773282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeStrings.add(typeName, false); 2774833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski stringsAdded++; 2775282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2776282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // This is a hack to tweak the sorting order of the final strings, 2777282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // to put stuff that is generally not language-specific first. 2778282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8 configTypeName(typeName); 2779282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (configTypeName == "drawable" || configTypeName == "layout" 2780282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || configTypeName == "color" || configTypeName == "anim" 2781282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || configTypeName == "interpolator" || configTypeName == "animator" 2782282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || configTypeName == "xml" || configTypeName == "menu" 2783282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski || configTypeName == "mipmap" || configTypeName == "raw") { 2784282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski configTypeName = "1complex"; 2785282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 2786282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski configTypeName = "2value"; 2787282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2788282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 278927f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski // mipmaps don't get filtered, so they will 279027f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski // allways end up in the base. Make sure they 279127f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski // don't end up in a split. 279227f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski if (typeName == mipmap16 && !isBase) { 279327f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski continue; 279427f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski } 279527f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski 2796282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool filterable = (typeName != mipmap16); 2797282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2798282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = t->getOrderedConfigs().size(); 2799282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ci=0; ci<N; ci++) { 2800282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci); 2801282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == NULL) { 2802282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2803282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2804282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = c->getEntries().size(); 2805282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ei=0; ei<N; ei++) { 2806282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ConfigDescription config = c->getEntries().keyAt(ei); 2807fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (filterable && !filter->match(config)) { 2808282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2809282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2810282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = c->getEntries().valueAt(ei); 2811282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e == NULL) { 2812282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2813282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2814282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski e->setNameIndex(keyStrings.add(e->getName(), true)); 2815282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2816282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If this entry has no values for other configs, 2817282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // and is the default config, then it is special. Otherwise 2818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // we want to add it with the config info. 2819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ConfigDescription* valueConfig = NULL; 2820282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (N != 1 || config == nullConfig) { 2821282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski valueConfig = &config; 2822282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2823282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2824282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = e->prepareFlatten(&valueStrings, this, 2825282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski &configTypeName, &config); 2826282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 2827282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 2828282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2829282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski allEntries.add(e); 2830282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2831282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2832282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2833282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2834282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p->setTypeStrings(typeStrings.createStringBlock()); 2835282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p->setKeyStrings(keyStrings.createStringBlock()); 2836282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2837282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2838282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bundle->getOutputAPKFile() != NULL) { 2839282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Now we want to sort the value strings for better locality. This will 2840282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // cause the positions of the strings to change, so we need to go back 2841282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // through out resource entries and update them accordingly. Only need 2842282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // to do this if actually writing the output file. 2843282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski valueStrings.sortByConfig(); 2844282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (pi=0; pi<allEntries.size(); pi++) { 2845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski allEntries[pi]->remapStringValue(&valueStrings); 2846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2848282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2849282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t strAmt = 0; 2850de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 2851282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Now build the array of package chunks. 2852282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<sp<AaptFile> > flatPackages; 2853282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (pi=0; pi<N; pi++) { 2854282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = mOrderedPackages.itemAt(pi); 2855282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p->getTypes().size() == 0) { 2856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Empty, skip! 2857282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2858282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2859282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2860282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = p->getTypeStrings().size(); 2861282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2862282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t baseSize = sizeof(ResTable_package); 2863282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2864282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Start the package data. 2865282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> data = new AaptFile(String8(), AaptGroupEntry(), String8()); 2866282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_package* header = (ResTable_package*)data->editData(baseSize); 2867282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (header == NULL) { 2868282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: out of memory creating ResTable_package\n"); 2869282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_MEMORY; 2870282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2871282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memset(header, 0, sizeof(*header)); 2872282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header->header.type = htods(RES_TABLE_PACKAGE_TYPE); 2873282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header->header.headerSize = htods(sizeof(*header)); 2874833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski header->id = htodl(static_cast<uint32_t>(p->getAssignedId())); 2875282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski strcpy16_htod(header->name, p->getName().string()); 2876282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2877282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Write the string blocks. 2878282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t typeStringsStart = data->getSize(); 2879282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<AaptFile> strFile = p->getTypeStringsData(); 2880282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t amt = data->writeData(strFile->getData(), strFile->getSize()); 2881282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #if PRINT_STRING_METRICS 2882282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "**** type strings: %d\n", amt); 2883282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #endif 2884282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski strAmt += amt; 2885282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (amt < 0) { 2886282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return amt; 2887282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2888282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t keyStringsStart = data->getSize(); 2889282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski strFile = p->getKeyStringsData(); 2890282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski amt = data->writeData(strFile->getData(), strFile->getSize()); 2891282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #if PRINT_STRING_METRICS 2892282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "**** key strings: %d\n", amt); 2893282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #endif 2894282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski strAmt += amt; 2895282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (amt < 0) { 2896282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return amt; 2897282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2898282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 289927f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski if (isBase) { 290027f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski status_t err = flattenLibraryTable(data, libraryPackages); 290127f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski if (err != NO_ERROR) { 290227f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski fprintf(stderr, "ERROR: failed to write library table\n"); 290327f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski return err; 290427f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski } 2905de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski } 2906de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 2907282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Build the type chunks inside of this package. 2908282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ti=0; ti<N; ti++) { 2909282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Retrieve them in the same order as the type string block. 2910282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 2911282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 typeName(p->getTypeStrings().stringAt(ti, &len)); 2912282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getTypes().valueFor(typeName); 2913282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LOG_ALWAYS_FATAL_IF(t == NULL && typeName != String16("<empty>"), 2914282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Type name %s not found", 2915282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(typeName).string()); 2916833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (t == NULL) { 2917833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski continue; 2918833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 2919282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool filterable = (typeName != mipmap16); 292027f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski const bool skipEntireType = (typeName == mipmap16 && !isBase); 2921282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2922282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = t != NULL ? t->getOrderedConfigs().size() : 0; 2923282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2924282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Until a non-NO_ENTRY value has been written for a resource, 2925282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // that resource is invalid; validResources[i] represents 2926282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the item at t->getOrderedConfigs().itemAt(i). 2927282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<bool> validResources; 2928282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski validResources.insertAt(false, 0, N); 2929282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2930282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // First write the typeSpec chunk, containing information about 2931282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // each resource entry in this type. 2932282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 2933282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t typeSpecSize = sizeof(ResTable_typeSpec) + sizeof(uint32_t)*N; 2934282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t typeSpecStart = data->getSize(); 2935282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_typeSpec* tsHeader = (ResTable_typeSpec*) 2936282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (((uint8_t*)data->editData(typeSpecStart+typeSpecSize)) + typeSpecStart); 2937282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tsHeader == NULL) { 2938282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: out of memory creating ResTable_typeSpec\n"); 2939282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_MEMORY; 2940282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2941282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memset(tsHeader, 0, sizeof(*tsHeader)); 2942282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tsHeader->header.type = htods(RES_TABLE_TYPE_SPEC_TYPE); 2943282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tsHeader->header.headerSize = htods(sizeof(*tsHeader)); 2944282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tsHeader->header.size = htodl(typeSpecSize); 2945282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tsHeader->id = ti+1; 2946282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tsHeader->entryCount = htodl(N); 2947282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2948282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t* typeSpecFlags = (uint32_t*) 2949282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (((uint8_t*)data->editData()) 2950282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski + typeSpecStart + sizeof(ResTable_typeSpec)); 2951282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memset(typeSpecFlags, 0, sizeof(uint32_t)*N); 2952282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2953282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ei=0; ei<N; ei++) { 2954282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> cl = t->getOrderedConfigs().itemAt(ei); 2955282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (cl->getPublic()) { 2956282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeSpecFlags[ei] |= htodl(ResTable_typeSpec::SPEC_PUBLIC); 2957282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 295827f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski 295927f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski if (skipEntireType) { 296027f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski continue; 296127f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski } 296227f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski 2963282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t CN = cl->getEntries().size(); 2964282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ci=0; ci<CN; ci++) { 2965fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (filterable && !filter->match(cl->getEntries().keyAt(ci))) { 2966282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2967282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2968282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t cj=ci+1; cj<CN; cj++) { 2969fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (filterable && !filter->match(cl->getEntries().keyAt(cj))) { 2970282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 2971282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2972282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeSpecFlags[ei] |= htodl( 2973282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski cl->getEntries().keyAt(ci).diff(cl->getEntries().keyAt(cj))); 2974282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2975282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2976282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2977282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 2978282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 297927f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski if (skipEntireType) { 298027f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski continue; 298127f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski } 298227f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski 2983282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // We need to write one type chunk for each configuration for 2984282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // which we have entries in this type. 2985282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NC = t->getUniqueConfigs().size(); 2986282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2987282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t typeSize = sizeof(ResTable_type) + sizeof(uint32_t)*N; 2988282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2989282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ci=0; ci<NC; ci++) { 2990282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ConfigDescription config = t->getUniqueConfigs().itemAt(ci); 2991282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2992282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Writing config %d config: imsi:%d/%d lang:%c%c cnt:%c%c " 2993282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d " 2994282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "sw%ddp w%ddp h%ddp dir:%d\n", 2995282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ti+1, 2996282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.mcc, config.mnc, 2997282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.language[0] ? config.language[0] : '-', 2998282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.language[1] ? config.language[1] : '-', 2999282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.country[0] ? config.country[0] : '-', 3000282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.country[1] ? config.country[1] : '-', 3001282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.orientation, 3002282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.uiMode, 3003282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.touchscreen, 3004282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.density, 3005282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.keyboard, 3006282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.inputFlags, 3007282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.navigation, 3008282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.screenWidth, 3009282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.screenHeight, 3010282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.smallestScreenWidthDp, 3011282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.screenWidthDp, 3012282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.screenHeightDp, 3013282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config.layoutDirection)); 3014282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3015fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski if (filterable && !filter->match(config)) { 3016282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 3017282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3018282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3019282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t typeStart = data->getSize(); 3020282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3021282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_type* tHeader = (ResTable_type*) 3022282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (((uint8_t*)data->editData(typeStart+typeSize)) + typeStart); 3023282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tHeader == NULL) { 3024282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: out of memory creating ResTable_type\n"); 3025282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_MEMORY; 3026282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3027282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3028282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memset(tHeader, 0, sizeof(*tHeader)); 3029282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->header.type = htods(RES_TABLE_TYPE_TYPE); 3030282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->header.headerSize = htods(sizeof(*tHeader)); 3031282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->id = ti+1; 3032282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->entryCount = htodl(N); 3033282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->entriesStart = htodl(typeSize); 3034282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config = config; 3035282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("Writing type %d config: imsi:%d/%d lang:%c%c cnt:%c%c " 3036282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d " 3037282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "sw%ddp w%ddp h%ddp dir:%d\n", 3038282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ti+1, 3039282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.mcc, tHeader->config.mnc, 3040282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.language[0] ? tHeader->config.language[0] : '-', 3041282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.language[1] ? tHeader->config.language[1] : '-', 3042282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.country[0] ? tHeader->config.country[0] : '-', 3043282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.country[1] ? tHeader->config.country[1] : '-', 3044282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.orientation, 3045282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.uiMode, 3046282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.touchscreen, 3047282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.density, 3048282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.keyboard, 3049282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.inputFlags, 3050282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.navigation, 3051282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.screenWidth, 3052282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.screenHeight, 3053282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.smallestScreenWidthDp, 3054282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.screenWidthDp, 3055282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.screenHeightDp, 3056282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.layoutDirection)); 3057282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->config.swapHtoD(); 3058282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3059282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Build the entries inside of this type. 3060282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t ei=0; ei<N; ei++) { 3061282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> cl = t->getOrderedConfigs().itemAt(ei); 3062282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = cl->getEntries().valueFor(config); 3063282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3064282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Set the offset for this entry in its type. 3065282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t* index = (uint32_t*) 3066282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (((uint8_t*)data->editData()) 3067282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski + typeStart + sizeof(ResTable_type)); 3068282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e != NULL) { 3069282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski index[ei] = htodl(data->getSize()-typeStart-typeSize); 3070282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3071282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Create the entry. 3072282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t amt = e->flatten(bundle, data, cl->getPublic()); 3073282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (amt < 0) { 3074282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return amt; 3075282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3076282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski validResources.editItemAt(ei) = true; 3077282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 3078282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski index[ei] = htodl(ResTable_type::NO_ENTRY); 3079282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3080282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3081282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3082282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Fill in the rest of the type information. 3083282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader = (ResTable_type*) 3084282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (((uint8_t*)data->editData()) + typeStart); 3085282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tHeader->header.size = htodl(data->getSize()-typeStart); 3086282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3087282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3088833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski // If we're building splits, then each invocation of the flattening 3089833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski // step will have 'missing' entries. Don't warn/error for this case. 3090833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (bundle->getSplitConfigurations().isEmpty()) { 3091833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski bool missing_entry = false; 3092833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski const char* log_prefix = bundle->getErrorOnMissingConfigEntry() ? 3093833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski "error" : "warning"; 3094833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski for (size_t i = 0; i < N; ++i) { 3095833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (!validResources[i]) { 3096833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski sp<ConfigList> c = t->getOrderedConfigs().itemAt(i); 3097833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski fprintf(stderr, "%s: no entries written for %s/%s (0x%08x)\n", log_prefix, 3098833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski String8(typeName).string(), String8(c->getName()).string(), 3099833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski Res_MAKEID(p->getAssignedId() - 1, ti, i)); 3100833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski missing_entry = true; 3101833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 3102833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski } 3103833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (bundle->getErrorOnMissingConfigEntry() && missing_entry) { 3104833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski fprintf(stderr, "Error: Missing entries, quit!\n"); 3105833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski return NOT_ENOUGH_DATA; 3106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3107cd28bd37ea2d88dd72930f032ca73daaad5744b4Ying Wang } 3108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Fill in the rest of the package information. 3111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header = (ResTable_package*)data->editData(); 3112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header->header.size = htodl(data->getSize()); 3113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header->typeStrings = htodl(typeStringsStart); 3114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header->lastPublicType = htodl(p->getTypeStrings().size()); 3115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header->keyStrings = htodl(keyStringsStart); 3116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header->lastPublicKey = htodl(p->getKeyStrings().size()); 3117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski flatPackages.add(data); 3119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // And now write out the final chunks. 3122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t dataStart = dest->getSize(); 3123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 3125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // blah 3126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_header header; 3127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memset(&header, 0, sizeof(header)); 3128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header.header.type = htods(RES_TABLE_TYPE); 3129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header.header.headerSize = htods(sizeof(header)); 3130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header.packageCount = htodl(flatPackages.size()); 3131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = dest->writeData(&header, sizeof(header)); 3132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: out of memory creating ResTable_header\n"); 3134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t strStart = dest->getSize(); 3139fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski status_t err = valueStrings.writeStringBlock(dest); 3140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t amt = (dest->getSize()-strStart); 3145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski strAmt += amt; 3146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #if PRINT_STRING_METRICS 3147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "**** value strings: %d\n", amt); 3148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "**** total strings: %d\n", strAmt); 3149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #endif 3150de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 3151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (pi=0; pi<flatPackages.size(); pi++) { 3152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = dest->writeData(flatPackages[pi]->getData(), 3153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski flatPackages[pi]->getSize()); 3154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: out of memory creating package chunk for ResTable_header\n"); 3156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_header* header = (ResTable_header*) 3161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (((uint8_t*)dest->getData()) + dataStart); 3162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header->header.size = htodl(dest->getSize() - dataStart); 3163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(aout << "Resource table:" 3165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski << HexDump(dest->getData(), dest->getSize()) << endl); 3166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #if PRINT_STRING_METRICS 3168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "**** total resource table size: %d / %d%% strings\n", 3169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest->getSize(), (strAmt*100)/dest->getSize()); 3170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #endif 3171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3175de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinskistatus_t ResourceTable::flattenLibraryTable(const sp<AaptFile>& dest, const Vector<sp<Package> >& libs) { 3176de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski // Write out the library table if necessary 3177de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski if (libs.size() > 0) { 3178de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski NOISY(fprintf(stderr, "Writing library reference table\n")); 3179de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 3180de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski const size_t libStart = dest->getSize(); 3181de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski const size_t count = libs.size(); 31826022debdbcc4498736580640c6287b57872617a2Adam Lesinski ResTable_lib_header* libHeader = (ResTable_lib_header*) dest->editDataInRange( 31836022debdbcc4498736580640c6287b57872617a2Adam Lesinski libStart, sizeof(ResTable_lib_header)); 3184de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 3185de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski memset(libHeader, 0, sizeof(*libHeader)); 3186de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski libHeader->header.type = htods(RES_TABLE_LIBRARY_TYPE); 3187de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski libHeader->header.headerSize = htods(sizeof(*libHeader)); 3188de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski libHeader->header.size = htodl(sizeof(*libHeader) + (sizeof(ResTable_lib_entry) * count)); 3189de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski libHeader->count = htodl(count); 3190de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 3191de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski // Write the library entries 3192de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski for (size_t i = 0; i < count; i++) { 3193de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski const size_t entryStart = dest->getSize(); 3194de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski sp<Package> libPackage = libs[i]; 3195de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski NOISY(fprintf(stderr, " Entry %s -> 0x%02x\n", 3196de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski String8(libPackage->getName()).string(), 3197de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski (uint8_t)libPackage->getAssignedId())); 3198de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 31996022debdbcc4498736580640c6287b57872617a2Adam Lesinski ResTable_lib_entry* entry = (ResTable_lib_entry*) dest->editDataInRange( 32006022debdbcc4498736580640c6287b57872617a2Adam Lesinski entryStart, sizeof(ResTable_lib_entry)); 3201de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski memset(entry, 0, sizeof(*entry)); 3202de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski entry->packageId = htodl(libPackage->getAssignedId()); 3203de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski strcpy16_htod(entry->packageName, libPackage->getName().string()); 3204de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski } 3205de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski } 3206de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski return NO_ERROR; 3207de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski} 3208de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski 3209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ResourceTable::writePublicDefinitions(const String16& package, FILE* fp) 3210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, 3212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "<!-- This file contains <public> resource definitions for all\n" 3213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " resources that were generated from the source data. -->\n" 3214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "\n" 3215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "<resources>\n"); 3216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski writePublicDefinitions(package, fp, true); 3218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski writePublicDefinitions(package, fp, false); 3219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, 3221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "\n" 3222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "</resources>\n"); 3223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ResourceTable::writePublicDefinitions(const String16& package, FILE* fp, bool pub) 3226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool didHeader = false; 3228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> pkg = mPackages.valueFor(package); 3230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pkg != NULL) { 3231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NT = pkg->getOrderedTypes().size(); 3232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<NT; i++) { 3233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = pkg->getOrderedTypes().itemAt(i); 3234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) { 3235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 3236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool didType = false; 3239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NC = t->getOrderedConfigs().size(); 3241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t j=0; j<NC; j++) { 3242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getOrderedConfigs().itemAt(j); 3243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == NULL) { 3244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 3245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c->getPublic() != pub) { 3248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 3249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!didType) { 3252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, "\n"); 3253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski didType = true; 3254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!didHeader) { 3256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pub) { 3257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp," <!-- PUBLIC SECTION. These resources have been declared public.\n"); 3258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp," Changes to these definitions will break binary compatibility. -->\n\n"); 3259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 3260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp," <!-- PRIVATE SECTION. These resources have not been declared public.\n"); 3261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp," You can make them public my moving these lines into a file in res/values. -->\n\n"); 3262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski didHeader = true; 3264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!pub) { 3266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NE = c->getEntries().size(); 3267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t k=0; k<NE; k++) { 3268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const SourcePos& pos = c->getEntries().valueAt(k)->getPos(); 3269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pos.file != "") { 3270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp," <!-- Declared at %s:%d -->\n", 3271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pos.file.string(), pos.line); 3272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(fp, " <public type=\"%s\" name=\"%s\" id=\"0x%08x\" />\n", 3276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(t->getName()).string(), 3277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(c->getName()).string(), 3278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getResId(pkg, t, c->getEntryIndex())); 3279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3284282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiResourceTable::Item::Item(const SourcePos& _sourcePos, 3285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool _isId, 3286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& _value, 3287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<StringPool::entry_style_span>* _style, 3288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t _format) 3289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski : sourcePos(_sourcePos) 3290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , isId(_isId) 3291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , value(_value) 3292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , format(_format) 3293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , bagKeyId(0) 3294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski , evaluating(false) 3295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (_style) { 3297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski style = *_style; 3298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 330182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam LesinskiResourceTable::Entry::Entry(const Entry& entry) 330282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski : RefBase() 330382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski , mName(entry.mName) 330482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski , mParent(entry.mParent) 330582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski , mType(entry.mType) 330682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski , mItem(entry.mItem) 330782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski , mItemFormat(entry.mItemFormat) 330882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski , mBag(entry.mBag) 330982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski , mNameIndex(entry.mNameIndex) 331082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski , mParentId(entry.mParentId) 331182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski , mPos(entry.mPos) {} 331282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 3313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Entry::makeItABag(const SourcePos& sourcePos) 3314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mType == TYPE_BAG) { 3316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mType == TYPE_UNKNOWN) { 3319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mType = TYPE_BAG; 3320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Resource entry %s is already defined as a single item.\n" 3323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s:%d: Originally defined here.\n", 3324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string(), 3325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mItem.sourcePos.file.string(), mItem.sourcePos.line); 3326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Entry::setItem(const SourcePos& sourcePos, 3330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& value, 3331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<StringPool::entry_style_span>* style, 3332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t format, 3333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool overwrite) 3334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Item item(sourcePos, false, value, style); 3336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mType == TYPE_BAG) { 333843a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski if (mBag.size() == 0) { 333943a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski sourcePos.error("Resource entry %s is already defined as a bag.", 334043a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski String8(mName).string()); 334143a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski } else { 334243a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski const Item& item(mBag.valueAt(0)); 334343a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski sourcePos.error("Resource entry %s is already defined as a bag.\n" 334443a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski "%s:%d: Originally defined here.\n", 334543a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski String8(mName).string(), 334643a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski item.sourcePos.file.string(), item.sourcePos.line); 334743a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski } 3348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ( (mType != TYPE_UNKNOWN) && (overwrite == false) ) { 3351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Resource entry %s is already defined.\n" 3352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s:%d: Originally defined here.\n", 3353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string(), 3354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mItem.sourcePos.file.string(), mItem.sourcePos.line); 3355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mType = TYPE_ITEM; 3359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mItem = item; 3360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mItemFormat = format; 3361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Entry::addToBag(const SourcePos& sourcePos, 3365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& key, const String16& value, 3366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Vector<StringPool::entry_style_span>* style, 3367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool replace, bool isId, int32_t format) 3368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = makeItABag(sourcePos); 3370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Item item(sourcePos, isId, value, style, format); 3375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // XXX NOTE: there is an error if you try to have a bag with two keys, 3377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // one an attr and one an id, with the same name. Not something we 3378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // currently ever have to worry about. 3379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ssize_t origKey = mBag.indexOfKey(key); 3380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (origKey >= 0) { 3381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!replace) { 3382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Item& item(mBag.valueAt(origKey)); 3383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Resource entry %s already has bag item %s.\n" 3384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s:%d: Originally defined here.\n", 3385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string(), String8(key).string(), 3386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski item.sourcePos.file.string(), item.sourcePos.line); 3387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Replacing %s with %s\n", 3390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(mBag.valueFor(key).value).string(), String8(value).string()); 3391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mBag.replaceValueFor(key, item); 3392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mBag.add(key, item); 3395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 339882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinskistatus_t ResourceTable::Entry::removeFromBag(const String16& key) { 339982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski if (mType != Entry::TYPE_BAG) { 340082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski return NO_ERROR; 340182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 340282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 340382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski if (mBag.removeItem(key) >= 0) { 340482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski return NO_ERROR; 340582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 340682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski return UNKNOWN_ERROR; 340782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski} 340882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 3409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Entry::emptyBag(const SourcePos& sourcePos) 3410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = makeItABag(sourcePos); 3412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mBag.clear(); 3417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Entry::generateAttributes(ResourceTable* table, 3421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& package) 3422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 attr16("attr"); 3424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 id16("id"); 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 const Item& it = mBag.valueAt(i); 3429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (it.isId) { 3430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!table->hasBagOrEntry(key, &id16, &package)) { 3431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16 value("false"); 343243a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski NOISY(fprintf(stderr, "Generating %s:id/%s\n", 343343a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski String8(package).string(), 343443a0df04b0826ffb9e4589aac73b07b0c98abe8cAdam Lesinski String8(key).string())); 3435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = table->addEntry(SourcePos(String8("<generated>"), 0), package, 3436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski id16, key, value); 3437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (!table->hasBagOrEntry(key, &attr16, &package)) { 3442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#if 1 3444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// fprintf(stderr, "ERROR: Bag attribute '%s' has not been defined.\n", 3445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// String8(key).string()); 3446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// const Item& item(mBag.valueAt(i)); 3447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// fprintf(stderr, "Referenced from file %s line %d\n", 3448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// item.sourcePos.file.string(), item.sourcePos.line); 3449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// return UNKNOWN_ERROR; 3450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#else 3451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char numberStr[16]; 3452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sprintf(numberStr, "%d", ResTable_map::TYPE_ANY); 3453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = table->addBag(SourcePos("<generated>", 0), package, 3454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski attr16, key, String16(""), 3455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16("^type"), 3456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String16(numberStr), NULL, NULL); 3457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 3461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Entry::assignResourceIds(ResourceTable* table, 3467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& package) 3468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasErrors = false; 3470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mType == TYPE_BAG) { 3472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char* errorMsg; 3473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 style16("style"); 3474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 attr16("attr"); 3475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16 id16("id"); 3476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentId = 0; 3477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mParent.size() > 0) { 3478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentId = table->getResId(mParent, &style16, NULL, &errorMsg); 3479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mParentId == 0) { 3480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mPos.error("Error retrieving parent for item: %s '%s'.\n", 3481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski errorMsg, String8(mParent).string()); 3482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 3483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = mBag.size(); 3486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 3487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& key = mBag.keyAt(i); 3488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Item& it = mBag.editValueAt(i); 3489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it.bagKeyId = table->getResId(key, 3490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it.isId ? &id16 : &attr16, NULL, &errorMsg); 3491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Bag key of %s: #%08x\n", String8(key).string(), it.bagKeyId); 3492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (it.bagKeyId == 0) { 3493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it.sourcePos.error("Error: %s: %s '%s'.\n", errorMsg, 3494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(it.isId ? id16 : attr16).string(), 3495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(key).string()); 3496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasErrors = true; 3497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return hasErrors ? UNKNOWN_ERROR : NO_ERROR; 3501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Entry::prepareFlatten(StringPool* strings, ResourceTable* table, 3504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String8* configTypeName, const ConfigDescription* config) 3505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mType == TYPE_ITEM) { 3507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Item& it = mItem; 3508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AccessorCookie ac(it.sourcePos, String8(mName), String8(it.value)); 3509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!table->stringToValue(&it.parsedValue, strings, 3510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it.value, false, true, 0, 3511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski &it.style, NULL, &ac, mItemFormat, 3512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski configTypeName, config)) { 3513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (mType == TYPE_BAG) { 3516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = mBag.size(); 3517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 3518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& key = mBag.keyAt(i); 3519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Item& it = mBag.editValueAt(i); 3520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AccessorCookie ac(it.sourcePos, String8(key), String8(it.value)); 3521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!table->stringToValue(&it.parsedValue, strings, 3522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it.value, false, true, it.bagKeyId, 3523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski &it.style, NULL, &ac, it.format, 3524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski configTypeName, config)) { 3525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 3529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mPos.error("Error: entry %s is not a single item or a bag.\n", 3530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string()); 3531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Entry::remapStringValue(StringPool* strings) 3537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mType == TYPE_ITEM) { 3539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Item& it = mItem; 3540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (it.parsedValue.dataType == Res_value::TYPE_STRING) { 3541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it.parsedValue.data = strings->mapOriginalPosToNewPos(it.parsedValue.data); 3542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (mType == TYPE_BAG) { 3544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = mBag.size(); 3545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 3546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Item& it = mBag.editValueAt(i); 3547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (it.parsedValue.dataType == Res_value::TYPE_STRING) { 3548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it.parsedValue.data = strings->mapOriginalPosToNewPos(it.parsedValue.data); 3549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 3552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mPos.error("Error: entry %s is not a single item or a bag.\n", 3553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string()); 3554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskissize_t ResourceTable::Entry::flatten(Bundle* bundle, const sp<AaptFile>& data, bool isPublic) 3560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t amt = 0; 3562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_entry header; 3563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memset(&header, 0, sizeof(header)); 3564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header.size = htods(sizeof(header)); 3565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const type ty = this != NULL ? mType : TYPE_ITEM; 3566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (this != NULL) { 3567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (ty == TYPE_BAG) { 3568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header.flags |= htods(header.FLAG_COMPLEX); 3569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (isPublic) { 3571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header.flags |= htods(header.FLAG_PUBLIC); 3572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski header.key.index = htodl(mNameIndex); 3574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (ty != TYPE_BAG) { 3576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = data->writeData(&header, sizeof(header)); 3577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: out of memory creating ResTable_entry\n"); 3579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Item& it = mItem; 3583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Res_value par; 3584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memset(&par, 0, sizeof(par)); 3585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski par.size = htods(it.parsedValue.size); 3586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski par.dataType = it.parsedValue.dataType; 3587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski par.res0 = it.parsedValue.res0; 3588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski par.data = htodl(it.parsedValue.data); 3589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #if 0 3590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Writing item (%s): type=%d, data=0x%x, res0=0x%x\n", 3591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string(), it.parsedValue.dataType, 3592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it.parsedValue.data, par.res0); 3593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #endif 3594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = data->writeData(&par, it.parsedValue.size); 3595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: out of memory creating Res_value\n"); 3597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski amt += it.parsedValue.size; 3600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 3601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t N = mBag.size(); 3602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 3603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Create correct ordering of items. 3604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski KeyedVector<uint32_t, const Item*> items; 3605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 3606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Item& it = mBag.valueAt(i); 3607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski items.add(it.bagKeyId, &it); 3608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski N = items.size(); 3610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_map_entry mapHeader; 3612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memcpy(&mapHeader, &header, sizeof(header)); 3613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mapHeader.size = htods(sizeof(mapHeader)); 3614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mapHeader.parent.ident = htodl(mParentId); 3615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mapHeader.count = htodl(N); 3616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = data->writeData(&mapHeader, sizeof(mapHeader)); 3617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: out of memory creating ResTable_entry\n"); 3619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 3623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Item& it = *items.valueAt(i); 3624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResTable_map map; 3625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski map.name.ident = htodl(it.bagKeyId); 3626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski map.value.size = htods(it.parsedValue.size); 3627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski map.value.dataType = it.parsedValue.dataType; 3628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski map.value.res0 = it.parsedValue.res0; 3629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski map.value.data = htodl(it.parsedValue.data); 3630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err = data->writeData(&map, sizeof(map)); 3631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: out of memory creating Res_value\n"); 3633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski amt += sizeof(map); 3636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return amt; 3639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ResourceTable::ConfigList::appendComment(const String16& comment, 3642282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool onlyIfEmpty) 3643282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() <= 0) { 3645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 3646282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3647282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (onlyIfEmpty && mComment.size() > 0) { 3648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 3649282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3650282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mComment.size() > 0) { 3651282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mComment.append(String16("\n")); 3652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3653282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mComment.append(comment); 3654282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3655282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3656282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ResourceTable::ConfigList::appendTypeComment(const String16& comment) 3657282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3658282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment.size() <= 0) { 3659282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 3660282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3661282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mTypeComment.size() > 0) { 3662282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mTypeComment.append(String16("\n")); 3663282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3664282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mTypeComment.append(comment); 3665282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3667282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Type::addPublic(const SourcePos& sourcePos, 3668282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 3669282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const uint32_t ident) 3670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #if 0 3672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t entryIdx = Res_GETENTRY(ident); 3673282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (entryIdx < 0) { 3674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Public resource %s/%s has an invalid 0 identifier (0x%08x).\n", 3675282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string(), String8(name).string(), ident); 3676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski #endif 3679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t typeIdx = Res_GETTYPE(ident); 3681282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (typeIdx >= 0) { 3682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski typeIdx++; 3683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mPublicIndex > 0 && mPublicIndex != typeIdx) { 3684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Public resource %s/%s has conflicting type codes for its" 3685282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " public identifiers (0x%x vs 0x%x).\n", 3686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string(), String8(name).string(), 3687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mPublicIndex, typeIdx); 3688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3689282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mPublicIndex = typeIdx; 3691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3693282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mFirstPublicSourcePos == NULL) { 3694282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mFirstPublicSourcePos = new SourcePos(sourcePos); 3695282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3696282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3697282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mPublic.indexOfKey(name) < 0) { 3698282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mPublic.add(name, Public(sourcePos, String16(), ident)); 3699282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 3700282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Public& p = mPublic.editValueFor(name); 3701282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p.ident != ident) { 3702282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Public resource %s/%s has conflicting public identifiers" 3703282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " (0x%08x vs 0x%08x).\n" 3704282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s:%d: Originally defined here.\n", 3705282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string(), String8(name).string(), p.ident, ident, 3706282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p.sourcePos.file.string(), p.sourcePos.line); 3707282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3708282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3709282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3710282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3711282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 3712282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3714282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ResourceTable::Type::canAddEntry(const String16& name) 3715282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3716282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCanAddEntries.add(name); 3717282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3718282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3719282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<ResourceTable::Entry> ResourceTable::Type::getEntry(const String16& entry, 3720282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const SourcePos& sourcePos, 3721282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config* config, 3722282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool doSetIndex, 3723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool overlay, 3724282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool autoAddOverlay) 3725282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3726282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int pos = -1; 3727282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = mConfigs.valueFor(entry); 3728282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == NULL) { 3729282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (overlay && !autoAddOverlay && mCanAddEntries.indexOf(entry) < 0) { 3730282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Resource at %s appears in overlay but not" 3731282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " in the base package; use <add-resource> to add.\n", 3732282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(entry).string()); 3733282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 3734282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3735282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c = new ConfigList(entry, sourcePos); 3736282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mConfigs.add(entry, c); 3737282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pos = (int)mOrderedConfigs.size(); 3738282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedConfigs.add(c); 3739282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (doSetIndex) { 3740282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c->setEntryIndex(pos); 3741282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3742282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3743282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3744282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ConfigDescription cdesc; 3745282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (config) cdesc = *config; 3746282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3747282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = c->getEntries().valueFor(cdesc); 3748282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e == NULL) { 3749282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (config != NULL) { 3750282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("New entry at %s:%d: imsi:%d/%d lang:%c%c cnt:%c%c " 3751282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "orien:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d " 3752282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "sw%ddp w%ddp h%ddp dir:%d\n", 3753282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.file.string(), sourcePos.line, 3754282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->mcc, config->mnc, 3755282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->language[0] ? config->language[0] : '-', 3756282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->language[1] ? config->language[1] : '-', 3757282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->country[0] ? config->country[0] : '-', 3758282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->country[1] ? config->country[1] : '-', 3759282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->orientation, 3760282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->touchscreen, 3761282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->density, 3762282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->keyboard, 3763282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->inputFlags, 3764282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->navigation, 3765282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->screenWidth, 3766282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->screenHeight, 3767282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->smallestScreenWidthDp, 3768282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->screenWidthDp, 3769282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->screenHeightDp, 3770282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski config->layoutDirection)); 3771282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 3772282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(printf("New entry at %s:%d: NULL config\n", 3773282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.file.string(), sourcePos.line)); 3774282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3775282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski e = new Entry(entry, sourcePos); 3776282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c->addEntry(cdesc, e); 3777282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 3778282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (doSetIndex) { 3779282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pos < 0) { 3780282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (pos=0; pos<(int)mOrderedConfigs.size(); pos++) { 3781282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mOrderedConfigs[pos] == c) { 3782282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 3783282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3784282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3785282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (pos >= (int)mOrderedConfigs.size()) { 3786282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sourcePos.error("Internal error: config not found in mOrderedConfigs when adding entry"); 3787282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 3788282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3789282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3790282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski e->setEntryIndex(pos); 3791282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3792282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 3793282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3794282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3795282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mUniqueConfigs.add(cdesc); 3796282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3797282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return e; 3798282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3799282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3800282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Type::applyPublicEntryOrder() 3801282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3802282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t N = mOrderedConfigs.size(); 3803282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<sp<ConfigList> > origOrder(mOrderedConfigs); 3804282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasError = false; 3805282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3806282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 3807282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 3808282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedConfigs.replaceAt(NULL, i); 3809282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3810282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3811282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t NP = mPublic.size(); 3812282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Ordering %d configs from %d public defs\n", N, NP); 3813282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t j; 3814282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (j=0; j<NP; j++) { 3815282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name = mPublic.keyAt(j); 3816282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Public& p = mPublic.valueAt(j); 3817282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t idx = Res_GETENTRY(p.ident); 3818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Looking for entry \"%s\"/\"%s\" (0x%08x) in %d...\n", 3819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // String8(mName).string(), String8(name).string(), p.ident, N); 3820282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool found = false; 3821282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 3822282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> e = origOrder.itemAt(i); 3823282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("#%d: \"%s\"\n", i, String8(e->getName()).string()); 3824282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e->getName() == name) { 3825282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (idx >= (int32_t)mOrderedConfigs.size()) { 3826282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p.sourcePos.error("Public entry identifier 0x%x entry index " 3827282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "is larger than available symbols (index %d, total symbols %d).\n", 3828282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p.ident, idx, mOrderedConfigs.size()); 3829282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasError = true; 3830282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (mOrderedConfigs.itemAt(idx) == NULL) { 3831282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski e->setPublic(true); 3832282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski e->setPublicSourcePos(p.sourcePos); 3833282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedConfigs.replaceAt(e, idx); 3834282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski origOrder.removeAt(i); 3835282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski N--; 3836282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski found = true; 3837282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 3838282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 3839282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> oe = mOrderedConfigs.itemAt(idx); 3840282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3841282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p.sourcePos.error("Multiple entry names declared for public entry" 3842282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " identifier 0x%x in type %s (%s vs %s).\n" 3843282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s:%d: Originally defined here.", 3844282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski idx+1, String8(mName).string(), 3845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(oe->getName()).string(), 3846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(name).string(), 3847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski oe->getPublicSourcePos().file.string(), 3848282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski oe->getPublicSourcePos().line); 3849282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasError = true; 3850282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3851282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3852282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3853282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3854282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!found) { 3855282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p.sourcePos.error("Public symbol %s/%s declared here is not defined.", 3856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(mName).string(), String8(name).string()); 3857282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasError = true; 3858282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3859282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3860282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3861282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //printf("Copying back in %d non-public configs, have %d\n", N, origOrder.size()); 3862282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3863282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (N != origOrder.size()) { 3864282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("Internal error: remaining private symbol count mismatch\n"); 3865282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski N = origOrder.size(); 3866282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3867282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3868282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski j = 0; 3869282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 3870282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> e = origOrder.itemAt(i); 3871282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // There will always be enough room for the remaining entries. 3872282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (mOrderedConfigs.itemAt(j) != NULL) { 3873282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski j++; 3874282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3875282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedConfigs.replaceAt(e, j); 3876282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski j++; 3877282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3878282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3879282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return hasError ? UNKNOWN_ERROR : NO_ERROR; 3880282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3881282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3882833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam LesinskiResourceTable::Package::Package(const String16& name, size_t packageId) 3883833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski : mName(name), mPackageId(packageId), 3884282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mTypeStringsMapping(0xffffffff), 3885282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mKeyStringsMapping(0xffffffff) 3886282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3887282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3888282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3889282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<ResourceTable::Type> ResourceTable::Package::getType(const String16& type, 3890282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const SourcePos& sourcePos, 3891282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool doSetIndex) 3892282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3893282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = mTypes.valueFor(type); 3894282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) { 3895282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski t = new Type(type, sourcePos); 3896282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mTypes.add(type, t); 3897282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedTypes.add(t); 3898282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (doSetIndex) { 3899282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // For some reason the type's index is set to one plus the index 3900282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // in the mOrderedTypes list, rather than just the index. 3901282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski t->setIndex(mOrderedTypes.size()); 3902282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3903282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3904282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return t; 3905282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3906282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3907282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Package::setTypeStrings(const sp<AaptFile>& data) 3908282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3909282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = setStrings(data, &mTypeStrings, &mTypeStringsMapping); 3910282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3911282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: Type string data is corrupt!\n"); 391257079519f4610715e4c0668c641575d10f3d4461Adam Lesinski return err; 3913282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 391457079519f4610715e4c0668c641575d10f3d4461Adam Lesinski 391557079519f4610715e4c0668c641575d10f3d4461Adam Lesinski // Retain a reference to the new data after we've successfully replaced 391657079519f4610715e4c0668c641575d10f3d4461Adam Lesinski // all uses of the old reference (in setStrings() ). 391757079519f4610715e4c0668c641575d10f3d4461Adam Lesinski mTypeStringsData = data; 391857079519f4610715e4c0668c641575d10f3d4461Adam Lesinski return NO_ERROR; 3919282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3920282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3921282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Package::setKeyStrings(const sp<AaptFile>& data) 3922282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3923282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = setStrings(data, &mKeyStrings, &mKeyStringsMapping); 3924282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err != NO_ERROR) { 3925282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "ERROR: Key string data is corrupt!\n"); 392657079519f4610715e4c0668c641575d10f3d4461Adam Lesinski return err; 3927282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 392857079519f4610715e4c0668c641575d10f3d4461Adam Lesinski 392957079519f4610715e4c0668c641575d10f3d4461Adam Lesinski // Retain a reference to the new data after we've successfully replaced 393057079519f4610715e4c0668c641575d10f3d4461Adam Lesinski // all uses of the old reference (in setStrings() ). 393157079519f4610715e4c0668c641575d10f3d4461Adam Lesinski mKeyStringsData = data; 393257079519f4610715e4c0668c641575d10f3d4461Adam Lesinski return NO_ERROR; 3933282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3934282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3935282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Package::setStrings(const sp<AaptFile>& data, 3936282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResStringPool* strings, 3937282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DefaultKeyedVector<String16, uint32_t>* mappings) 3938282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3939282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (data->getData() == NULL) { 3940282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3941282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3942282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3943282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY(aout << "Setting restable string pool: " 3944282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski << HexDump(data->getData(), data->getSize()) << endl); 3945282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3946282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t err = strings->setTo(data->getData(), data->getSize()); 3947282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (err == NO_ERROR) { 3948282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = strings->size(); 3949282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 3950282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t len; 3951282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mappings->add(String16(strings->stringAt(i, &len)), i); 3952282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3953282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3954282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return err; 3955282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 3956282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3957282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ResourceTable::Package::applyPublicTypeOrder() 3958282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 3959282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t N = mOrderedTypes.size(); 3960282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Vector<sp<Type> > origOrder(mOrderedTypes); 3961282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3962282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 3963282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 3964282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedTypes.replaceAt(NULL, i); 3965282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3966282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3967282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 3968282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = origOrder.itemAt(i); 3969282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int32_t idx = t->getPublicIndex(); 3970282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (idx > 0) { 3971282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski idx--; 3972282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (idx >= (int32_t)mOrderedTypes.size()) { 3973282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedTypes.add(); 3974282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3975282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mOrderedTypes.itemAt(idx) != NULL) { 3976282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> ot = mOrderedTypes.itemAt(idx); 3977282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski t->getFirstPublicSourcePos().error("Multiple type names declared for public type" 3978282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski " identifier 0x%x (%s vs %s).\n" 3979282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "%s:%d: Originally defined here.", 3980282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski idx, String8(ot->getName()).string(), 3981282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(t->getName()).string(), 3982282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ot->getFirstPublicSourcePos().file.string(), 3983282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ot->getFirstPublicSourcePos().line); 3984282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 3985282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3986282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedTypes.replaceAt(t, idx); 3987282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski origOrder.removeAt(i); 3988282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski i--; 3989282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski N--; 3990282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3991282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 3992282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3993282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t j=0; 3994282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 3995282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = origOrder.itemAt(i); 3996282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // There will always be enough room for the remaining types. 3997282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (mOrderedTypes.itemAt(j) != NULL) { 3998282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski j++; 3999282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4000282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOrderedTypes.replaceAt(t, j); 4001282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4002282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4003282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 4004282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 4005282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4006282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<ResourceTable::Package> ResourceTable::getPackage(const String16& package) 4007282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 4008833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski if (package != mAssetsPackage) { 4009833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski return NULL; 4010282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4011833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski return mPackages.valueFor(package); 4012282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 4013282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4014282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<ResourceTable::Type> ResourceTable::getType(const String16& package, 4015282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 4016282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const SourcePos& sourcePos, 4017282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool doSetIndex) 4018282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 4019282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p = getPackage(package); 4020282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p == NULL) { 4021282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 4022282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4023282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return p->getType(type, sourcePos, doSetIndex); 4024282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 4025282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4026282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<ResourceTable::Entry> ResourceTable::getEntry(const String16& package, 4027282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& type, 4028282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const String16& name, 4029282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const SourcePos& sourcePos, 4030282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool overlay, 4031282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config* config, 4032282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool doSetIndex) 4033282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 4034282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = getType(package, type, sourcePos, doSetIndex); 4035282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (t == NULL) { 4036282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 4037282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4038282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return t->getEntry(name, sourcePos, config, doSetIndex, overlay, mBundle->getAutoAddOverlay()); 4039282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 4040282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4041e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinskisp<ResourceTable::ConfigList> ResourceTable::getConfigList(const String16& package, 4042e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const String16& type, const String16& name) const 4043e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski{ 4044e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const size_t packageCount = mOrderedPackages.size(); 4045e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski for (size_t pi = 0; pi < packageCount; pi++) { 4046e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const sp<Package>& p = mOrderedPackages[pi]; 4047e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski if (p == NULL || p->getName() != package) { 4048e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski continue; 4049e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4050e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4051e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const Vector<sp<Type> >& types = p->getOrderedTypes(); 4052e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const size_t typeCount = types.size(); 4053e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski for (size_t ti = 0; ti < typeCount; ti++) { 4054e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const sp<Type>& t = types[ti]; 4055e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski if (t == NULL || t->getName() != type) { 4056e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski continue; 4057e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4058e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4059e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const Vector<sp<ConfigList> >& configs = t->getOrderedConfigs(); 4060e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const size_t configCount = configs.size(); 4061e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski for (size_t ci = 0; ci < configCount; ci++) { 4062e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const sp<ConfigList>& cl = configs[ci]; 4063e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski if (cl == NULL || cl->getName() != name) { 4064e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski continue; 4065e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4066e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4067e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski return cl; 4068e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4069e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4070e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4071e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski return NULL; 4072e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski} 4073e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4074282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisp<const ResourceTable::Entry> ResourceTable::getEntry(uint32_t resID, 4075282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ResTable_config* config) const 4076282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 4077833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski size_t pid = Res_GETPACKAGE(resID)+1; 4078282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = mOrderedPackages.size(); 4079282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> p; 4080833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski for (size_t i = 0; i < N; i++) { 4081282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Package> check = mOrderedPackages[i]; 4082282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (check->getAssignedId() == pid) { 4083282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p = check; 4084282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 4085282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4086282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4087282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4088282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p == NULL) { 4089282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "warning: Package not found for resource #%08x\n", resID); 4090282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 4091282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4092282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4093282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int tid = Res_GETTYPE(resID); 4094282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tid < 0 || tid >= (int)p->getOrderedTypes().size()) { 4095282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "warning: Type not found for resource #%08x\n", resID); 4096282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 4097282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4098282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Type> t = p->getOrderedTypes()[tid]; 4099282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int eid = Res_GETENTRY(resID); 4101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (eid < 0 || eid >= (int)t->getOrderedConfigs().size()) { 4102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "warning: Entry not found for resource #%08x\n", resID); 4103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 4104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<ConfigList> c = t->getOrderedConfigs()[eid]; 4107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == NULL) { 4108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "warning: Entry not found for resource #%08x\n", resID); 4109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 4110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ConfigDescription cdesc; 4113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (config) cdesc = *config; 4114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<Entry> e = c->getEntries().valueFor(cdesc); 4115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (c == NULL) { 4116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "warning: Entry configuration not found for resource #%08x\n", resID); 4117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 4118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return e; 4121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 4122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiconst ResourceTable::Item* ResourceTable::getItem(uint32_t resID, uint32_t attrID) const 4124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 4125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<const Entry> e = getEntry(resID); 4126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (e == NULL) { 4127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 4128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = e->getBag().size(); 4131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (size_t i=0; i<N; i++) { 4132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Item& it = e->getBag().valueAt(i); 4133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (it.bagKeyId == 0) { 4134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "warning: ID not yet assigned to '%s' in bag '%s'\n", 4135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(e->getName()).string(), 4136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(e->getBag().keyAt(i)).string()); 4137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (it.bagKeyId == attrID) { 4139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return ⁢ 4140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 4144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 4145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ResourceTable::getItemValue( 4147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t resID, uint32_t attrID, Res_value* outValue) 4148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 4149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const Item* item = getItem(resID, attrID); 4150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 4151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool res = false; 4152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (item != NULL) { 4153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (item->evaluating) { 4154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sp<const Entry> e = getEntry(resID); 4155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const size_t N = e->getBag().size(); 4156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski size_t i; 4157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (i=0; i<N; i++) { 4158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (&e->getBag().valueAt(i) == item) { 4159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 4160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "warning: Circular reference detected in key '%s' of bag '%s'\n", 4163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(e->getName()).string(), 4164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String8(e->getBag().keyAt(i)).string()); 4165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 4166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski item->evaluating = true; 4168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski res = stringToValue(outValue, NULL, item->value, false, false, item->bagKeyId); 4169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NOISY( 4170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (res) { 4171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("getItemValue of #%08x[#%08x] (%s): type=#%08x, data=#%08x\n", 4172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resID, attrID, String8(getEntry(resID)->getName()).string(), 4173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outValue->dataType, outValue->data); 4174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 4175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski printf("getItemValue of #%08x[#%08x]: failed\n", 4176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resID, attrID); 4177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ); 4179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski item->evaluating = false; 4180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return res; 4182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 418382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 418482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski/** 418582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * Returns true if the given attribute ID comes from 418682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * a platform version from or after L. 418782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski */ 418882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinskibool ResourceTable::isAttributeFromL(uint32_t attrId) { 418982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const uint32_t baseAttrId = 0x010103f7; 419082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski if ((attrId & 0xffff0000) != (baseAttrId & 0xffff0000)) { 419182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski return false; 419282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 419382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 419482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski uint32_t specFlags; 419582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski if (!mAssets->getIncludedResources().getResourceFlags(attrId, &specFlags)) { 419682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski return false; 419782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 419882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 419982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski return (specFlags & ResTable_typeSpec::SPEC_PUBLIC) != 0 && 420082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski (attrId & 0x0000ffff) >= (baseAttrId & 0x0000ffff); 420182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski} 420282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 4203e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinskistatic bool isMinSdkVersionLOrAbove(const Bundle* bundle) { 4204e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski if (bundle->getMinSdkVersion() != NULL && strlen(bundle->getMinSdkVersion()) > 0) { 4205e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const char firstChar = bundle->getMinSdkVersion()[0]; 4206e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski if (firstChar >= 'L' && firstChar <= 'Z') { 4207e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski // L is the code-name for the v21 release. 4208e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski return true; 4209e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4210e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4211e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const int minSdk = atoi(bundle->getMinSdkVersion()); 4212e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski if (minSdk >= SDK_L) { 4213e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski return true; 4214e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4215e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4216e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski return false; 4217e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski} 4218e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 421982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski/** 422082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * Modifies the entries in the resource table to account for compatibility 422182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * issues with older versions of Android. 422282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * 422382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * This primarily handles the issue of private/public attribute clashes 422482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * in framework resources. 422582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * 422682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * AAPT has traditionally assigned resource IDs to public attributes, 422782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * and then followed those public definitions with private attributes. 422882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * 422982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * --- PUBLIC --- 423082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * | 0x01010234 | attr/color 423182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * | 0x01010235 | attr/background 423282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * 423382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * --- PRIVATE --- 423482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * | 0x01010236 | attr/secret 423582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * | 0x01010237 | attr/shhh 423682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * 423782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * Each release, when attributes are added, they take the place of the private 423882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * attributes and the private attributes are shifted down again. 423982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * 424082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * --- PUBLIC --- 424182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * | 0x01010234 | attr/color 424282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * | 0x01010235 | attr/background 424382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * | 0x01010236 | attr/shinyNewAttr 424482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * | 0x01010237 | attr/highlyValuedFeature 424582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * 424682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * --- PRIVATE --- 424782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * | 0x01010238 | attr/secret 424882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * | 0x01010239 | attr/shhh 424982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * 425082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * Platform code may look for private attributes set in a theme. If an app 425182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * compiled against a newer version of the platform uses a new public 425282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * attribute that happens to have the same ID as the private attribute 425382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * the older platform is expecting, then the behavior is undefined. 425482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * 425582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * We get around this by detecting any newly defined attributes (in L), 425682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * copy the resource into a -v21 qualified resource, and delete the 425782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * attribute from the original resource. This ensures that older platforms 425882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * don't see the new attribute, but when running on L+ platforms, the 425982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski * attribute will be respected. 426082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski */ 426182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinskistatus_t ResourceTable::modifyForCompat(const Bundle* bundle) { 4262e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski if (isMinSdkVersionLOrAbove(bundle)) { 426382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski // If this app will only ever run on L+ devices, 426482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski // we don't need to do any compatibility work. 4265e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski return NO_ERROR; 426682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 426782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 426882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const String16 attr16("attr"); 426982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 427082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const size_t packageCount = mOrderedPackages.size(); 427182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski for (size_t pi = 0; pi < packageCount; pi++) { 427282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski sp<Package> p = mOrderedPackages.itemAt(pi); 427382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski if (p == NULL || p->getTypes().size() == 0) { 427482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski // Empty, skip! 427582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski continue; 427682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 427782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 427882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const size_t typeCount = p->getOrderedTypes().size(); 427982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski for (size_t ti = 0; ti < typeCount; ti++) { 428082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski sp<Type> t = p->getOrderedTypes().itemAt(ti); 428182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski if (t == NULL) { 428282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski continue; 428382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 428482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 428582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const size_t configCount = t->getOrderedConfigs().size(); 428682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski for (size_t ci = 0; ci < configCount; ci++) { 428782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci); 428882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski if (c == NULL) { 428982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski continue; 429082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 429182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 429282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski Vector<key_value_pair_t<ConfigDescription, sp<Entry> > > entriesToAdd; 429382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const DefaultKeyedVector<ConfigDescription, sp<Entry> >& entries = 429482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski c->getEntries(); 429582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const size_t entryCount = entries.size(); 429682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski for (size_t ei = 0; ei < entryCount; ei++) { 429782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski sp<Entry> e = entries.valueAt(ei); 429882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski if (e == NULL || e->getType() != Entry::TYPE_BAG) { 429982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski continue; 430082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 430182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 430282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const ConfigDescription& config = entries.keyAt(ei); 430382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski if (config.sdkVersion >= SDK_L) { 430482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski // We don't need to do anything if the resource is 430582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski // already qualified for version 21 or higher. 430682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski continue; 430782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 430882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 430982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski Vector<String16> attributesToRemove; 431082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const KeyedVector<String16, Item>& bag = e->getBag(); 431182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const size_t bagCount = bag.size(); 431282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski for (size_t bi = 0; bi < bagCount; bi++) { 431382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const Item& item = bag.valueAt(bi); 431482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const uint32_t attrId = getResId(bag.keyAt(bi), &attr16); 431582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski if (isAttributeFromL(attrId)) { 431682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski attributesToRemove.add(bag.keyAt(bi)); 431782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 431882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 431982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 432082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski if (attributesToRemove.isEmpty()) { 432182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski continue; 432282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 432382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 432482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski // Duplicate the entry under the same configuration 432582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski // but with sdkVersion == SDK_L. 432682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski ConfigDescription newConfig(config); 432782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski newConfig.sdkVersion = SDK_L; 432882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski entriesToAdd.add(key_value_pair_t<ConfigDescription, sp<Entry> >( 432982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski newConfig, new Entry(*e))); 433082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 433182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski // Remove the attribute from the original. 433282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski for (size_t i = 0; i < attributesToRemove.size(); i++) { 433382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski e->removeFromBag(attributesToRemove[i]); 433482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 433582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 433682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 433782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski const size_t entriesToAddCount = entriesToAdd.size(); 433882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski for (size_t i = 0; i < entriesToAddCount; i++) { 433982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski if (entries.indexOfKey(entriesToAdd[i].key) >= 0) { 434082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski // An entry already exists for this config. 434182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski // That means that any attributes that were 434282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski // defined in L in the original bag will be overriden 434382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski // anyways on L devices, so we do nothing. 434482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski continue; 434582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 434682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 434782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski entriesToAdd[i].value->getPos() 434882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski .printf("using v%d attributes; synthesizing resource %s:%s/%s for configuration %s.", 434982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski SDK_L, 435082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski String8(p->getName()).string(), 435182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski String8(t->getName()).string(), 435282a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski String8(entriesToAdd[i].value->getName()).string(), 435382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski entriesToAdd[i].key.toString().string()); 435482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski 435582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski c->addEntry(entriesToAdd[i].key, entriesToAdd[i].value); 435682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 435782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 435882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 435982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski } 436082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski return NO_ERROR; 436182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski} 4362e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4363e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinskistatus_t ResourceTable::modifyForCompat(const Bundle* bundle, 4364e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const String16& resourceName, 4365e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const sp<AaptFile>& target, 4366e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const sp<XMLNode>& root) { 4367e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski if (isMinSdkVersionLOrAbove(bundle)) { 4368e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski return NO_ERROR; 4369e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4370e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4371e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski if (target->getResourceType() == "" || target->getGroupEntry().toParams().sdkVersion >= SDK_L) { 4372e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski // Skip resources that have no type (AndroidManifest.xml) or are already version qualified with v21 4373e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski // or higher. 4374e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski return NO_ERROR; 4375e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4376e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4377e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski Vector<key_value_pair_t<sp<XMLNode>, size_t> > attrsToRemove; 4378e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4379e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski Vector<sp<XMLNode> > nodesToVisit; 4380e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski nodesToVisit.push(root); 4381e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski while (!nodesToVisit.isEmpty()) { 4382e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski sp<XMLNode> node = nodesToVisit.top(); 4383e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski nodesToVisit.pop(); 4384e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4385e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const Vector<XMLNode::attribute_entry>& attrs = node->getAttributes(); 4386e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const size_t attrCount = attrs.size(); 4387e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski for (size_t i = 0; i < attrCount; i++) { 4388e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const XMLNode::attribute_entry& attr = attrs[i]; 4389e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski if (isAttributeFromL(attr.nameResId)) { 4390e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski attrsToRemove.add(key_value_pair_t<sp<XMLNode>, size_t>(node, i)); 4391e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4392e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4393e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4394e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski // Schedule a visit to the children. 4395e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const Vector<sp<XMLNode> >& children = node->getChildren(); 4396e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const size_t childCount = children.size(); 4397e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski for (size_t i = 0; i < childCount; i++) { 4398e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski nodesToVisit.push(children[i]); 4399e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4400e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4401e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4402e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski if (attrsToRemove.isEmpty()) { 4403e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski return NO_ERROR; 4404e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4405e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4406e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski ConfigDescription newConfig(target->getGroupEntry().toParams()); 4407e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski newConfig.sdkVersion = SDK_L; 4408e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4409e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski // Look to see if we already have an overriding v21 configuration. 4410e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski sp<ConfigList> cl = getConfigList(String16(mAssets->getPackage()), 4411e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski String16(target->getResourceType()), resourceName); 4412e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski if (cl->getEntries().indexOfKey(newConfig) < 0) { 4413e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski // We don't have an overriding entry for v21, so we must duplicate this one. 4414e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski sp<XMLNode> newRoot = root->clone(); 4415e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski sp<AaptFile> newFile = new AaptFile(target->getSourceFile(), 4416e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski AaptGroupEntry(newConfig), target->getResourceType()); 4417e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski String8 resPath = String8::format("res/%s/%s", 4418e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski newFile->getGroupEntry().toDirName(target->getResourceType()).string(), 4419e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski target->getPath().getPathLeaf().string()); 4420e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski resPath.convertToResPath(); 4421e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4422e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski // Add a resource table entry. 4423e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski SourcePos(target->getSourceFile(), -1).printf( 4424e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski "using v%d attributes; synthesizing resource %s:%s/%s for configuration %s.", 4425e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski SDK_L, 4426e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski mAssets->getPackage().string(), 4427e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski newFile->getResourceType().string(), 4428e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski String8(resourceName).string(), 4429e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski newConfig.toString().string()); 4430e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4431e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski addEntry(SourcePos(), 4432e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski String16(mAssets->getPackage()), 4433e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski String16(target->getResourceType()), 4434e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski resourceName, 4435e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski String16(resPath), 4436e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski NULL, 4437e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski &newConfig); 4438e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4439e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski // Schedule this to be compiled. 4440e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski CompileResourceWorkItem item; 4441e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski item.resourceName = resourceName; 4442e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski item.resPath = resPath; 4443e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski item.file = newFile; 4444e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski mWorkQueue.push(item); 4445e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4446e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4447e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const size_t removeCount = attrsToRemove.size(); 4448e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski for (size_t i = 0; i < removeCount; i++) { 4449e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski sp<XMLNode> node = attrsToRemove[i].key; 4450e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski size_t attrIndex = attrsToRemove[i].value; 4451e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski const XMLNode::attribute_entry& ae = node->getAttributes()[attrIndex]; 4452e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski SourcePos(node->getFilename(), node->getStartLineNumber()).printf( 4453e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski "removing attribute %s%s%s from <%s>", 4454e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski String8(ae.ns).string(), 4455e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski (ae.ns.size() == 0 ? "" : ":"), 4456e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski String8(ae.name).string(), 4457e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski String8(node->getElementName()).string()); 4458e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski node->removeAttribute(attrIndex); 4459e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski } 4460e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski 4461e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski return NO_ERROR; 4462e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski} 4463