ResourceTable.cpp revision 19138468caf7050d482dc15f35a344eab11bb756
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Copyright 2006 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Build resource files from raw assets.
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "ResourceTable.h"
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "XMLNode.h"
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/ByteOrder.h>
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/ResourceTypes.h>
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdarg.h>
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define NOISY(x) //x
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t compileXmlFile(const sp<AaptAssets>& assets,
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const sp<AaptFile>& target,
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ResourceTable* table,
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        int options)
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<XMLNode> root = XMLNode::parse(target);
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (root == NULL) {
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
26a96cbb435d7b2197ab2b61fd98d14cbd6e0c5c3dDianne Hackborn
27a96cbb435d7b2197ab2b61fd98d14cbd6e0c5c3dDianne Hackborn    return compileXmlFile(assets, root, target, table, options);
28a96cbb435d7b2197ab2b61fd98d14cbd6e0c5c3dDianne Hackborn}
29a96cbb435d7b2197ab2b61fd98d14cbd6e0c5c3dDianne Hackborn
30a96cbb435d7b2197ab2b61fd98d14cbd6e0c5c3dDianne Hackbornstatus_t compileXmlFile(const sp<AaptAssets>& assets,
31a96cbb435d7b2197ab2b61fd98d14cbd6e0c5c3dDianne Hackborn                        const sp<XMLNode>& root,
32a96cbb435d7b2197ab2b61fd98d14cbd6e0c5c3dDianne Hackborn                        const sp<AaptFile>& target,
33a96cbb435d7b2197ab2b61fd98d14cbd6e0c5c3dDianne Hackborn                        ResourceTable* table,
34a96cbb435d7b2197ab2b61fd98d14cbd6e0c5c3dDianne Hackborn                        int options)
35a96cbb435d7b2197ab2b61fd98d14cbd6e0c5c3dDianne Hackborn{
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if ((options&XML_COMPILE_STRIP_WHITESPACE) != 0) {
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        root->removeWhitespace(true, NULL);
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else  if ((options&XML_COMPILE_COMPACT_WHITESPACE) != 0) {
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        root->removeWhitespace(false, NULL);
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4219138468caf7050d482dc15f35a344eab11bb756Kenny Root    if ((options&XML_COMPILE_UTF8) != 0) {
4319138468caf7050d482dc15f35a344eab11bb756Kenny Root        root->setUTF8(true);
4419138468caf7050d482dc15f35a344eab11bb756Kenny Root    }
4519138468caf7050d482dc15f35a344eab11bb756Kenny Root
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool hasErrors = false;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if ((options&XML_COMPILE_ASSIGN_ATTRIBUTE_IDS) != 0) {
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        status_t err = root->assignResourceIds(assets, table);
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != NO_ERROR) {
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            hasErrors = true;
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = root->parseValues(assets, table);
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != NO_ERROR) {
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        hasErrors = true;
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (hasErrors) {
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    NOISY(printf("Input XML Resource:\n"));
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    NOISY(root->print());
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    err = root->flatten(target,
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (options&XML_COMPILE_STRIP_COMMENTS) != 0,
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (options&XML_COMPILE_STRIP_RAW_VALUES) != 0);
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != NO_ERROR) {
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return err;
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    NOISY(printf("Output XML Resource:\n"));
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    NOISY(ResXMLTree tree;
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        tree.setTo(target->getData(), target->getSize());
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        printXMLBlock(&tree));
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    target->setCompressionMethod(ZipEntry::kCompressDeflated);
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err;
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#undef NOISY
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define NOISY(x) //x
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct flag_entry
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char16_t* name;
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t nameLen;
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t value;
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char* description;
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char16_t referenceArray[] =
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { 'r', 'e', 'f', 'e', 'r', 'e', 'n', 'c', 'e' };
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char16_t stringArray[] =
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { 's', 't', 'r', 'i', 'n', 'g' };
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char16_t integerArray[] =
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { 'i', 'n', 't', 'e', 'g', 'e', 'r' };
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char16_t booleanArray[] =
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { 'b', 'o', 'o', 'l', 'e', 'a', 'n' };
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char16_t colorArray[] =
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { 'c', 'o', 'l', 'o', 'r' };
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char16_t floatArray[] =
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { 'f', 'l', 'o', 'a', 't' };
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char16_t dimensionArray[] =
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n' };
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char16_t fractionArray[] =
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { 'f', 'r', 'a', 'c', 't', 'i', 'o', 'n' };
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char16_t enumArray[] =
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { 'e', 'n', 'u', 'm' };
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char16_t flagsArray[] =
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { 'f', 'l', 'a', 'g', 's' };
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const flag_entry gFormatFlags[] = {
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { referenceArray, sizeof(referenceArray)/2, ResTable_map::TYPE_REFERENCE,
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "a reference to another resource, in the form \"<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>\"\n"
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "or to a theme attribute in the form \"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>\"."},
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { stringArray, sizeof(stringArray)/2, ResTable_map::TYPE_STRING,
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "a string value, using '\\\\;' to escape characters such as '\\\\n' or '\\\\uxxxx' for a unicode character." },
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { integerArray, sizeof(integerArray)/2, ResTable_map::TYPE_INTEGER,
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "an integer value, such as \"<code>100</code>\"." },
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { booleanArray, sizeof(booleanArray)/2, ResTable_map::TYPE_BOOLEAN,
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "a boolean value, either \"<code>true</code>\" or \"<code>false</code>\"." },
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { colorArray, sizeof(colorArray)/2, ResTable_map::TYPE_COLOR,
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "a color value, in the form of \"<code>#<i>rgb</i></code>\", \"<code>#<i>argb</i></code>\",\n"
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "\"<code>#<i>rrggbb</i></code>\", or \"<code>#<i>aarrggbb</i></code>\"." },
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { floatArray, sizeof(floatArray)/2, ResTable_map::TYPE_FLOAT,
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "a floating point value, such as \"<code>1.2</code>\"."},
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { dimensionArray, sizeof(dimensionArray)/2, ResTable_map::TYPE_DIMENSION,
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "a dimension value, which is a floating point number appended with a unit such as \"<code>14.5sp</code>\".\n"
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size),\n"
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "in (inches), mm (millimeters)." },
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { fractionArray, sizeof(fractionArray)/2, ResTable_map::TYPE_FRACTION,
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "a fractional value, which is a floating point number appended with either % or %p, such as \"<code>14.5%</code>\".\n"
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "The % suffix always means a percentage of the base size; the optional %p suffix provides a size relative to\n"
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "some parent container." },
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { enumArray, sizeof(enumArray)/2, ResTable_map::TYPE_ENUM, NULL },
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { flagsArray, sizeof(flagsArray)/2, ResTable_map::TYPE_FLAGS, NULL },
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { NULL, 0, 0, NULL }
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char16_t suggestedArray[] = { 's', 'u', 'g', 'g', 'e', 's', 't', 'e', 'd' };
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const flag_entry l10nRequiredFlags[] = {
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { suggestedArray, sizeof(suggestedArray)/2, ResTable_map::L10N_SUGGESTED, NULL },
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { NULL, 0, 0, NULL }
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char16_t nulStr[] = { 0 };
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic uint32_t parse_flags(const char16_t* str, size_t len,
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             const flag_entry* flags, bool* outError = NULL)
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (len > 0 && isspace(*str)) {
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        str++;
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        len--;
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (len > 0 && isspace(str[len-1])) {
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        len--;
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char16_t* const end = str + len;
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t value = 0;
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (str < end) {
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const char16_t* div = str;
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (div < end && *div != '|') {
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            div++;
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const flag_entry* cur = flags;
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (cur->name) {
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (strzcmp16(cur->name, cur->nameLen, str, div-str) == 0) {
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                value |= cur->value;
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            cur++;
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!cur->name) {
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (outError) *outError = true;
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        str = div < end ? div+1 : div;
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (outError) *outError = false;
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return value;
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic String16 mayOrMust(int type, int flags)
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if ((type&(~flags)) == 0) {
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return String16("<p>Must");
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return String16("<p>May");
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void appendTypeInfo(ResourceTable* outTable, const String16& pkg,
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const String16& typeName, const String16& ident, int type,
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const flag_entry* flags)
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool hadType = false;
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (flags->name) {
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((type&flags->value) != 0 && flags->description != NULL) {
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String16 fullMsg(mayOrMust(type, flags->value));
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fullMsg.append(String16(" be "));
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fullMsg.append(String16(flags->description));
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            outTable->appendTypeComment(pkg, typeName, ident, fullMsg);
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            hadType = true;
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        flags++;
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (hadType && (type&ResTable_map::TYPE_REFERENCE) == 0) {
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        outTable->appendTypeComment(pkg, typeName, ident,
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String16("<p>This may also be a reference to a resource (in the form\n"
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                         "\"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>\") or\n"
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                         "theme attribute (in the form\n"
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                         "\"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>\")\n"
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                         "containing a value of this type."));
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct PendingAttribute
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 myPackage;
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const SourcePos sourcePos;
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const bool appendComment;
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t type;
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String16 ident;
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String16 comment;
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool hasErrors;
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool added;
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    PendingAttribute(String16 _package, const sp<AaptFile>& in,
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ResXMLTree& block, bool _appendComment)
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        : myPackage(_package)
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        , sourcePos(in->getPrintableSource(), block.getLineNumber())
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        , appendComment(_appendComment)
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        , type(ResTable_map::TYPE_ANY)
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        , hasErrors(false)
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        , added(false)
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t createIfNeeded(ResourceTable* outTable)
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (added || hasErrors) {
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return NO_ERROR;
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        added = true;
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String16 attr16("attr");
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (outTable->hasBagOrEntry(myPackage, attr16, ident)) {
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sourcePos.error("Attribute \"%s\" has already been defined\n",
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(ident).string());
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            hasErrors = true;
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return UNKNOWN_ERROR;
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        char numberStr[16];
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sprintf(numberStr, "%d", type);
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        status_t err = outTable->addBag(sourcePos, myPackage,
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                attr16, ident, String16(""),
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String16("^type"),
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String16(numberStr), NULL, NULL);
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != NO_ERROR) {
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            hasErrors = true;
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return err;
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        outTable->appendComment(myPackage, attr16, ident, comment, appendComment);
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //printf("Attribute %s comment: %s\n", String8(ident).string(),
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //     String8(comment).string());
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return err;
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic status_t compileAttribute(const sp<AaptFile>& in,
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 ResXMLTree& block,
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16& myPackage,
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 ResourceTable* outTable,
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 String16* outIdent = NULL,
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 bool inStyleable = false)
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    PendingAttribute attr(myPackage, in, block, inStyleable);
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 attr16("attr");
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 id16("id");
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Attribute type constants.
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 enum16("enum");
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 flag16("flag");
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ResXMLTree::event_code_t code;
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t len;
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err;
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ssize_t identIdx = block.indexOfAttribute(NULL, "name");
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (identIdx >= 0) {
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        attr.ident = String16(block.getAttributeStringValue(identIdx, &len));
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (outIdent) {
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            *outIdent = attr.ident;
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        attr.sourcePos.error("A 'name' attribute is required for <attr>\n");
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        attr.hasErrors = true;
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    attr.comment = String16(
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            block.getComment(&len) ? block.getComment(&len) : nulStr);
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ssize_t typeIdx = block.indexOfAttribute(NULL, "format");
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (typeIdx >= 0) {
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String16 typeStr = String16(block.getAttributeStringValue(typeIdx, &len));
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        attr.type = parse_flags(typeStr.string(), typeStr.size(), gFormatFlags);
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (attr.type == 0) {
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            attr.sourcePos.error("Tag <attr> 'format' attribute value \"%s\" not valid\n",
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(typeStr).string());
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            attr.hasErrors = true;
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        attr.createIfNeeded(outTable);
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (!inStyleable) {
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Attribute definitions outside of styleables always define the
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // attribute as a generic value.
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        attr.createIfNeeded(outTable);
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //printf("Attribute %s: type=0x%08x\n", String8(attr.ident).string(), attr.type);
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ssize_t minIdx = block.indexOfAttribute(NULL, "min");
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (minIdx >= 0) {
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String16 val = String16(block.getAttributeStringValue(minIdx, &len));
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!ResTable::stringToInt(val.string(), val.size(), NULL)) {
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            attr.sourcePos.error("Tag <attr> 'min' attribute must be a number, not \"%s\"\n",
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(val).string());
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            attr.hasErrors = true;
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        attr.createIfNeeded(outTable);
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!attr.hasErrors) {
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident,
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String16(""), String16("^min"), String16(val), NULL, NULL);
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (err != NO_ERROR) {
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                attr.hasErrors = true;
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ssize_t maxIdx = block.indexOfAttribute(NULL, "max");
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (maxIdx >= 0) {
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String16 val = String16(block.getAttributeStringValue(maxIdx, &len));
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!ResTable::stringToInt(val.string(), val.size(), NULL)) {
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            attr.sourcePos.error("Tag <attr> 'max' attribute must be a number, not \"%s\"\n",
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(val).string());
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            attr.hasErrors = true;
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        attr.createIfNeeded(outTable);
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!attr.hasErrors) {
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident,
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String16(""), String16("^max"), String16(val), NULL, NULL);
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            attr.hasErrors = true;
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if ((minIdx >= 0 || maxIdx >= 0) && (attr.type&ResTable_map::TYPE_INTEGER) == 0) {
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        attr.sourcePos.error("Tag <attr> must have format=integer attribute if using max or min\n");
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        attr.hasErrors = true;
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ssize_t l10nIdx = block.indexOfAttribute(NULL, "localization");
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (l10nIdx >= 0) {
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const uint16_t* str = block.getAttributeStringValue(l10nIdx, &len);
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bool error;
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        uint32_t l10n_required = parse_flags(str, len, l10nRequiredFlags, &error);
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (error) {
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            attr.sourcePos.error("Tag <attr> 'localization' attribute value \"%s\" not valid\n",
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(str).string());
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            attr.hasErrors = true;
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        attr.createIfNeeded(outTable);
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!attr.hasErrors) {
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            char buf[10];
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sprintf(buf, "%d", l10n_required);
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident,
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String16(""), String16("^l10n"), String16(buf), NULL, NULL);
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (err != NO_ERROR) {
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                attr.hasErrors = true;
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String16 enumOrFlagsComment;
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (code == ResXMLTree::START_TAG) {
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            uint32_t localType = 0;
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (strcmp16(block.getElementName(&len), enum16.string()) == 0) {
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                localType = ResTable_map::TYPE_ENUM;
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), flag16.string()) == 0) {
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                localType = ResTable_map::TYPE_FLAGS;
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                SourcePos(in->getPrintableSource(), block.getLineNumber())
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        .error("Tag <%s> can not appear inside <attr>, only <enum> or <flag>\n",
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String8(block.getElementName(&len)).string());
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return UNKNOWN_ERROR;
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            attr.createIfNeeded(outTable);
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (attr.type == ResTable_map::TYPE_ANY) {
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // No type was explicitly stated, so supplying enum tags
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // implicitly creates an enum or flag.
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                attr.type = 0;
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if ((attr.type&(ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS)) == 0) {
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Wasn't originally specified as an enum, so update its type.
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                attr.type |= localType;
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!attr.hasErrors) {
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    char numberStr[16];
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sprintf(numberStr, "%d", attr.type);
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    err = outTable->addBag(SourcePos(in->getPrintableSource(), block.getLineNumber()),
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            myPackage, attr16, attr.ident, String16(""),
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            String16("^type"), String16(numberStr), NULL, NULL, true);
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (err != NO_ERROR) {
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        attr.hasErrors = true;
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if ((uint32_t)(attr.type&(ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS)) != localType) {
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (localType == ResTable_map::TYPE_ENUM) {
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    SourcePos(in->getPrintableSource(), block.getLineNumber())
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            .error("<enum> attribute can not be used inside a flags format\n");
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    attr.hasErrors = true;
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    SourcePos(in->getPrintableSource(), block.getLineNumber())
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            .error("<flag> attribute can not be used inside a enum format\n");
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    attr.hasErrors = true;
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String16 itemIdent;
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ssize_t itemIdentIdx = block.indexOfAttribute(NULL, "name");
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (itemIdentIdx >= 0) {
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                itemIdent = String16(block.getAttributeStringValue(itemIdentIdx, &len));
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                SourcePos(in->getPrintableSource(), block.getLineNumber())
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        .error("A 'name' attribute is required for <enum> or <flag>\n");
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                attr.hasErrors = true;
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String16 value;
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ssize_t valueIdx = block.indexOfAttribute(NULL, "value");
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (valueIdx >= 0) {
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                value = String16(block.getAttributeStringValue(valueIdx, &len));
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                SourcePos(in->getPrintableSource(), block.getLineNumber())
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        .error("A 'value' attribute is required for <enum> or <flag>\n");
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                attr.hasErrors = true;
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!attr.hasErrors && !ResTable::stringToInt(value.string(), value.size(), NULL)) {
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                SourcePos(in->getPrintableSource(), block.getLineNumber())
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        .error("Tag <enum> or <flag> 'value' attribute must be a number,"
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        " not \"%s\"\n",
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String8(value).string());
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                attr.hasErrors = true;
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Make sure an id is defined for this enum/flag identifier...
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!attr.hasErrors && !outTable->hasBagOrEntry(itemIdent, &id16, &myPackage)) {
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                err = outTable->startBag(SourcePos(in->getPrintableSource(), block.getLineNumber()),
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                         myPackage, id16, itemIdent, String16(), NULL);
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (err != NO_ERROR) {
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    attr.hasErrors = true;
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!attr.hasErrors) {
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (enumOrFlagsComment.size() == 0) {
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    enumOrFlagsComment.append(mayOrMust(attr.type,
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS));
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    enumOrFlagsComment.append((attr.type&ResTable_map::TYPE_ENUM)
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       ? String16(" be one of the following constant values.")
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       : String16(" be one or more (separated by '|') of the following constant values."));
48759ad275e937bb3c32e59bc01d86f484e7b4bdbe1Dirk Dougherty                    enumOrFlagsComment.append(String16("</p>\n<table>\n"
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                "<colgroup align=\"left\" />\n"
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                "<colgroup align=\"left\" />\n"
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                "<colgroup align=\"left\" />\n"
49159ad275e937bb3c32e59bc01d86f484e7b4bdbe1Dirk Dougherty                                                "<tr><th>Constant</th><th>Value</th><th>Description</th></tr>"));
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
49459ad275e937bb3c32e59bc01d86f484e7b4bdbe1Dirk Dougherty                enumOrFlagsComment.append(String16("\n<tr><td><code>"));
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                enumOrFlagsComment.append(itemIdent);
49659ad275e937bb3c32e59bc01d86f484e7b4bdbe1Dirk Dougherty                enumOrFlagsComment.append(String16("</code></td><td>"));
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                enumOrFlagsComment.append(value);
49859ad275e937bb3c32e59bc01d86f484e7b4bdbe1Dirk Dougherty                enumOrFlagsComment.append(String16("</td><td>"));
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (block.getComment(&len)) {
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    enumOrFlagsComment.append(String16(block.getComment(&len)));
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
50259ad275e937bb3c32e59bc01d86f484e7b4bdbe1Dirk Dougherty                enumOrFlagsComment.append(String16("</td></tr>"));
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                err = outTable->addBag(SourcePos(in->getPrintableSource(), block.getLineNumber()),
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       myPackage,
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       attr16, attr.ident, String16(""),
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       itemIdent, value, NULL, NULL, false, true);
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (err != NO_ERROR) {
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    attr.hasErrors = true;
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (code == ResXMLTree::END_TAG) {
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (strcmp16(block.getElementName(&len), attr16.string()) == 0) {
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if ((attr.type&ResTable_map::TYPE_ENUM) != 0) {
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (strcmp16(block.getElementName(&len), enum16.string()) != 0) {
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    SourcePos(in->getPrintableSource(), block.getLineNumber())
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            .error("Found tag </%s> where </enum> is expected\n",
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            String8(block.getElementName(&len)).string());
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return UNKNOWN_ERROR;
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (strcmp16(block.getElementName(&len), flag16.string()) != 0) {
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    SourcePos(in->getPrintableSource(), block.getLineNumber())
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            .error("Found tag </%s> where </flag> is expected\n",
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            String8(block.getElementName(&len)).string());
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return UNKNOWN_ERROR;
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!attr.hasErrors && attr.added) {
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        appendTypeInfo(outTable, myPackage, attr16, attr.ident, attr.type, gFormatFlags);
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!attr.hasErrors && enumOrFlagsComment.size() > 0) {
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        enumOrFlagsComment.append(String16("\n</table>"));
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        outTable->appendTypeComment(myPackage, attr16, attr.ident, enumOrFlagsComment);
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool localeIsDefined(const ResTable_config& config)
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return config.locale == 0;
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t parseAndAddBag(Bundle* bundle,
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const sp<AaptFile>& in,
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ResXMLTree* block,
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const ResTable_config& config,
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const String16& myPackage,
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const String16& curType,
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const String16& ident,
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const String16& parentIdent,
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const String16& itemIdent,
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        int32_t curFormat,
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        bool pseudolocalize,
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const bool overwrite,
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ResourceTable* outTable)
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err;
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 item16("item");
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String16 str;
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Vector<StringPool::entry_style_span> spans;
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    err = parseStyledString(bundle, in->getPrintableSource().string(),
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            block, item16, &str, &spans,
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            pseudolocalize);
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != NO_ERROR) {
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return err;
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    NOISY(printf("Adding resource bag entry l=%c%c c=%c%c orien=%d d=%d "
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 " pid=%s, bag=%s, id=%s: %s\n",
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 config.language[0], config.language[1],
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 config.country[0], config.country[1],
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 config.orientation, config.density,
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 String8(parentIdent).string(),
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 String8(ident).string(),
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 String8(itemIdent).string(),
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 String8(str).string()));
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    err = outTable->addBag(SourcePos(in->getPrintableSource(), block->getLineNumber()),
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           myPackage, curType, ident, parentIdent, itemIdent, str,
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           &spans, &config, overwrite, false, curFormat);
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err;
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t parseAndAddEntry(Bundle* bundle,
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const sp<AaptFile>& in,
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ResXMLTree* block,
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const ResTable_config& config,
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const String16& myPackage,
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const String16& curType,
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const String16& ident,
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const String16& curTag,
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        bool curIsStyled,
6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        int32_t curFormat,
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        bool pseudolocalize,
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const bool overwrite,
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ResourceTable* outTable)
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err;
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String16 str;
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Vector<StringPool::entry_style_span> spans;
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    err = parseStyledString(bundle, in->getPrintableSource().string(), block,
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            curTag, &str, curIsStyled ? &spans : NULL,
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            pseudolocalize);
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err < NO_ERROR) {
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return err;
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    NOISY(printf("Adding resource entry l=%c%c c=%c%c orien=%d d=%d id=%s: %s\n",
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 config.language[0], config.language[1],
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 config.country[0], config.country[1],
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 config.orientation, config.density,
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 String8(ident).string(), String8(str).string()));
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    err = outTable->addEntry(SourcePos(in->getPrintableSource(), block->getLineNumber()),
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             myPackage, curType, ident, str, &spans, &config,
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             false, curFormat, overwrite);
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err;
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t compileResourceFile(Bundle* bundle,
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             const sp<AaptAssets>& assets,
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             const sp<AaptFile>& in,
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             const ResTable_config& defParams,
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             const bool overwrite,
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             ResourceTable* outTable)
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ResXMLTree block;
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = parseXMLResource(in, &block, false, true);
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != NO_ERROR) {
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return err;
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Top-level tag.
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 resources16("resources");
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Identifier declaration tags.
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 declare_styleable16("declare-styleable");
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 attr16("attr");
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Data creation organizational tags.
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 string16("string");
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 drawable16("drawable");
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 color16("color");
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 bool16("bool");
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 integer16("integer");
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 dimen16("dimen");
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 fraction16("fraction");
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 style16("style");
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 plurals16("plurals");
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 array16("array");
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 string_array16("string-array");
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 integer_array16("integer-array");
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 public16("public");
668f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn    const String16 public_padding16("public-padding");
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 private_symbols16("private-symbols");
67058c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn    const String16 add_resource16("add-resource");
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 skip16("skip");
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 eat_comment16("eat-comment");
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Data creation tags.
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 bag16("bag");
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 item16("item");
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Attribute type constants.
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 enum16("enum");
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // plural values
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 other16("other");
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 quantityOther16("^other");
6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 zero16("zero");
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 quantityZero16("^zero");
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 one16("one");
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 quantityOne16("^one");
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 two16("two");
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 quantityTwo16("^two");
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 few16("few");
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 quantityFew16("^few");
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 many16("many");
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 quantityMany16("^many");
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // useful attribute names and special values
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 name16("name");
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 translatable16("translatable");
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 false16("false");
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 myPackage(assets->getPackage());
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool hasErrors = false;
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
704f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn    DefaultKeyedVector<String16, uint32_t> nextPublicId(0);
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ResXMLTree::event_code_t code;
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    do {
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        code = block.next();
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } while (code == ResXMLTree::START_NAMESPACE);
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t len;
7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (code != ResXMLTree::START_TAG) {
7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "No start tag found\n");
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (strcmp16(block.getElementName(&len), resources16.string()) != 0) {
7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "Invalid start tag %s\n", String8(block.getElementName(&len)).string());
7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ResTable_config curParams(defParams);
7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ResTable_config pseudoParams(curParams);
7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pseudoParams.language[0] = 'z';
7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pseudoParams.language[1] = 'z';
7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pseudoParams.country[0] = 'Z';
7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pseudoParams.country[1] = 'Z';
7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (code == ResXMLTree::START_TAG) {
7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const String16* curTag = NULL;
7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String16 curType;
7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int32_t curFormat = ResTable_map::TYPE_ANY;
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bool curIsBag = false;
7371aa8170e6a448afad86e5d62927d3b8ca4cd9707Robert Greenwalt            bool curIsBagReplaceOnOverwrite = false;
7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bool curIsStyled = false;
7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bool curIsPseudolocalizable = false;
7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bool localHasErrors = false;
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {
7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                while ((code=block.next()) != ResXMLTree::END_DOCUMENT
7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        && code != ResXMLTree::BAD_DOCUMENT) {
7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (code == ResXMLTree::END_TAG) {
7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {
7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            break;
7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) {
7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                while ((code=block.next()) != ResXMLTree::END_DOCUMENT
7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        && code != ResXMLTree::BAD_DOCUMENT) {
7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (code == ResXMLTree::END_TAG) {
7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) {
7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            break;
7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), public16.string()) == 0) {
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());
7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String16 type;
7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ssize_t typeIdx = block.indexOfAttribute(NULL, "type");
7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (typeIdx < 0) {
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    srcPos.error("A 'type' attribute is required for <public>\n");
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hasErrors = localHasErrors = true;
7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                type = String16(block.getAttributeStringValue(typeIdx, &len));
7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String16 name;
7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ssize_t nameIdx = block.indexOfAttribute(NULL, "name");
7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (nameIdx < 0) {
7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    srcPos.error("A 'name' attribute is required for <public>\n");
7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hasErrors = localHasErrors = true;
7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                name = String16(block.getAttributeStringValue(nameIdx, &len));
7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                uint32_t ident = 0;
7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ssize_t identIdx = block.indexOfAttribute(NULL, "id");
7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (identIdx >= 0) {
7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    const char16_t* identStr = block.getAttributeStringValue(identIdx, &len);
7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Res_value identValue;
7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (!ResTable::stringToInt(identStr, len, &identValue)) {
7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        srcPos.error("Given 'id' attribute is not an integer: %s\n",
7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                String8(block.getAttributeStringValue(identIdx, &len)).string());
7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        hasErrors = localHasErrors = true;
7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else {
7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ident = identValue.data;
794f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        nextPublicId.replaceValueFor(type, ident+1);
7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
796f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                } else if (nextPublicId.indexOfKey(type) < 0) {
7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    srcPos.error("No 'id' attribute supplied <public>,"
7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            " and no previous id defined in this file.\n");
7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hasErrors = localHasErrors = true;
8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (!localHasErrors) {
801f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    ident = nextPublicId.valueFor(type);
802f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    nextPublicId.replaceValueFor(type, ident+1);
8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!localHasErrors) {
8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    err = outTable->addPublic(srcPos, myPackage, type, name, ident);
8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (err < NO_ERROR) {
8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        hasErrors = localHasErrors = true;
8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!localHasErrors) {
8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R"));
8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (symbols != NULL) {
8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        symbols = symbols->addNestedSymbol(String8(type), srcPos);
8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (symbols != NULL) {
8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        symbols->makeSymbolPublic(String8(name), srcPos);
8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String16 comment(
8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            block.getComment(&len) ? block.getComment(&len) : nulStr);
8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        symbols->appendComment(String8(name), comment, srcPos);
8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else {
8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        srcPos.error("Unable to create symbols!\n");
8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        hasErrors = localHasErrors = true;
8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (code == ResXMLTree::END_TAG) {
8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (strcmp16(block.getElementName(&len), public16.string()) == 0) {
8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            break;
8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
836f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn            } else if (strcmp16(block.getElementName(&len), public_padding16.string()) == 0) {
837f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());
838f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn
839f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                String16 type;
840f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                ssize_t typeIdx = block.indexOfAttribute(NULL, "type");
841f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                if (typeIdx < 0) {
842f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    srcPos.error("A 'type' attribute is required for <public-padding>\n");
843f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    hasErrors = localHasErrors = true;
844f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                }
845f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                type = String16(block.getAttributeStringValue(typeIdx, &len));
846f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn
847f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                String16 name;
848f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                ssize_t nameIdx = block.indexOfAttribute(NULL, "name");
849f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                if (nameIdx < 0) {
850f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    srcPos.error("A 'name' attribute is required for <public-padding>\n");
851f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    hasErrors = localHasErrors = true;
852f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                }
853f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                name = String16(block.getAttributeStringValue(nameIdx, &len));
854f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn
855f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                uint32_t start = 0;
856f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                ssize_t startIdx = block.indexOfAttribute(NULL, "start");
857f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                if (startIdx >= 0) {
858f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    const char16_t* startStr = block.getAttributeStringValue(startIdx, &len);
859f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    Res_value startValue;
860f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    if (!ResTable::stringToInt(startStr, len, &startValue)) {
861f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        srcPos.error("Given 'start' attribute is not an integer: %s\n",
862f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                                String8(block.getAttributeStringValue(startIdx, &len)).string());
863f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        hasErrors = localHasErrors = true;
864f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    } else {
865f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        start = startValue.data;
866f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    }
867f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                } else if (nextPublicId.indexOfKey(type) < 0) {
868f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    srcPos.error("No 'start' attribute supplied <public-padding>,"
869f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                            " and no previous id defined in this file.\n");
870f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    hasErrors = localHasErrors = true;
871f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                } else if (!localHasErrors) {
872f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    start = nextPublicId.valueFor(type);
873f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                }
874f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn
875f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                uint32_t end = 0;
876f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                ssize_t endIdx = block.indexOfAttribute(NULL, "end");
877f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                if (endIdx >= 0) {
878f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    const char16_t* endStr = block.getAttributeStringValue(endIdx, &len);
879f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    Res_value endValue;
880f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    if (!ResTable::stringToInt(endStr, len, &endValue)) {
881f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        srcPos.error("Given 'end' attribute is not an integer: %s\n",
882f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                                String8(block.getAttributeStringValue(endIdx, &len)).string());
883f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        hasErrors = localHasErrors = true;
884f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    } else {
885f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        end = endValue.data;
886f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    }
887f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                } else {
888f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    srcPos.error("No 'end' attribute supplied <public-padding>\n");
889f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    hasErrors = localHasErrors = true;
890f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                }
891f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn
892f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                if (end >= start) {
893f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    nextPublicId.replaceValueFor(type, end+1);
894f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                } else {
895f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    srcPos.error("Padding start '%ul' is after end '%ul'\n",
896f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                            start, end);
897f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    hasErrors = localHasErrors = true;
898f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                }
899f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn
900f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                String16 comment(
901f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    block.getComment(&len) ? block.getComment(&len) : nulStr);
902f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                for (uint32_t curIdent=start; curIdent<=end; curIdent++) {
903f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    if (localHasErrors) {
904f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        break;
905f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    }
906f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    String16 curName(name);
907f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    char buf[64];
908f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    sprintf(buf, "%d", (int)(end-curIdent+1));
909f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    curName.append(String16(buf));
910f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn
911f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    err = outTable->addEntry(srcPos, myPackage, type, curName,
912f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                                             String16("padding"), NULL, &curParams, false,
913f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                                             ResTable_map::TYPE_STRING, overwrite);
914f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    if (err < NO_ERROR) {
915f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        hasErrors = localHasErrors = true;
916f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        break;
917f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    }
918f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    err = outTable->addPublic(srcPos, myPackage, type,
919f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                            curName, curIdent);
920f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    if (err < NO_ERROR) {
921f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        hasErrors = localHasErrors = true;
922f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        break;
923f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    }
924f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R"));
925f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    if (symbols != NULL) {
926f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        symbols = symbols->addNestedSymbol(String8(type), srcPos);
927f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    }
928f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    if (symbols != NULL) {
929f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        symbols->makeSymbolPublic(String8(curName), srcPos);
930f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        symbols->appendComment(String8(curName), comment, srcPos);
931f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    } else {
932f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        srcPos.error("Unable to create symbols!\n");
933f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        hasErrors = localHasErrors = true;
934f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    }
935f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                }
936f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn
937f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
938f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    if (code == ResXMLTree::END_TAG) {
939f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        if (strcmp16(block.getElementName(&len), public_padding16.string()) == 0) {
940f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                            break;
941f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        }
942f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    }
943f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                }
944f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                continue;
945f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn
9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), private_symbols16.string()) == 0) {
9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String16 pkg;
9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ssize_t pkgIdx = block.indexOfAttribute(NULL, "package");
9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (pkgIdx < 0) {
9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            "A 'package' attribute is required for <private-symbols>\n");
9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hasErrors = localHasErrors = true;
9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pkg = String16(block.getAttributeStringValue(pkgIdx, &len));
9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!localHasErrors) {
9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    assets->setSymbolsPrivatePackage(String8(pkg));
9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (code == ResXMLTree::END_TAG) {
9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (strcmp16(block.getElementName(&len), private_symbols16.string()) == 0) {
9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            break;
9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
96858c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn            } else if (strcmp16(block.getElementName(&len), add_resource16.string()) == 0) {
96958c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());
97058c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn
97158c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                String16 typeName;
97258c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                ssize_t typeIdx = block.indexOfAttribute(NULL, "type");
97358c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                if (typeIdx < 0) {
97458c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                    srcPos.error("A 'type' attribute is required for <add-resource>\n");
97558c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                    hasErrors = localHasErrors = true;
97658c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                }
97758c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                typeName = String16(block.getAttributeStringValue(typeIdx, &len));
97858c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn
97958c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                String16 name;
98058c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                ssize_t nameIdx = block.indexOfAttribute(NULL, "name");
98158c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                if (nameIdx < 0) {
98258c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                    srcPos.error("A 'name' attribute is required for <add-resource>\n");
98358c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                    hasErrors = localHasErrors = true;
98458c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                }
98558c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                name = String16(block.getAttributeStringValue(nameIdx, &len));
98658c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn
98758c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                outTable->canAddEntry(srcPos, myPackage, typeName, name);
98858c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn
98958c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
99058c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                    if (code == ResXMLTree::END_TAG) {
99193d72516994277acdd3894a169ec1f1cbc50db97Robert Greenwalt                        if (strcmp16(block.getElementName(&len), add_resource16.string()) == 0) {
99258c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                            break;
99358c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                        }
99458c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                    }
99558c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                }
99658c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                continue;
99758c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn
9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), declare_styleable16.string()) == 0) {
9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());
10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String16 ident;
10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ssize_t identIdx = block.indexOfAttribute(NULL, "name");
10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (identIdx < 0) {
10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    srcPos.error("A 'name' attribute is required for <declare-styleable>\n");
10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hasErrors = localHasErrors = true;
10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ident = String16(block.getAttributeStringValue(identIdx, &len));
10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R"));
10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!localHasErrors) {
10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (symbols != NULL) {
10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        symbols = symbols->addNestedSymbol(String8("styleable"), srcPos);
10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sp<AaptSymbols> styleSymbols = symbols;
10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (symbols != NULL) {
10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        symbols = symbols->addNestedSymbol(String8(ident), srcPos);
10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (symbols == NULL) {
10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        srcPos.error("Unable to create symbols!\n");
10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        return UNKNOWN_ERROR;
10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String16 comment(
10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        block.getComment(&len) ? block.getComment(&len) : nulStr);
10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    styleSymbols->appendComment(String8(ident), comment, srcPos);
10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    symbols = NULL;
10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (code == ResXMLTree::START_TAG) {
10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {
10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            while ((code=block.next()) != ResXMLTree::END_DOCUMENT
10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                   && code != ResXMLTree::BAD_DOCUMENT) {
10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                if (code == ResXMLTree::END_TAG) {
10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {
10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        break;
10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    }
10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                }
10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            continue;
10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } else if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) {
10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            while ((code=block.next()) != ResXMLTree::END_DOCUMENT
10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                   && code != ResXMLTree::BAD_DOCUMENT) {
10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                if (code == ResXMLTree::END_TAG) {
10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) {
10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        break;
10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    }
10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                }
10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            continue;
10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } else if (strcmp16(block.getElementName(&len), attr16.string()) != 0) {
10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    "Tag <%s> can not appear inside <declare-styleable>, only <attr>\n",
10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    String8(block.getElementName(&len)).string());
10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            return UNKNOWN_ERROR;
10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String16 comment(
10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            block.getComment(&len) ? block.getComment(&len) : nulStr);
10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String16 itemIdent;
10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        err = compileAttribute(in, block, myPackage, outTable, &itemIdent, true);
10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (err != NO_ERROR) {
10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            hasErrors = localHasErrors = true;
10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (symbols != NULL) {
10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            SourcePos srcPos(String8(in->getPrintableSource()), block.getLineNumber());
10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            symbols->addSymbol(String8(itemIdent), 0, srcPos);
10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            symbols->appendComment(String8(itemIdent), comment, srcPos);
10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            //printf("Attribute %s comment: %s\n", String8(itemIdent).string(),
10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            //     String8(comment).string());
10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else if (code == ResXMLTree::END_TAG) {
10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (strcmp16(block.getElementName(&len), declare_styleable16.string()) == 0) {
10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            break;
10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                "Found tag </%s> where </attr> is expected\n",
10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                String8(block.getElementName(&len)).string());
10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        return UNKNOWN_ERROR;
10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), attr16.string()) == 0) {
10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                err = compileAttribute(in, block, myPackage, outTable, NULL);
10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (err != NO_ERROR) {
10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hasErrors = true;
10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), item16.string()) == 0) {
10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &item16;
10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ssize_t attri = block.indexOfAttribute(NULL, "type");
10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (attri >= 0) {
10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    curType = String16(block.getAttributeStringValue(attri, &len));
10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ssize_t formatIdx = block.indexOfAttribute(NULL, "format");
11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (formatIdx >= 0) {
11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String16 formatStr = String16(block.getAttributeStringValue(
11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                formatIdx, &len));
11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        curFormat = parse_flags(formatStr.string(), formatStr.size(),
11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                gFormatFlags);
11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (curFormat == 0) {
11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    "Tag <item> 'format' attribute value \"%s\" not valid\n",
11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    String8(formatStr).string());
11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            hasErrors = localHasErrors = true;
11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            "A 'type' attribute is required for <item>\n");
11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hasErrors = localHasErrors = true;
11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curIsStyled = true;
11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), string16.string()) == 0) {
11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Note the existence and locale of every string we process
11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                char rawLocale[16];
11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curParams.getLocale(rawLocale);
11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String8 locale(rawLocale);
11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String16 name;
11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String16 translatable;
11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                size_t n = block.getAttributeCount();
11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (size_t i = 0; i < n; i++) {
11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    size_t length;
11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    const uint16_t* attr = block.getAttributeName(i, &length);
11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (strcmp16(attr, name16.string()) == 0) {
11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        name.setTo(block.getAttributeStringValue(i, &length));
11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else if (strcmp16(attr, translatable16.string()) == 0) {
11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        translatable.setTo(block.getAttributeStringValue(i, &length));
11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (name.size() > 0) {
11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (translatable == false16) {
11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // Untranslatable strings must only exist in the default [empty] locale
11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (locale.size() > 0) {
11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            fprintf(stderr, "aapt: warning: string '%s' in %s marked untranslatable but exists"
11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    " in locale '%s'\n", String8(name).string(),
11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    bundle->getResourceSourceDirs()[0],
11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    locale.string());
11459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            // hasErrors = localHasErrors = true;
11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } else {
11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            // Intentionally empty block:
11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            //
11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            // Don't add untranslatable strings to the localization table; that
11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            // way if we later see localizations of them, they'll be flagged as
11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            // having no default translation.
11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else {
11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        outTable->addLocalization(name, locale);
11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &string16;
11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curType = string16;
11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_STRING;
11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curIsStyled = true;
11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curIsPseudolocalizable = true;
11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), drawable16.string()) == 0) {
11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &drawable16;
11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curType = drawable16;
11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_COLOR;
11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), color16.string()) == 0) {
11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &color16;
11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curType = color16;
11709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_COLOR;
11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), bool16.string()) == 0) {
11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &bool16;
11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curType = bool16;
11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_BOOLEAN;
11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), integer16.string()) == 0) {
11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &integer16;
11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curType = integer16;
11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_INTEGER;
11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), dimen16.string()) == 0) {
11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &dimen16;
11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curType = dimen16;
11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_DIMENSION;
11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), fraction16.string()) == 0) {
11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &fraction16;
11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curType = fraction16;
11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_FRACTION;
11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), bag16.string()) == 0) {
11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &bag16;
11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curIsBag = true;
11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ssize_t attri = block.indexOfAttribute(NULL, "type");
11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (attri >= 0) {
11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    curType = String16(block.getAttributeStringValue(attri, &len));
11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            "A 'type' attribute is required for <bag>\n");
11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hasErrors = localHasErrors = true;
11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), style16.string()) == 0) {
11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &style16;
12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curType = style16;
12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curIsBag = true;
12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), plurals16.string()) == 0) {
12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &plurals16;
12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curType = plurals16;
12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curIsBag = true;
12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), array16.string()) == 0) {
12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &array16;
12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curType = array16;
12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curIsBag = true;
12101aa8170e6a448afad86e5d62927d3b8ca4cd9707Robert Greenwalt                curIsBagReplaceOnOverwrite = true;
12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ssize_t formatIdx = block.indexOfAttribute(NULL, "format");
12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (formatIdx >= 0) {
12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String16 formatStr = String16(block.getAttributeStringValue(
12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            formatIdx, &len));
12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    curFormat = parse_flags(formatStr.string(), formatStr.size(),
12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                            gFormatFlags);
12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (curFormat == 0) {
12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                "Tag <array> 'format' attribute value \"%s\" not valid\n",
12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                String8(formatStr).string());
12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        hasErrors = localHasErrors = true;
12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
12249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), string_array16.string()) == 0) {
12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &string_array16;
12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curType = array16;
12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_STRING;
12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curIsBag = true;
12291aa8170e6a448afad86e5d62927d3b8ca4cd9707Robert Greenwalt                curIsBagReplaceOnOverwrite = true;
12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curIsPseudolocalizable = true;
12319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), integer_array16.string()) == 0) {
12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &integer_array16;
12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curType = array16;
12349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_INTEGER;
12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curIsBag = true;
12361aa8170e6a448afad86e5d62927d3b8ca4cd9707Robert Greenwalt                curIsBagReplaceOnOverwrite = true;
12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        "Found tag %s where item is expected\n",
12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String8(block.getElementName(&len)).string());
12419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return UNKNOWN_ERROR;
12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String16 ident;
12459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ssize_t identIdx = block.indexOfAttribute(NULL, "name");
12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (identIdx >= 0) {
12479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ident = String16(block.getAttributeStringValue(identIdx, &len));
12489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
12499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
12509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        "A 'name' attribute is required for <%s>\n",
12519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String8(*curTag).string());
12529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                hasErrors = localHasErrors = true;
12539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
12549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String16 comment(block.getComment(&len) ? block.getComment(&len) : nulStr);
12569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (curIsBag) {
12589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Figure out the parent of this bag...
12599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String16 parentIdent;
12609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ssize_t parentIdentIdx = block.indexOfAttribute(NULL, "parent");
12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (parentIdentIdx >= 0) {
12629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    parentIdent = String16(block.getAttributeStringValue(parentIdentIdx, &len));
12639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
12649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ssize_t sep = ident.findLast('.');
12659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (sep >= 0) {
12669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        parentIdent.setTo(ident, sep);
12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
12689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
12699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!localHasErrors) {
12711aa8170e6a448afad86e5d62927d3b8ca4cd9707Robert Greenwalt                    err = outTable->startBag(SourcePos(in->getPrintableSource(),
12721aa8170e6a448afad86e5d62927d3b8ca4cd9707Robert Greenwalt                            block.getLineNumber()), myPackage, curType, ident,
12731aa8170e6a448afad86e5d62927d3b8ca4cd9707Robert Greenwalt                            parentIdent, &curParams,
12741aa8170e6a448afad86e5d62927d3b8ca4cd9707Robert Greenwalt                            overwrite, curIsBagReplaceOnOverwrite);
12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (err != NO_ERROR) {
12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        hasErrors = localHasErrors = true;
12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ssize_t elmIndex = 0;
12819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                char elmIndexStr[14];
12829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                while ((code=block.next()) != ResXMLTree::END_DOCUMENT
12839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        && code != ResXMLTree::BAD_DOCUMENT) {
12849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (code == ResXMLTree::START_TAG) {
12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (strcmp16(block.getElementName(&len), item16.string()) != 0) {
12879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
12889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    "Tag <%s> can not appear inside <%s>, only <item>\n",
12899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    String8(block.getElementName(&len)).string(),
12909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    String8(*curTag).string());
12919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            return UNKNOWN_ERROR;
12929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
12939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String16 itemIdent;
12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (curType == array16) {
12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            sprintf(elmIndexStr, "^index_%d", (int)elmIndex++);
12979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            itemIdent = String16(elmIndexStr);
12989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } else if (curType == plurals16) {
12999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            ssize_t itemIdentIdx = block.indexOfAttribute(NULL, "quantity");
13009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            if (itemIdentIdx >= 0) {
13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                String16 quantity16(block.getAttributeStringValue(itemIdentIdx, &len));
13029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                if (quantity16 == other16) {
13039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    itemIdent = quantityOther16;
13049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                }
13059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                else if (quantity16 == zero16) {
13069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    itemIdent = quantityZero16;
13079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                }
13089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                else if (quantity16 == one16) {
13099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    itemIdent = quantityOne16;
13109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                }
13119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                else if (quantity16 == two16) {
13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    itemIdent = quantityTwo16;
13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                }
13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                else if (quantity16 == few16) {
13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    itemIdent = quantityFew16;
13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                }
13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                else if (quantity16 == many16) {
13189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    itemIdent = quantityMany16;
13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                }
13209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                else {
13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
13229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                            "Illegal 'quantity' attribute is <item> inside <plurals>\n");
13239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    hasErrors = localHasErrors = true;
13249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                }
13259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            } else {
13269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
13279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        "A 'quantity' attribute is required for <item> inside <plurals>\n");
13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                hasErrors = localHasErrors = true;
13299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
13309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } else {
13319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            ssize_t itemIdentIdx = block.indexOfAttribute(NULL, "name");
13329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            if (itemIdentIdx >= 0) {
13339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                itemIdent = String16(block.getAttributeStringValue(itemIdentIdx, &len));
13349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            } else {
13359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        "A 'name' attribute is required for <item>\n");
13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                hasErrors = localHasErrors = true;
13389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
13399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
13409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ResXMLParser::ResXMLPosition parserPosition;
13429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        block.getPosition(&parserPosition);
13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        err = parseAndAddBag(bundle, in, &block, curParams, myPackage, curType,
13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                ident, parentIdent, itemIdent, curFormat,
13469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                false, overwrite, outTable);
13479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (err == NO_ERROR) {
13489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            if (curIsPseudolocalizable && localeIsDefined(curParams)
13499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    && bundle->getPseudolocalize()) {
13509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                // pseudolocalize here
13519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 1
13529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                block.setPosition(parserPosition);
13539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                err = parseAndAddBag(bundle, in, &block, pseudoParams, myPackage,
13549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        curType, ident, parentIdent, itemIdent, curFormat, true,
13559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        overwrite, outTable);
13569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
13579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
13589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
13599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (err != NO_ERROR) {
13609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            hasErrors = localHasErrors = true;
13619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
13629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else if (code == ResXMLTree::END_TAG) {
13639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (strcmp16(block.getElementName(&len), curTag->string()) != 0) {
13649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
13659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    "Found tag </%s> where </%s> is expected\n",
13669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    String8(block.getElementName(&len)).string(),
13679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    String8(*curTag).string());
13689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            return UNKNOWN_ERROR;
13699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
13709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        break;
13719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
13729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
13739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
13749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ResXMLParser::ResXMLPosition parserPosition;
13759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                block.getPosition(&parserPosition);
13769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                err = parseAndAddEntry(bundle, in, &block, curParams, myPackage, curType, ident,
13789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        *curTag, curIsStyled, curFormat, false, overwrite, outTable);
13799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (err < NO_ERROR) { // Why err < NO_ERROR instead of err != NO_ERROR?
13819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hasErrors = localHasErrors = true;
13829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
13839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                else if (err == NO_ERROR) {
13849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (curIsPseudolocalizable && localeIsDefined(curParams)
13859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            && bundle->getPseudolocalize()) {
13869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // pseudolocalize here
13879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        block.setPosition(parserPosition);
13889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        err = parseAndAddEntry(bundle, in, &block, pseudoParams, myPackage, curType,
138932c2c902200e894c6e887218a337334d81013be5Robert Greenwalt                                ident, *curTag, curIsStyled, curFormat, true, overwrite, outTable);
13909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (err != NO_ERROR) {
13919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            hasErrors = localHasErrors = true;
13929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
13939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
13949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
13959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
13969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 0
13989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (comment.size() > 0) {
13999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                printf("Comment for @%s:%s/%s: %s\n", String8(myPackage).string(),
14009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                       String8(curType).string(), String8(ident).string(),
14019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                       String8(comment).string());
14029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
14039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
14049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!localHasErrors) {
14059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                outTable->appendComment(myPackage, curType, ident, comment, false);
14069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
14079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        else if (code == ResXMLTree::END_TAG) {
14099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (strcmp16(block.getElementName(&len), resources16.string()) != 0) {
14109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
14119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        "Unexpected end tag %s\n", String8(block.getElementName(&len)).string());
14129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return UNKNOWN_ERROR;
14139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
14149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        else if (code == ResXMLTree::START_NAMESPACE || code == ResXMLTree::END_NAMESPACE) {
14169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        else if (code == ResXMLTree::TEXT) {
14189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (isWhitespace(block.getText(&len))) {
14199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
14209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
14219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
14229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    "Found text \"%s\" where item tag is expected\n",
14239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(block.getText(&len)).string());
14249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return UNKNOWN_ERROR;
14259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
14299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
14309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResourceTable::ResourceTable(Bundle* bundle, const String16& assetsPackage)
14329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    : mAssetsPackage(assetsPackage), mNextPackageId(1), mHaveAppPackage(false),
14339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      mIsAppPackage(!bundle->getExtending()),
14349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      mNumLocal(0),
14359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      mBundle(bundle)
14369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
14379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
14389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::addIncludedResources(Bundle* bundle, const sp<AaptAssets>& assets)
14409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
14419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = assets->buildIncludedResources(bundle);
14429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != NO_ERROR) {
14439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return err;
14449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // For future reference to included resources.
14479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mAssets = assets;
14489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const ResTable& incl = assets->getIncludedResources();
14509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Retrieve all the packages.
14529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t N = incl.getBasePackageCount();
14539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (size_t phase=0; phase<2; phase++) {
14549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (size_t i=0; i<N; i++) {
14559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String16 name(incl.getBasePackageName(i));
14569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            uint32_t id = incl.getBasePackageId(i);
14579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // First time through: only add base packages (id
14589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // is not 0); second time through add the other
14599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // packages.
14609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (phase != 0) {
14619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (id != 0) {
14629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Skip base packages -- already one.
14639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    id = 0;
14649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Assign a dynamic id.
14669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    id = mNextPackageId;
14679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
14689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (id != 0) {
14699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (id == 127) {
14709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (mHaveAppPackage) {
1471a96cbb435d7b2197ab2b61fd98d14cbd6e0c5c3dDianne Hackborn                        fprintf(stderr, "Included resources have two application packages!\n");
14729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        return UNKNOWN_ERROR;
14739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
14749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mHaveAppPackage = true;
14759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
14769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mNextPackageId > id) {
14779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    fprintf(stderr, "Included base package ID %d already in use!\n", id);
14789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return UNKNOWN_ERROR;
14799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
14809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
14819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (id != 0) {
14829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                NOISY(printf("Including package %s with ID=%d\n",
14839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             String8(name).string(), id));
14849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sp<Package> p = new Package(name, id);
14859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mPackages.add(name, p);
14869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mOrderedPackages.add(p);
14879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (id >= mNextPackageId) {
14899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mNextPackageId = id+1;
14909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
14919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
14929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Every resource table always has one first entry, the bag attributes.
14969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const SourcePos unknown(String8("????"), 0);
14979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Type> attr = getType(mAssetsPackage, String16("attr"), unknown);
14989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
15009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
15019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::addPublic(const SourcePos& sourcePos,
15039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const String16& package,
15049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const String16& type,
15059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const String16& name,
15069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const uint32_t ident)
15079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
15089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t rid = mAssets->getIncludedResources()
15099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        .identifierForName(name.string(), name.size(),
15109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           type.string(), type.size(),
15119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           package.string(), package.size());
15129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (rid != 0) {
15139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sourcePos.error("Error declaring public resource %s/%s for included package %s\n",
15149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String8(type).string(), String8(name).string(),
15159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String8(package).string());
15169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
15179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Type> t = getType(package, type, sourcePos);
15209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (t == NULL) {
15219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
15229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return t->addPublic(sourcePos, name, ident);
15249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
15259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::addEntry(const SourcePos& sourcePos,
15279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16& package,
15289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16& type,
15299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16& name,
15309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16& value,
15319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const Vector<StringPool::entry_style_span>* style,
15329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const ResTable_config* params,
15339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const bool doSetIndex,
15349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const int32_t format,
15359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const bool overwrite)
15369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
15379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Check for adding entries in other packages...  for now we do
15389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // nothing.  We need to do the right thing here to support skinning.
15399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t rid = mAssets->getIncludedResources()
15409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        .identifierForName(name.string(), name.size(),
15419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           type.string(), type.size(),
15429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           package.string(), package.size());
15439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (rid != 0) {
15449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NO_ERROR;
15459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 0
15489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (name == String16("left")) {
15499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        printf("Adding entry left: file=%s, line=%d, type=%s, value=%s\n",
15509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project               sourcePos.file.string(), sourcePos.line, String8(type).string(),
15519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project               String8(value).string());
15529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
1554f878e2d80c3a0afefe3b018d232df6066379e1d5Robert Greenwalt
1555f878e2d80c3a0afefe3b018d232df6066379e1d5Robert Greenwalt    sp<Entry> e = getEntry(package, type, name, sourcePos, overwrite,
1556f878e2d80c3a0afefe3b018d232df6066379e1d5Robert Greenwalt                           params, doSetIndex);
15579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (e == NULL) {
15589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
15599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = e->setItem(sourcePos, value, style, format, overwrite);
15619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err == NO_ERROR) {
15629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mNumLocal++;
15639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err;
15659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
15669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::startBag(const SourcePos& sourcePos,
15689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16& package,
15699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16& type,
15709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16& name,
15719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16& bagParent,
15729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const ResTable_config* params,
15731aa8170e6a448afad86e5d62927d3b8ca4cd9707Robert Greenwalt                                 bool overlay,
15749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 bool replace, bool isId)
15759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
15764b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt    status_t result = NO_ERROR;
15774b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt
15789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Check for adding entries in other packages...  for now we do
15799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // nothing.  We need to do the right thing here to support skinning.
15809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t rid = mAssets->getIncludedResources()
15819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    .identifierForName(name.string(), name.size(),
15829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                       type.string(), type.size(),
15839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                       package.string(), package.size());
15849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (rid != 0) {
15859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NO_ERROR;
15869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 0
15899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (name == String16("left")) {
15909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        printf("Adding bag left: file=%s, line=%d, type=%s\n",
15919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project               sourcePos.file.striing(), sourcePos.line, String8(type).string());
15929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
15941aa8170e6a448afad86e5d62927d3b8ca4cd9707Robert Greenwalt    if (overlay && !hasBagOrEntry(package, type, name)) {
159558c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn        bool canAdd = false;
159658c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn        sp<Package> p = mPackages.valueFor(package);
159758c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn        if (p != NULL) {
159858c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn            sp<Type> t = p->getTypes().valueFor(type);
159958c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn            if (t != NULL) {
160058c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                if (t->getCanAddEntries().indexOf(name) >= 0) {
160158c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                    canAdd = true;
160258c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                }
160358c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn            }
160458c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn        }
160558c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn        if (!canAdd) {
160658c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn            sourcePos.error("Resource does not already exist in overlay at '%s'; use <add-resource> to add.\n",
160758c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                            String8(name).string());
160858c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn            return UNKNOWN_ERROR;
160958c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn        }
16101aa8170e6a448afad86e5d62927d3b8ca4cd9707Robert Greenwalt    }
1611f878e2d80c3a0afefe3b018d232df6066379e1d5Robert Greenwalt    sp<Entry> e = getEntry(package, type, name, sourcePos, overlay, params);
16129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (e == NULL) {
16139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
16149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // If a parent is explicitly specified, set it.
16179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (bagParent.size() > 0) {
16189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String16 curPar = e->getParent();
16199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (curPar.size() > 0 && curPar != bagParent) {
16209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sourcePos.error("Conflicting parents specified, was '%s', now '%s'\n",
16219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            String8(e->getParent()).string(),
16229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            String8(bagParent).string());
16239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return UNKNOWN_ERROR;
16249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        e->setParent(bagParent);
16269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16274b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt
16284b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt    if ((result = e->makeItABag(sourcePos)) != NO_ERROR) {
16294b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt        return result;
16304b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt    }
16319411a39866b749ad0a47f15083f311847eb79178Robert Greenwalt
16321aa8170e6a448afad86e5d62927d3b8ca4cd9707Robert Greenwalt    if (overlay && replace) {
16339411a39866b749ad0a47f15083f311847eb79178Robert Greenwalt        return e->emptyBag(sourcePos);
16349411a39866b749ad0a47f15083f311847eb79178Robert Greenwalt    }
16359411a39866b749ad0a47f15083f311847eb79178Robert Greenwalt    return result;
16369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
16379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::addBag(const SourcePos& sourcePos,
16399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                               const String16& package,
16409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                               const String16& type,
16419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                               const String16& name,
16429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                               const String16& bagParent,
16439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                               const String16& bagKey,
16449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                               const String16& value,
16459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                               const Vector<StringPool::entry_style_span>* style,
16469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                               const ResTable_config* params,
16479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                               bool replace, bool isId, const int32_t format)
16489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
16499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Check for adding entries in other packages...  for now we do
16509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // nothing.  We need to do the right thing here to support skinning.
16519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t rid = mAssets->getIncludedResources()
16529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        .identifierForName(name.string(), name.size(),
16539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           type.string(), type.size(),
16549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           package.string(), package.size());
16559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (rid != 0) {
16569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NO_ERROR;
16579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 0
16609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (name == String16("left")) {
16619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        printf("Adding bag left: file=%s, line=%d, type=%s\n",
16629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project               sourcePos.file.striing(), sourcePos.line, String8(type).string());
16639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
1665f878e2d80c3a0afefe3b018d232df6066379e1d5Robert Greenwalt    sp<Entry> e = getEntry(package, type, name, sourcePos, replace, params);
16669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (e == NULL) {
16679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
16689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // If a parent is explicitly specified, set it.
16719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (bagParent.size() > 0) {
16729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String16 curPar = e->getParent();
16739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (curPar.size() > 0 && curPar != bagParent) {
16749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sourcePos.error("Conflicting parents specified, was '%s', now '%s'\n",
16759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(e->getParent()).string(),
16769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(bagParent).string());
16779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return UNKNOWN_ERROR;
16789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        e->setParent(bagParent);
16809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const bool first = e->getBag().indexOfKey(bagKey) < 0;
16839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = e->addToBag(sourcePos, bagKey, value, style, replace, isId, format);
16849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err == NO_ERROR && first) {
16859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mNumLocal++;
16869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err;
16889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
16899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::hasBagOrEntry(const String16& package,
16919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const String16& type,
16929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const String16& name) const
16939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
16949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // First look for this in the included resources...
16959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t rid = mAssets->getIncludedResources()
16969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        .identifierForName(name.string(), name.size(),
16979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           type.string(), type.size(),
16989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           package.string(), package.size());
16999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (rid != 0) {
17009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
17019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Package> p = mPackages.valueFor(package);
17049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (p != NULL) {
17059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<Type> t = p->getTypes().valueFor(type);
17069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (t != NULL) {
17079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<ConfigList> c =  t->getConfigs().valueFor(name);
17089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (c != NULL) return true;
17099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return false;
17139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
17149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::hasBagOrEntry(const String16& ref,
17169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const String16* defType,
17179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const String16* defPackage)
17189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
17199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String16 package, type, name;
17209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!ResTable::expandResourceRef(ref.string(), ref.size(), &package, &type, &name,
17219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                defType, defPackage ? defPackage:&mAssetsPackage, NULL)) {
17229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
17239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return hasBagOrEntry(package, type, name);
17259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
17269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::appendComment(const String16& package,
17289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const String16& type,
17299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const String16& name,
17309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const String16& comment,
17319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  bool onlyIfEmpty)
17329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
17339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (comment.size() <= 0) {
17349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
17359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Package> p = mPackages.valueFor(package);
17389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (p != NULL) {
17399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<Type> t = p->getTypes().valueFor(type);
17409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (t != NULL) {
17419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<ConfigList> c =  t->getConfigs().valueFor(name);
17429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (c != NULL) {
17439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                c->appendComment(comment, onlyIfEmpty);
17449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
17459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
17469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return false;
17499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
17509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::appendTypeComment(const String16& package,
17529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                      const String16& type,
17539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                      const String16& name,
17549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                      const String16& comment)
17559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
17569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (comment.size() <= 0) {
17579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
17589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Package> p = mPackages.valueFor(package);
17619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (p != NULL) {
17629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<Type> t = p->getTypes().valueFor(type);
17639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (t != NULL) {
17649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<ConfigList> c =  t->getConfigs().valueFor(name);
17659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (c != NULL) {
17669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                c->appendTypeComment(comment);
17679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
17689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
17699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return false;
17729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
17739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
177458c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackbornvoid ResourceTable::canAddEntry(const SourcePos& pos,
177558c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn        const String16& package, const String16& type, const String16& name)
177658c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn{
177758c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn    sp<Type> t = getType(package, type, pos);
177858c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn    if (t != NULL) {
177958c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn        t->canAddEntry(name);
178058c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn    }
178158c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn}
178258c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn
17839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsize_t ResourceTable::size() const {
17849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return mPackages.size();
17859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
17869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsize_t ResourceTable::numLocalResources() const {
17889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return mNumLocal;
17899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
17909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::hasResources() const {
17929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return mNumLocal > 0;
17939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
17949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsp<AaptFile> ResourceTable::flatten(Bundle* bundle)
17969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
17979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<AaptFile> data = new AaptFile(String8(), AaptGroupEntry(), String8());
17989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = flatten(bundle, data);
17999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err == NO_ERROR ? data : NULL;
18009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
18019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectinline uint32_t ResourceTable::getResId(const sp<Package>& p,
18039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        const sp<Type>& t,
18049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        uint32_t nameId)
18059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
18069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return makeResId(p->getAssignedId(), t->getIndex(), nameId);
18079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
18089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t ResourceTable::getResId(const String16& package,
18109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16& type,
18119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16& name,
18129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 bool onlyPublic) const
18139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
18149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Package> p = mPackages.valueFor(package);
18159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (p == NULL) return 0;
18169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // First look for this in the included resources...
18189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t specFlags = 0;
18199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t rid = mAssets->getIncludedResources()
18209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        .identifierForName(name.string(), name.size(),
18219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           type.string(), type.size(),
18229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           package.string(), package.size(),
18239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           &specFlags);
18249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (rid != 0) {
18259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (onlyPublic) {
18269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if ((specFlags & ResTable_typeSpec::SPEC_PUBLIC) == 0) {
18279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return 0;
18289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
18299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
18309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (Res_INTERNALID(rid)) {
18329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return rid;
18339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
18349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return Res_MAKEID(p->getAssignedId()-1,
18359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                          Res_GETTYPE(rid),
18369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                          Res_GETENTRY(rid));
18379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Type> t = p->getTypes().valueFor(type);
18409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (t == NULL) return 0;
18419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<ConfigList> c =  t->getConfigs().valueFor(name);
18429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (c == NULL) return 0;
18439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t ei = c->getEntryIndex();
18449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (ei < 0) return 0;
18459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return getResId(p, t, ei);
18469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
18479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t ResourceTable::getResId(const String16& ref,
18499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16* defType,
18509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16* defPackage,
18519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const char** outErrorMsg,
18529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 bool onlyPublic) const
18539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
18549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String16 package, type, name;
18559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!ResTable::expandResourceRef(
18569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ref.string(), ref.size(), &package, &type, &name,
18579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        defType, defPackage ? defPackage:&mAssetsPackage,
18589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        outErrorMsg)) {
18599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NOISY(printf("Expanding resource: ref=%s\n",
18609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                     String8(ref).string()));
18619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NOISY(printf("Expanding resource: defType=%s\n",
18629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                     defType ? String8(*defType).string() : "NULL"));
18639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NOISY(printf("Expanding resource: defPackage=%s\n",
18649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                     defPackage ? String8(*defPackage).string() : "NULL"));
18659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NOISY(printf("Expanding resource: ref=%s\n", String8(ref).string()));
18669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NOISY(printf("Expanded resource: p=%s, t=%s, n=%s, res=0\n",
18679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                     String8(package).string(), String8(type).string(),
18689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                     String8(name).string()));
18699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 0;
18709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t res = getResId(package, type, name, onlyPublic);
18729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    NOISY(printf("Expanded resource: p=%s, t=%s, n=%s, res=%d\n",
18739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 String8(package).string(), String8(type).string(),
18749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 String8(name).string(), res));
18759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (res == 0) {
18769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (outErrorMsg)
18779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            *outErrorMsg = "No resource found that matches the given name";
18789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return res;
18809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
18819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::isValidResourceName(const String16& s)
18839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
18849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char16_t* p = s.string();
18859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool first = true;
18869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (*p) {
18879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((*p >= 'a' && *p <= 'z')
18889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            || (*p >= 'A' && *p <= 'Z')
18899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            || *p == '_'
18909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            || (!first && *p >= '0' && *p <= '9')) {
18919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            first = false;
18929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p++;
18939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            continue;
18949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
18959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
18969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return true;
18989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
18999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::stringToValue(Res_value* outValue, StringPool* pool,
19019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const String16& str,
19029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  bool preserveSpaces, bool coerceType,
19039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  uint32_t attrID,
19049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const Vector<StringPool::entry_style_span>* style,
19059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  String16* outStr, void* accessorCookie,
19069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  uint32_t attrType)
19079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
19089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String16 finalStr;
19099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool res = true;
19119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (style == NULL || style->size() == 0) {
19129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Text is not styled so it can be any type...  let's figure it out.
19139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        res = mAssets->getIncludedResources()
19149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            .stringToValue(outValue, &finalStr, str.string(), str.size(), preserveSpaces,
19159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            coerceType, attrID, NULL, &mAssetsPackage, this,
19169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           accessorCookie, attrType);
19179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
19189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Styled text can only be a string, and while collecting the style
19199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // information we have already processed that string!
19209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        outValue->size = sizeof(Res_value);
19219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        outValue->res0 = 0;
19229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        outValue->dataType = outValue->TYPE_STRING;
19239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        outValue->data = 0;
19249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        finalStr = str;
19259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!res) {
19289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
19299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (outValue->dataType == outValue->TYPE_STRING) {
19329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Should do better merging styles.
19339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (pool) {
19349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (style != NULL && style->size() > 0) {
19359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                outValue->data = pool->add(finalStr, *style);
19369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
19379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                outValue->data = pool->add(finalStr, true);
19389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
19399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
19409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Caller will fill this in later.
19419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            outValue->data = 0;
19429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (outStr) {
19459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            *outStr = finalStr;
19469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return true;
19519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
19529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t ResourceTable::getCustomResource(
19549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16& package, const String16& type, const String16& name) const
19559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
19569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //printf("getCustomResource: %s %s %s\n", String8(package).string(),
19579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //       String8(type).string(), String8(name).string());
19589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Package> p = mPackages.valueFor(package);
19599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (p == NULL) return 0;
19609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Type> t = p->getTypes().valueFor(type);
19619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (t == NULL) return 0;
19629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<ConfigList> c =  t->getConfigs().valueFor(name);
19639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (c == NULL) return 0;
19649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t ei = c->getEntryIndex();
19659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (ei < 0) return 0;
19669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return getResId(p, t, ei);
19679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
19689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t ResourceTable::getCustomResourceWithCreation(
19709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const String16& package, const String16& type, const String16& name,
19719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const bool createIfNotFound)
19729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
19739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t resId = getCustomResource(package, type, name);
19749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (resId != 0 || !createIfNotFound) {
19759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return resId;
19769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String16 value("false");
19789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t status = addEntry(mCurrentXmlPos, package, type, name, value, NULL, NULL, true);
19809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (status == NO_ERROR) {
19819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        resId = getResId(package, type, name);
19829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return resId;
19839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return 0;
19859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
19869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t ResourceTable::getRemappedPackage(uint32_t origPackage) const
19889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
19899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return origPackage;
19909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
19919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::getAttributeType(uint32_t attrID, uint32_t* outType)
19939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
19949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //printf("getAttributeType #%08x\n", attrID);
19959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Res_value value;
19969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (getItemValue(attrID, ResTable_map::ATTR_TYPE, &value)) {
19979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //printf("getAttributeType #%08x (%s): #%08x\n", attrID,
19989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //       String8(getEntry(attrID)->getName()).string(), value.data);
19999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        *outType = value.data;
20009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
20019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return false;
20039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
20049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::getAttributeMin(uint32_t attrID, uint32_t* outMin)
20069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
20079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //printf("getAttributeMin #%08x\n", attrID);
20089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Res_value value;
20099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (getItemValue(attrID, ResTable_map::ATTR_MIN, &value)) {
20109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        *outMin = value.data;
20119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
20129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return false;
20149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
20159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::getAttributeMax(uint32_t attrID, uint32_t* outMax)
20179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
20189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //printf("getAttributeMax #%08x\n", attrID);
20199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Res_value value;
20209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (getItemValue(attrID, ResTable_map::ATTR_MAX, &value)) {
20219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        *outMax = value.data;
20229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
20239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return false;
20259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
20269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t ResourceTable::getAttributeL10N(uint32_t attrID)
20289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
20299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //printf("getAttributeL10N #%08x\n", attrID);
20309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Res_value value;
20319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (getItemValue(attrID, ResTable_map::ATTR_L10N, &value)) {
20329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return value.data;
20339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return ResTable_map::L10N_NOT_REQUIRED;
20359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
20369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::getLocalizationSetting()
20389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
20399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return mBundle->getRequireLocalization();
20409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
20419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResourceTable::reportError(void* accessorCookie, const char* fmt, ...)
20439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
20449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (accessorCookie != NULL && fmt != NULL) {
20459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        AccessorCookie* ac = (AccessorCookie*)accessorCookie;
20469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int retval=0;
20479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        char buf[1024];
20489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        va_list ap;
20499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        va_start(ap, fmt);
20509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        retval = vsnprintf(buf, sizeof(buf), fmt, ap);
20519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        va_end(ap);
20529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ac->sourcePos.error("Error: %s (at '%s' with value '%s').\n",
20539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            buf, ac->attr.string(), ac->value.string());
20549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
20569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::getAttributeKeys(
20589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t attrID, Vector<String16>* outKeys)
20599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
20609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<const Entry> e = getEntry(attrID);
20619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (e != NULL) {
20629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t N = e->getBag().size();
20639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (size_t i=0; i<N; i++) {
20649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const String16& key = e->getBag().keyAt(i);
20659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (key.size() > 0 && key.string()[0] != '^') {
20669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                outKeys->add(key);
20679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
20689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
20699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
20709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return false;
20729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
20739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::getAttributeEnum(
20759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t attrID, const char16_t* name, size_t nameLen,
20769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Res_value* outValue)
20779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
20789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //printf("getAttributeEnum #%08x %s\n", attrID, String8(name, nameLen).string());
20799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String16 nameStr(name, nameLen);
20809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<const Entry> e = getEntry(attrID);
20819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (e != NULL) {
20829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t N = e->getBag().size();
20839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (size_t i=0; i<N; i++) {
20849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //printf("Comparing %s to %s\n", String8(name, nameLen).string(),
20859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //       String8(e->getBag().keyAt(i)).string());
20869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (e->getBag().keyAt(i) == nameStr) {
20879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return getItemValue(attrID, e->getBag().valueAt(i).bagKeyId, outValue);
20889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
20899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
20909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return false;
20929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
20939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::getAttributeFlags(
20959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t attrID, const char16_t* name, size_t nameLen,
20969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Res_value* outValue)
20979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
20989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    outValue->dataType = Res_value::TYPE_INT_HEX;
20999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    outValue->data = 0;
21009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //printf("getAttributeFlags #%08x %s\n", attrID, String8(name, nameLen).string());
21029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String16 nameStr(name, nameLen);
21039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<const Entry> e = getEntry(attrID);
21049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (e != NULL) {
21059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t N = e->getBag().size();
21069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const char16_t* end = name + nameLen;
21089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const char16_t* pos = name;
21099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bool failed = false;
21109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (pos < end && !failed) {
21119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const char16_t* start = pos;
21129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            end++;
21139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            while (pos < end && *pos != '|') {
21149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pos++;
21159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
21169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String16 nameStr(start, pos-start);
21189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            size_t i;
21199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (i=0; i<N; i++) {
21209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                //printf("Comparing \"%s\" to \"%s\"\n", String8(nameStr).string(),
21219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                //       String8(e->getBag().keyAt(i)).string());
21229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (e->getBag().keyAt(i) == nameStr) {
21239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Res_value val;
21249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    bool got = getItemValue(attrID, e->getBag().valueAt(i).bagKeyId, &val);
21259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (!got) {
21269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        return false;
21279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
21289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    //printf("Got value: 0x%08x\n", val.data);
21299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    outValue->data |= val.data;
21309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
21319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
21329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
21339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (i >= N) {
21359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Didn't find this flag identifier.
21369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return false;
21379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
21389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (pos < end) {
21399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pos++;
21409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
21419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
21429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
21449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return false;
21469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
21479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::assignResourceIds()
21499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
21509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t N = mOrderedPackages.size();
21519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t pi;
21529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t firstError = NO_ERROR;
21539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // First generate all bag attributes and assign indices.
21559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (pi=0; pi<N; pi++) {
21569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<Package> p = mOrderedPackages.itemAt(pi);
21579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (p == NULL || p->getTypes().size() == 0) {
21589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Empty, skip!
21599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            continue;
21609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
21619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        status_t err = p->applyPublicTypeOrder();
21639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != NO_ERROR && firstError == NO_ERROR) {
21649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            firstError = err;
21659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
21669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Generate attributes...
21689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t N = p->getOrderedTypes().size();
21699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        size_t ti;
21709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (ti=0; ti<N; ti++) {
21719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<Type> t = p->getOrderedTypes().itemAt(ti);
21729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (t == NULL) {
21739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
21749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
21759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const size_t N = t->getOrderedConfigs().size();
21769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (size_t ci=0; ci<N; ci++) {
21779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);
21789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (c == NULL) {
21799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
21809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
21819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                const size_t N = c->getEntries().size();
21829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (size_t ei=0; ei<N; ei++) {
21839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sp<Entry> e = c->getEntries().valueAt(ei);
21849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (e == NULL) {
21859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        continue;
21869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
21879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    status_t err = e->generateAttributes(this, p->getName());
21889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (err != NO_ERROR && firstError == NO_ERROR) {
21899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        firstError = err;
21909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
21919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
21929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
21939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
21949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const SourcePos unknown(String8("????"), 0);
21969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<Type> attr = p->getType(String16("attr"), unknown);
21979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Assign indices...
21999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (ti=0; ti<N; ti++) {
22009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<Type> t = p->getOrderedTypes().itemAt(ti);
22019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (t == NULL) {
22029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
22039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
22049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            err = t->applyPublicEntryOrder();
22059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (err != NO_ERROR && firstError == NO_ERROR) {
22069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                firstError = err;
22079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
22089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const size_t N = t->getOrderedConfigs().size();
22109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            t->setIndex(ti+1);
22119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOG_ALWAYS_FATAL_IF(ti == 0 && attr != t,
22139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                "First type is not attr!");
22149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (size_t ei=0; ei<N; ei++) {
22169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ei);
22179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (c == NULL) {
22189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
22199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
22209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                c->setEntryIndex(ei);
22219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
22229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
22239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Assign resource IDs to keys in bags...
22259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (ti=0; ti<N; ti++) {
22269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<Type> t = p->getOrderedTypes().itemAt(ti);
22279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (t == NULL) {
22289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
22299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
22309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const size_t N = t->getOrderedConfigs().size();
22319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (size_t ci=0; ci<N; ci++) {
22329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);
22339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                //printf("Ordered config #%d: %p\n", ci, c.get());
22349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                const size_t N = c->getEntries().size();
22359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (size_t ei=0; ei<N; ei++) {
22369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sp<Entry> e = c->getEntries().valueAt(ei);
22379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (e == NULL) {
22389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        continue;
22399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
22409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    status_t err = e->assignResourceIds(this, p->getName());
22419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (err != NO_ERROR && firstError == NO_ERROR) {
22429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        firstError = err;
22439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
22449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
22459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
22469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
22479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return firstError;
22499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
22509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::addSymbols(const sp<AaptSymbols>& outSymbols) {
22529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t N = mOrderedPackages.size();
22539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t pi;
22549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (pi=0; pi<N; pi++) {
22569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<Package> p = mOrderedPackages.itemAt(pi);
22579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (p->getTypes().size() == 0) {
22589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Empty, skip!
22599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            continue;
22609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
22619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t N = p->getOrderedTypes().size();
22639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        size_t ti;
22649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (ti=0; ti<N; ti++) {
22669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<Type> t = p->getOrderedTypes().itemAt(ti);
22679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (t == NULL) {
22689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
22699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
22709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const size_t N = t->getOrderedConfigs().size();
22719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<AaptSymbols> typeSymbols;
22729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            typeSymbols = outSymbols->addNestedSymbol(String8(t->getName()), t->getPos());
22739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (size_t ci=0; ci<N; ci++) {
22749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);
22759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (c == NULL) {
22769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
22779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
22789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                uint32_t rid = getResId(p, t, ci);
22799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (rid == 0) {
22809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return UNKNOWN_ERROR;
22819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
22829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (Res_GETPACKAGE(rid) == (size_t)(p->getAssignedId()-1)) {
22839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    typeSymbols->addSymbol(String8(c->getName()), rid, c->getPos());
22849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String16 comment(c->getComment());
22869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    typeSymbols->appendComment(String8(c->getName()), comment, c->getPos());
22879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    //printf("Type symbol %s comment: %s\n", String8(e->getName()).string(),
22889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    //     String8(comment).string());
22899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    comment = c->getTypeComment();
22909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    typeSymbols->appendTypeComment(String8(c->getName()), comment);
22919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
22929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 0
22939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    printf("**** NO MATCH: 0x%08x vs 0x%08x\n",
22949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           Res_GETPACKAGE(rid), p->getAssignedId());
22959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
22969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
22979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
22989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
22999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
23009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
23019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
23029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid
23059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResourceTable::addLocalization(const String16& name, const String8& locale)
23069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
23079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mLocalizations[name].insert(locale);
23089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
23099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*!
23129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Flag various sorts of localization problems.  '+' indicates checks already implemented;
23139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * '-' indicates checks that will be implemented in the future.
23149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
23159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * + A localized string for which no default-locale version exists => warning
23169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * + A string for which no version in an explicitly-requested locale exists => warning
23179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * + A localized translation of an translateable="false" string => warning
23189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * - A localized string not provided in every locale used by the table
23199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
23209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t
23219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResourceTable::validateLocalizations(void)
23229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
23239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = NO_ERROR;
23249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String8 defaultLocale;
23259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // For all strings...
23279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (map<String16, set<String8> >::iterator nameIter = mLocalizations.begin();
23289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         nameIter != mLocalizations.end();
23299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         nameIter++) {
23309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const set<String8>& configSet = nameIter->second;   // naming convenience
23319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Look for strings with no default localization
23339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (configSet.count(defaultLocale) == 0) {
23349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stdout, "aapt: warning: string '%s' has no default translation in %s; found:",
23359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(nameIter->first).string(), mBundle->getResourceSourceDirs()[0]);
23369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (set<String8>::iterator locales = configSet.begin();
23379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 locales != configSet.end();
23389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 locales++) {
23399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                fprintf(stdout, " %s", (*locales).string());
23409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
23419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stdout, "\n");
23429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // !!! TODO: throw an error here in some circumstances
23439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
23449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Check that all requested localizations are present for this string
23469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mBundle->getConfigurations() != NULL && mBundle->getRequireLocalization()) {
23479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const char* allConfigs = mBundle->getConfigurations();
23489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const char* start = allConfigs;
23499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const char* comma;
23509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            do {
23529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String8 config;
23539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                comma = strchr(start, ',');
23549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (comma != NULL) {
23559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    config.setTo(start, comma - start);
23569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    start = comma + 1;
23579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
23589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    config.setTo(start);
23599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
23609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // don't bother with the pseudolocale "zz_ZZ"
23629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (config != "zz_ZZ") {
23639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (configSet.find(config) == configSet.end()) {
23649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // okay, no specific localization found.  it's possible that we are
23659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // requiring a specific regional localization [e.g. de_DE] but there is an
23669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // available string in the generic language localization [e.g. de];
23679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // consider that string to have fulfilled the localization requirement.
23689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String8 region(config.string(), 2);
23699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (configSet.find(region) == configSet.end()) {
23709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            if (configSet.count(defaultLocale) == 0) {
2371c87d25215c842cea370c6a86ce67585fa8da4900Eric Fischer                                fprintf(stdout, "aapt: warning: "
23729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        "*** string '%s' has no default or required localization "
23739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        "for '%s' in %s\n",
23749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        String8(nameIter->first).string(),
23759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        config.string(),
23769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        mBundle->getResourceSourceDirs()[0]);
23779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
23789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
23799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
23809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
23819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project           } while (comma != NULL);
23829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
23839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
23849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err;
23869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
23879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t
23909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResourceFilter::parse(const char* arg)
23919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
23929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (arg == NULL) {
23939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 0;
23949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
23959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char* p = arg;
23979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char* q;
23989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (true) {
24009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        q = strchr(p, ',');
24019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (q == NULL) {
24029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            q = p + strlen(p);
24039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
24049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String8 part(p, q-p);
24069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (part == "zz_ZZ") {
24089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mContainsPseudo = true;
24099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
24109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int axis;
24119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        uint32_t value;
24129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (AaptGroupEntry::parseNamePart(part, &axis, &value)) {
24139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "Invalid configuration: %s\n", arg);
24149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "                       ");
24159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i=0; i<p-arg; i++) {
24169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                fprintf(stderr, " ");
24179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
24189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i=0; i<q-p; i++) {
24199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                fprintf(stderr, "^");
24209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
24219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "\n");
24229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 1;
24239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
24249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ssize_t index = mData.indexOfKey(axis);
24269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (index < 0) {
24279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mData.add(axis, SortedVector<uint32_t>());
24289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
24299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SortedVector<uint32_t>& sv = mData.editValueFor(axis);
24309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sv.add(value);
24319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // if it's a locale with a region, also match an unmodified locale of the
24329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // same language
24339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (axis == AXIS_LANGUAGE) {
24349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (value & 0xffff0000) {
24359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sv.add(value & 0x0000ffff);
24369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
24379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
24389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p = q;
24399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!*p) break;
24409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p++;
24419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
24429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
24449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
24459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool
24479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResourceFilter::match(int axis, uint32_t value)
24489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
24499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (value == 0) {
24509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // they didn't specify anything so take everything
24519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
24529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
24539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ssize_t index = mData.indexOfKey(axis);
24549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (index < 0) {
24559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // we didn't request anything on this axis so take everything
24569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
24579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
24589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const SortedVector<uint32_t>& sv = mData.valueAt(index);
24599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return sv.indexOf(value) >= 0;
24609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
24619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool
24639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResourceFilter::match(const ResTable_config& config)
24649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
24659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (config.locale) {
24669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        uint32_t locale = (config.country[1] << 24) | (config.country[0] << 16)
24679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                | (config.language[1] << 8) | (config.language[0]);
24689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!match(AXIS_LANGUAGE, locale)) {
24699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
24709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
24719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
24729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!match(AXIS_ORIENTATION, config.orientation)) {
24739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
24749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
24759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!match(AXIS_DENSITY, config.density)) {
24769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
24779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
24789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!match(AXIS_TOUCHSCREEN, config.touchscreen)) {
24799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
24809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
24819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!match(AXIS_KEYSHIDDEN, config.inputFlags)) {
24829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
24839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
24849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!match(AXIS_KEYBOARD, config.keyboard)) {
24859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
24869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
24879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!match(AXIS_NAVIGATION, config.navigation)) {
24889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
24899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
24909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!match(AXIS_SCREENSIZE, config.screenSize)) {
24919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
24929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
24939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!match(AXIS_VERSION, config.version)) {
24949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
24959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
24969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return true;
24979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
24989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest)
25009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
25019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ResourceFilter filter;
25029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = filter.parse(bundle->getConfigurations());
25039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != NO_ERROR) {
25049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return err;
25059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
25069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t N = mOrderedPackages.size();
25089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t pi;
25099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Iterate through all data, collecting all values (strings,
25119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // references, etc).
251219138468caf7050d482dc15f35a344eab11bb756Kenny Root    StringPool valueStrings = StringPool(false, bundle->getUTF8());
25139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (pi=0; pi<N; pi++) {
25149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<Package> p = mOrderedPackages.itemAt(pi);
25159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (p->getTypes().size() == 0) {
25169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Empty, skip!
25179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            continue;
25189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
25199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
252019138468caf7050d482dc15f35a344eab11bb756Kenny Root        StringPool typeStrings = StringPool(false, bundle->getUTF8());
252119138468caf7050d482dc15f35a344eab11bb756Kenny Root        StringPool keyStrings = StringPool(false, bundle->getUTF8());
25229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t N = p->getOrderedTypes().size();
25249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (size_t ti=0; ti<N; ti++) {
25259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<Type> t = p->getOrderedTypes().itemAt(ti);
25269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (t == NULL) {
25279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                typeStrings.add(String16("<empty>"), false);
25289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
25299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
25309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            typeStrings.add(t->getName(), false);
25319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const size_t N = t->getOrderedConfigs().size();
25339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (size_t ci=0; ci<N; ci++) {
25349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);
25359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (c == NULL) {
25369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
25379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
25389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                const size_t N = c->getEntries().size();
25399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (size_t ei=0; ei<N; ei++) {
25409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ConfigDescription config = c->getEntries().keyAt(ei);
25419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (!filter.match(config)) {
25429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        continue;
25439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
25449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sp<Entry> e = c->getEntries().valueAt(ei);
25459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (e == NULL) {
25469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        continue;
25479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
25489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    e->setNameIndex(keyStrings.add(e->getName(), true));
25499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    status_t err = e->prepareFlatten(&valueStrings, this);
25509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (err != NO_ERROR) {
25519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        return err;
25529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
25539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
25549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
25559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
25569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p->setTypeStrings(typeStrings.createStringBlock());
25589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p->setKeyStrings(keyStrings.createStringBlock());
25599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
25609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ssize_t strAmt = 0;
25629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Now build the array of package chunks.
25649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Vector<sp<AaptFile> > flatPackages;
25659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (pi=0; pi<N; pi++) {
25669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<Package> p = mOrderedPackages.itemAt(pi);
25679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (p->getTypes().size() == 0) {
25689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Empty, skip!
25699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            continue;
25709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
25719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t N = p->getTypeStrings().size();
25739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t baseSize = sizeof(ResTable_package);
25759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Start the package data.
25779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<AaptFile> data = new AaptFile(String8(), AaptGroupEntry(), String8());
25789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ResTable_package* header = (ResTable_package*)data->editData(baseSize);
25799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (header == NULL) {
25809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "ERROR: out of memory creating ResTable_package\n");
25819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return NO_MEMORY;
25829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
25839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        memset(header, 0, sizeof(*header));
25849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header->header.type = htods(RES_TABLE_PACKAGE_TYPE);
25859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header->header.headerSize = htods(sizeof(*header));
25869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header->id = htodl(p->getAssignedId());
25879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        strcpy16_htod(header->name, p->getName().string());
25889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Write the string blocks.
25909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t typeStringsStart = data->getSize();
25919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<AaptFile> strFile = p->getTypeStringsData();
25929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ssize_t amt = data->writeData(strFile->getData(), strFile->getSize());
25939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        #if PRINT_STRING_METRICS
25949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fprintf(stderr, "**** type strings: %d\n", amt);
25959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        #endif
25969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        strAmt += amt;
25979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (amt < 0) {
25989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return amt;
25999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
26009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t keyStringsStart = data->getSize();
26019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        strFile = p->getKeyStringsData();
26029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        amt = data->writeData(strFile->getData(), strFile->getSize());
26039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        #if PRINT_STRING_METRICS
26049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fprintf(stderr, "**** key strings: %d\n", amt);
26059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        #endif
26069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        strAmt += amt;
26079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (amt < 0) {
26089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return amt;
26099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
26109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Build the type chunks inside of this package.
26129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (size_t ti=0; ti<N; ti++) {
26139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Retrieve them in the same order as the type string block.
26149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            size_t len;
26159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String16 typeName(p->getTypeStrings().stringAt(ti, &len));
26169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<Type> t = p->getTypes().valueFor(typeName);
26179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOG_ALWAYS_FATAL_IF(t == NULL && typeName != String16("<empty>"),
26189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                "Type name %s not found",
26199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                String8(typeName).string());
26209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const size_t N = t != NULL ? t->getOrderedConfigs().size() : 0;
26229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // First write the typeSpec chunk, containing information about
26249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // each resource entry in this type.
26259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            {
26269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                const size_t typeSpecSize = sizeof(ResTable_typeSpec) + sizeof(uint32_t)*N;
26279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                const size_t typeSpecStart = data->getSize();
26289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ResTable_typeSpec* tsHeader = (ResTable_typeSpec*)
26299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    (((uint8_t*)data->editData(typeSpecStart+typeSpecSize)) + typeSpecStart);
26309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (tsHeader == NULL) {
26319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    fprintf(stderr, "ERROR: out of memory creating ResTable_typeSpec\n");
26329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return NO_MEMORY;
26339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
26349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                memset(tsHeader, 0, sizeof(*tsHeader));
26359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tsHeader->header.type = htods(RES_TABLE_TYPE_SPEC_TYPE);
26369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tsHeader->header.headerSize = htods(sizeof(*tsHeader));
26379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tsHeader->header.size = htodl(typeSpecSize);
26389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tsHeader->id = ti+1;
26399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tsHeader->entryCount = htodl(N);
26409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                uint32_t* typeSpecFlags = (uint32_t*)
26429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    (((uint8_t*)data->editData())
26439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + typeSpecStart + sizeof(ResTable_typeSpec));
26449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                memset(typeSpecFlags, 0, sizeof(uint32_t)*N);
26459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (size_t ei=0; ei<N; ei++) {
26479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sp<ConfigList> cl = t->getOrderedConfigs().itemAt(ei);
26489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (cl->getPublic()) {
26499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        typeSpecFlags[ei] |= htodl(ResTable_typeSpec::SPEC_PUBLIC);
26509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
26519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    const size_t CN = cl->getEntries().size();
26529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    for (size_t ci=0; ci<CN; ci++) {
26539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (!filter.match(cl->getEntries().keyAt(ci))) {
26549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            continue;
26559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
26569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        for (size_t cj=ci+1; cj<CN; cj++) {
26579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            if (!filter.match(cl->getEntries().keyAt(cj))) {
26589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                continue;
26599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
26609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            typeSpecFlags[ei] |= htodl(
26619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                cl->getEntries().keyAt(ci).diff(cl->getEntries().keyAt(cj)));
26629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
26639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
26649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
26659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
26669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // We need to write one type chunk for each configuration for
26689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // which we have entries in this type.
26699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const size_t NC = t->getUniqueConfigs().size();
26709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const size_t typeSize = sizeof(ResTable_type) + sizeof(uint32_t)*N;
26729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (size_t ci=0; ci<NC; ci++) {
26749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ConfigDescription config = t->getUniqueConfigs().itemAt(ci);
26759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                NOISY(printf("Writing config %d config: imsi:%d/%d lang:%c%c cnt:%c%c "
26779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                     "orien:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n",
26789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      ti+1,
26799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.mcc, config.mnc,
26809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.language[0] ? config.language[0] : '-',
26819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.language[1] ? config.language[1] : '-',
26829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.country[0] ? config.country[0] : '-',
26839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.country[1] ? config.country[1] : '-',
26849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.orientation,
26859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.touchscreen,
26869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.density,
26879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.keyboard,
26889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.inputFlags,
26899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.navigation,
26909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.screenWidth,
26919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.screenHeight));
26929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!filter.match(config)) {
26949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
26959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
26969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                const size_t typeStart = data->getSize();
26989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ResTable_type* tHeader = (ResTable_type*)
27009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    (((uint8_t*)data->editData(typeStart+typeSize)) + typeStart);
27019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (tHeader == NULL) {
27029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    fprintf(stderr, "ERROR: out of memory creating ResTable_type\n");
27039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return NO_MEMORY;
27049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
27059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                memset(tHeader, 0, sizeof(*tHeader));
27079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tHeader->header.type = htods(RES_TABLE_TYPE_TYPE);
27089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tHeader->header.headerSize = htods(sizeof(*tHeader));
27099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tHeader->id = ti+1;
27109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tHeader->entryCount = htodl(N);
27119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tHeader->entriesStart = htodl(typeSize);
27129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tHeader->config = config;
27139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                NOISY(printf("Writing type %d config: imsi:%d/%d lang:%c%c cnt:%c%c "
27149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                     "orien:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n",
27159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      ti+1,
27169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.mcc, tHeader->config.mnc,
27179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.language[0] ? tHeader->config.language[0] : '-',
27189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.language[1] ? tHeader->config.language[1] : '-',
27199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.country[0] ? tHeader->config.country[0] : '-',
27209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.country[1] ? tHeader->config.country[1] : '-',
27219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.orientation,
27229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.touchscreen,
27239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.density,
27249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.keyboard,
27259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.inputFlags,
27269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.navigation,
27279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.screenWidth,
27289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.screenHeight));
27299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tHeader->config.swapHtoD();
27309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Build the entries inside of this type.
27329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (size_t ei=0; ei<N; ei++) {
27339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sp<ConfigList> cl = t->getOrderedConfigs().itemAt(ei);
27349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sp<Entry> e = cl->getEntries().valueFor(config);
27359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Set the offset for this entry in its type.
27379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    uint32_t* index = (uint32_t*)
27389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        (((uint8_t*)data->editData())
27399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            + typeStart + sizeof(ResTable_type));
27409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (e != NULL) {
27419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        index[ei] = htodl(data->getSize()-typeStart-typeSize);
27429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // Create the entry.
27449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ssize_t amt = e->flatten(bundle, data, cl->getPublic());
27459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (amt < 0) {
27469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            return amt;
27479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
27489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else {
27499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        index[ei] = htodl(ResTable_type::NO_ENTRY);
27509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
27519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
27529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Fill in the rest of the type information.
27549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tHeader = (ResTable_type*)
27559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    (((uint8_t*)data->editData()) + typeStart);
27569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tHeader->header.size = htodl(data->getSize()-typeStart);
27579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
27589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
27599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Fill in the rest of the package information.
27619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header = (ResTable_package*)data->editData();
27629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header->header.size = htodl(data->getSize());
27639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header->typeStrings = htodl(typeStringsStart);
27649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header->lastPublicType = htodl(p->getTypeStrings().size());
27659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header->keyStrings = htodl(keyStringsStart);
27669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header->lastPublicKey = htodl(p->getKeyStrings().size());
27679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        flatPackages.add(data);
27699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
27709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // And now write out the final chunks.
27729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t dataStart = dest->getSize();
27739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
27759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // blah
27769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ResTable_header header;
27779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        memset(&header, 0, sizeof(header));
27789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header.header.type = htods(RES_TABLE_TYPE);
27799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header.header.headerSize = htods(sizeof(header));
27809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header.packageCount = htodl(flatPackages.size());
27819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        status_t err = dest->writeData(&header, sizeof(header));
27829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != NO_ERROR) {
27839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "ERROR: out of memory creating ResTable_header\n");
27849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return err;
27859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
27869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
27879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ssize_t strStart = dest->getSize();
27899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    err = valueStrings.writeStringBlock(dest);
27909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != NO_ERROR) {
27919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return err;
27929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
27939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ssize_t amt = (dest->getSize()-strStart);
27959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    strAmt += amt;
27969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    #if PRINT_STRING_METRICS
27979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    fprintf(stderr, "**** value strings: %d\n", amt);
27989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    fprintf(stderr, "**** total strings: %d\n", strAmt);
27999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    #endif
28009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (pi=0; pi<flatPackages.size(); pi++) {
28029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        err = dest->writeData(flatPackages[pi]->getData(),
28039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                              flatPackages[pi]->getSize());
28049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != NO_ERROR) {
28059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "ERROR: out of memory creating package chunk for ResTable_header\n");
28069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return err;
28079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
28089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
28099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ResTable_header* header = (ResTable_header*)
28119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (((uint8_t*)dest->getData()) + dataStart);
28129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    header->header.size = htodl(dest->getSize() - dataStart);
28139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    NOISY(aout << "Resource table:"
28159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project          << HexDump(dest->getData(), dest->getSize()) << endl);
28169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    #if PRINT_STRING_METRICS
28189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    fprintf(stderr, "**** total resource table size: %d / %d%% strings\n",
28199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dest->getSize(), (strAmt*100)/dest->getSize());
28209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    #endif
28219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
28239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
28249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResourceTable::writePublicDefinitions(const String16& package, FILE* fp)
28269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
28279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    fprintf(fp,
28289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    "<!-- This file contains <public> resource definitions for all\n"
28299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    "     resources that were generated from the source data. -->\n"
28309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    "\n"
28319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    "<resources>\n");
28329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    writePublicDefinitions(package, fp, true);
28349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    writePublicDefinitions(package, fp, false);
28359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    fprintf(fp,
28379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    "\n"
28389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    "</resources>\n");
28399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
28409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResourceTable::writePublicDefinitions(const String16& package, FILE* fp, bool pub)
28429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
28439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool didHeader = false;
28449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Package> pkg = mPackages.valueFor(package);
28469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (pkg != NULL) {
28479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t NT = pkg->getOrderedTypes().size();
28489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (size_t i=0; i<NT; i++) {
28499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<Type> t = pkg->getOrderedTypes().itemAt(i);
28509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (t == NULL) {
28519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
28529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
28539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bool didType = false;
28559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const size_t NC = t->getOrderedConfigs().size();
28579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (size_t j=0; j<NC; j++) {
28589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sp<ConfigList> c = t->getOrderedConfigs().itemAt(j);
28599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (c == NULL) {
28609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
28619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
28629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (c->getPublic() != pub) {
28649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
28659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
28669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!didType) {
28689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    fprintf(fp, "\n");
28699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    didType = true;
28709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
28719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!didHeader) {
28729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (pub) {
28739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        fprintf(fp,"  <!-- PUBLIC SECTION.  These resources have been declared public.\n");
28749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        fprintf(fp,"       Changes to these definitions will break binary compatibility. -->\n\n");
28759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else {
28769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        fprintf(fp,"  <!-- PRIVATE SECTION.  These resources have not been declared public.\n");
28779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        fprintf(fp,"       You can make them public my moving these lines into a file in res/values. -->\n\n");
28789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
28799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    didHeader = true;
28809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
28819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!pub) {
28829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    const size_t NE = c->getEntries().size();
28839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    for (size_t k=0; k<NE; k++) {
28849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const SourcePos& pos = c->getEntries().valueAt(k)->getPos();
28859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (pos.file != "") {
28869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            fprintf(fp,"  <!-- Declared at %s:%d -->\n",
28879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    pos.file.string(), pos.line);
28889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
28899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
28909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
28919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                fprintf(fp, "  <public type=\"%s\" name=\"%s\" id=\"0x%08x\" />\n",
28929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String8(t->getName()).string(),
28939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String8(c->getName()).string(),
28949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        getResId(pkg, t, c->getEntryIndex()));
28959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
28969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
28979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
28989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
28999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResourceTable::Item::Item(const SourcePos& _sourcePos,
29019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                          bool _isId,
29029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                          const String16& _value,
29039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                          const Vector<StringPool::entry_style_span>* _style,
29049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                          int32_t _format)
29059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    : sourcePos(_sourcePos)
29069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    , isId(_isId)
29079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    , value(_value)
29089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    , format(_format)
29099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    , bagKeyId(0)
29109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    , evaluating(false)
29119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
29129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (_style) {
29139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        style = *_style;
29149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
29159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
29169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::Entry::makeItABag(const SourcePos& sourcePos)
29189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
29199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mType == TYPE_BAG) {
29209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NO_ERROR;
29219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
29229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mType == TYPE_UNKNOWN) {
29239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mType = TYPE_BAG;
29249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NO_ERROR;
29259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
29269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sourcePos.error("Resource entry %s is already defined as a single item.\n"
29279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    "%s:%d: Originally defined here.\n",
29289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(mName).string(),
29299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mItem.sourcePos.file.string(), mItem.sourcePos.line);
29309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return UNKNOWN_ERROR;
29319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
29329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::Entry::setItem(const SourcePos& sourcePos,
29349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       const String16& value,
29359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       const Vector<StringPool::entry_style_span>* style,
29369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       int32_t format,
29379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       const bool overwrite)
29389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
29399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Item item(sourcePos, false, value, style);
29409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mType == TYPE_BAG) {
29429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const Item& item(mBag.valueAt(0));
29439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sourcePos.error("Resource entry %s is already defined as a bag.\n"
29449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        "%s:%d: Originally defined here.\n",
29459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String8(mName).string(),
29469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        item.sourcePos.file.string(), item.sourcePos.line);
29479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
29489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
29499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if ( (mType != TYPE_UNKNOWN) && (overwrite == false) ) {
29509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sourcePos.error("Resource entry %s is already defined.\n"
29519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        "%s:%d: Originally defined here.\n",
29529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String8(mName).string(),
29539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        mItem.sourcePos.file.string(), mItem.sourcePos.line);
29549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
29559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2956f878e2d80c3a0afefe3b018d232df6066379e1d5Robert Greenwalt
29579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mType = TYPE_ITEM;
29589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mItem = item;
29599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mItemFormat = format;
29609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
29619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
29629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::Entry::addToBag(const SourcePos& sourcePos,
29649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        const String16& key, const String16& value,
29659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        const Vector<StringPool::entry_style_span>* style,
29669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        bool replace, bool isId, int32_t format)
29679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
29689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = makeItABag(sourcePos);
29699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != NO_ERROR) {
29709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return err;
29719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
29729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Item item(sourcePos, isId, value, style, format);
29749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // XXX NOTE: there is an error if you try to have a bag with two keys,
29769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // one an attr and one an id, with the same name.  Not something we
29779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // currently ever have to worry about.
29789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ssize_t origKey = mBag.indexOfKey(key);
29799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (origKey >= 0) {
29809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!replace) {
29819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const Item& item(mBag.valueAt(origKey));
29829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sourcePos.error("Resource entry %s already has bag item %s.\n"
29839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    "%s:%d: Originally defined here.\n",
29849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(mName).string(), String8(key).string(),
29859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    item.sourcePos.file.string(), item.sourcePos.line);
29869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return UNKNOWN_ERROR;
29879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
29889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //printf("Replacing %s with %s\n",
29899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //       String8(mBag.valueFor(key).value).string(), String8(value).string());
29909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mBag.replaceValueFor(key, item);
29919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
29929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mBag.add(key, item);
29949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
29959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
29969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29974b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwaltstatus_t ResourceTable::Entry::emptyBag(const SourcePos& sourcePos)
29984b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt{
29994b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt    status_t err = makeItABag(sourcePos);
30004b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt    if (err != NO_ERROR) {
30014b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt        return err;
30024b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt    }
30034b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt
30044b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt    mBag.clear();
30054b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt    return NO_ERROR;
30064b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt}
30074b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt
30089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::Entry::generateAttributes(ResourceTable* table,
30099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                  const String16& package)
30109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
30119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 attr16("attr");
30129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 id16("id");
30139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t N = mBag.size();
30149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (size_t i=0; i<N; i++) {
30159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const String16& key = mBag.keyAt(i);
30169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const Item& it = mBag.valueAt(i);
30179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (it.isId) {
30189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!table->hasBagOrEntry(key, &id16, &package)) {
30199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String16 value("false");
30209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                status_t err = table->addEntry(SourcePos(String8("<generated>"), 0), package,
30219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                               id16, key, value);
30229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (err != NO_ERROR) {
30239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return err;
30249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
30259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
30269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (!table->hasBagOrEntry(key, &attr16, &package)) {
30279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
30289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 1
30299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//             fprintf(stderr, "ERROR: Bag attribute '%s' has not been defined.\n",
30309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//                     String8(key).string());
30319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//             const Item& item(mBag.valueAt(i));
30329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//             fprintf(stderr, "Referenced from file %s line %d\n",
30339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//                     item.sourcePos.file.string(), item.sourcePos.line);
30349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//             return UNKNOWN_ERROR;
30359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else
30369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            char numberStr[16];
30379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sprintf(numberStr, "%d", ResTable_map::TYPE_ANY);
30389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            status_t err = table->addBag(SourcePos("<generated>", 0), package,
30399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                         attr16, key, String16(""),
30409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                         String16("^type"),
30419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                         String16(numberStr), NULL, NULL);
30429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (err != NO_ERROR) {
30439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return err;
30449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
30459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
30469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
30479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
30489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
30499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
30509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
30519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::Entry::assignResourceIds(ResourceTable* table,
30529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                 const String16& package)
30539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
30549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool hasErrors = false;
30559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
30569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mType == TYPE_BAG) {
30579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const char* errorMsg;
30589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const String16 style16("style");
30599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const String16 attr16("attr");
30609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const String16 id16("id");
30619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mParentId = 0;
30629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mParent.size() > 0) {
30639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mParentId = table->getResId(mParent, &style16, NULL, &errorMsg);
30649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mParentId == 0) {
30659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mPos.error("Error retrieving parent for item: %s '%s'.\n",
30669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        errorMsg, String8(mParent).string());
30679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                hasErrors = true;
30689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
30699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
30709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t N = mBag.size();
30719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (size_t i=0; i<N; i++) {
30729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const String16& key = mBag.keyAt(i);
30739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Item& it = mBag.editValueAt(i);
30749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            it.bagKeyId = table->getResId(key,
30759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    it.isId ? &id16 : &attr16, NULL, &errorMsg);
30769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //printf("Bag key of %s: #%08x\n", String8(key).string(), it.bagKeyId);
30779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (it.bagKeyId == 0) {
30789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                it.sourcePos.error("Error: %s: %s '%s'.\n", errorMsg,
30799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String8(it.isId ? id16 : attr16).string(),
30809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String8(key).string());
30819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                hasErrors = true;
30829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
30839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
30849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
30859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
30869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
30879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
30889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::Entry::prepareFlatten(StringPool* strings, ResourceTable* table)
30899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
30909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mType == TYPE_ITEM) {
30919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Item& it = mItem;
30929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        AccessorCookie ac(it.sourcePos, String8(mName), String8(it.value));
30939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!table->stringToValue(&it.parsedValue, strings,
30949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  it.value, false, true, 0,
30959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  &it.style, NULL, &ac, mItemFormat)) {
30969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return UNKNOWN_ERROR;
30979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
30989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (mType == TYPE_BAG) {
30999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t N = mBag.size();
31009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (size_t i=0; i<N; i++) {
31019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const String16& key = mBag.keyAt(i);
31029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Item& it = mBag.editValueAt(i);
31039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            AccessorCookie ac(it.sourcePos, String8(key), String8(it.value));
31049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!table->stringToValue(&it.parsedValue, strings,
31059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                      it.value, false, true, it.bagKeyId,
31069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                      &it.style, NULL, &ac, it.format)) {
31079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return UNKNOWN_ERROR;
31089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
31099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
31109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
31119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPos.error("Error: entry %s is not a single item or a bag.\n",
31129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                   String8(mName).string());
31139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
31149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
31159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
31169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
31179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
31189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t ResourceTable::Entry::flatten(Bundle* bundle, const sp<AaptFile>& data, bool isPublic)
31199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
31209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t amt = 0;
31219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ResTable_entry header;
31229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    memset(&header, 0, sizeof(header));
31239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    header.size = htods(sizeof(header));
31249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const type ty = this != NULL ? mType : TYPE_ITEM;
31259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (this != NULL) {
31269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ty == TYPE_BAG) {
31279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            header.flags |= htods(header.FLAG_COMPLEX);
31289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
31299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (isPublic) {
31309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            header.flags |= htods(header.FLAG_PUBLIC);
31319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
31329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header.key.index = htodl(mNameIndex);
31339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
31349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (ty != TYPE_BAG) {
31359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        status_t err = data->writeData(&header, sizeof(header));
31369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != NO_ERROR) {
31379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "ERROR: out of memory creating ResTable_entry\n");
31389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return err;
31399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
31409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
31419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const Item& it = mItem;
31429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Res_value par;
31439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        memset(&par, 0, sizeof(par));
31449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        par.size = htods(it.parsedValue.size);
31459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        par.dataType = it.parsedValue.dataType;
31469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        par.res0 = it.parsedValue.res0;
31479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        par.data = htodl(it.parsedValue.data);
31489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        #if 0
31499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        printf("Writing item (%s): type=%d, data=0x%x, res0=0x%x\n",
31509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project               String8(mName).string(), it.parsedValue.dataType,
31519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project               it.parsedValue.data, par.res0);
31529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        #endif
31539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        err = data->writeData(&par, it.parsedValue.size);
31549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != NO_ERROR) {
31559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "ERROR: out of memory creating Res_value\n");
31569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return err;
31579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
31589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        amt += it.parsedValue.size;
31599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
31609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        size_t N = mBag.size();
31619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        size_t i;
31629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Create correct ordering of items.
31639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        KeyedVector<uint32_t, const Item*> items;
31649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (i=0; i<N; i++) {
31659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const Item& it = mBag.valueAt(i);
31669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            items.add(it.bagKeyId, &it);
31679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
31689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        N = items.size();
31699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
31709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ResTable_map_entry mapHeader;
31719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        memcpy(&mapHeader, &header, sizeof(header));
31729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mapHeader.size = htods(sizeof(mapHeader));
31739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mapHeader.parent.ident = htodl(mParentId);
31749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mapHeader.count = htodl(N);
31759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        status_t err = data->writeData(&mapHeader, sizeof(mapHeader));
31769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != NO_ERROR) {
31779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "ERROR: out of memory creating ResTable_entry\n");
31789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return err;
31799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
31809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
31819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (i=0; i<N; i++) {
31829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const Item& it = *items.valueAt(i);
31839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ResTable_map map;
31849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            map.name.ident = htodl(it.bagKeyId);
31859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            map.value.size = htods(it.parsedValue.size);
31869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            map.value.dataType = it.parsedValue.dataType;
31879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            map.value.res0 = it.parsedValue.res0;
31889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            map.value.data = htodl(it.parsedValue.data);
31899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            err = data->writeData(&map, sizeof(map));
31909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (err != NO_ERROR) {
31919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                fprintf(stderr, "ERROR: out of memory creating Res_value\n");
31929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return err;
31939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
31949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            amt += sizeof(map);
31959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
31969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
31979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return amt;
31989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
31999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
32009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResourceTable::ConfigList::appendComment(const String16& comment,
32019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                              bool onlyIfEmpty)
32029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
32039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (comment.size() <= 0) {
32049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
32059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
32069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (onlyIfEmpty && mComment.size() > 0) {
32079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
32089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
32099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mComment.size() > 0) {
32109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mComment.append(String16("\n"));
32119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
32129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mComment.append(comment);
32139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
32149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
32159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResourceTable::ConfigList::appendTypeComment(const String16& comment)
32169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
32179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (comment.size() <= 0) {
32189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
32199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
32209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mTypeComment.size() > 0) {
32219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mTypeComment.append(String16("\n"));
32229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
32239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mTypeComment.append(comment);
32249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
32259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
32269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::Type::addPublic(const SourcePos& sourcePos,
32279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        const String16& name,
32289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        const uint32_t ident)
32299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
32309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    #if 0
32319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t entryIdx = Res_GETENTRY(ident);
32329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (entryIdx < 0) {
32339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sourcePos.error("Public resource %s/%s has an invalid 0 identifier (0x%08x).\n",
32349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String8(mName).string(), String8(name).string(), ident);
32359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
32369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
32379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    #endif
32389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
32399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t typeIdx = Res_GETTYPE(ident);
32409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (typeIdx >= 0) {
32419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        typeIdx++;
32429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mPublicIndex > 0 && mPublicIndex != typeIdx) {
32439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sourcePos.error("Public resource %s/%s has conflicting type codes for its"
32449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    " public identifiers (0x%x vs 0x%x).\n",
32459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(mName).string(), String8(name).string(),
32469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mPublicIndex, typeIdx);
32479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return UNKNOWN_ERROR;
32489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
32499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPublicIndex = typeIdx;
32509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
32519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
32529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mFirstPublicSourcePos == NULL) {
32539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mFirstPublicSourcePos = new SourcePos(sourcePos);
32549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
32559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
32569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mPublic.indexOfKey(name) < 0) {
32579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPublic.add(name, Public(sourcePos, String16(), ident));
32589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
32599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Public& p = mPublic.editValueFor(name);
32609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (p.ident != ident) {
32619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sourcePos.error("Public resource %s/%s has conflicting public identifiers"
32629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    " (0x%08x vs 0x%08x).\n"
32639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    "%s:%d: Originally defined here.\n",
32649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(mName).string(), String8(name).string(), p.ident, ident,
32659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    p.sourcePos.file.string(), p.sourcePos.line);
32669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return UNKNOWN_ERROR;
32679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
32689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
32699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
32709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
32719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
32729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
327358c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackbornvoid ResourceTable::Type::canAddEntry(const String16& name)
327458c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn{
327558c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn    mCanAddEntries.add(name);
327658c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn}
327758c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn
32789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsp<ResourceTable::Entry> ResourceTable::Type::getEntry(const String16& entry,
32799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                       const SourcePos& sourcePos,
32809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                       const ResTable_config* config,
3281f878e2d80c3a0afefe3b018d232df6066379e1d5Robert Greenwalt                                                       bool doSetIndex,
3282f878e2d80c3a0afefe3b018d232df6066379e1d5Robert Greenwalt                                                       bool overlay)
32839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
32849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int pos = -1;
32859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<ConfigList> c = mConfigs.valueFor(entry);
32869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (c == NULL) {
328758c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn        if (overlay == true && mCanAddEntries.indexOf(entry) < 0) {
328858c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn            sourcePos.error("Resource at %s appears in overlay but not"
328958c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                            " in the base package; use <add-resource> to add.\n",
329058c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                            String8(entry).string());
3291f878e2d80c3a0afefe3b018d232df6066379e1d5Robert Greenwalt            return NULL;
3292f878e2d80c3a0afefe3b018d232df6066379e1d5Robert Greenwalt        }
32939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        c = new ConfigList(entry, sourcePos);
32949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mConfigs.add(entry, c);
32959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pos = (int)mOrderedConfigs.size();
32969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOrderedConfigs.add(c);
32979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (doSetIndex) {
32989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            c->setEntryIndex(pos);
32999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
33009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
33019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
33029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ConfigDescription cdesc;
33039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (config) cdesc = *config;
33049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
33059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Entry> e = c->getEntries().valueFor(cdesc);
33069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (e == NULL) {
33079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (config != NULL) {
33089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            NOISY(printf("New entry at %s:%d: imsi:%d/%d lang:%c%c cnt:%c%c "
33099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    "orien:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n",
33109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      sourcePos.file.string(), sourcePos.line,
33119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->mcc, config->mnc,
33129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->language[0] ? config->language[0] : '-',
33139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->language[1] ? config->language[1] : '-',
33149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->country[0] ? config->country[0] : '-',
33159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->country[1] ? config->country[1] : '-',
33169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->orientation,
33179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->touchscreen,
33189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->density,
33199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->keyboard,
33209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->inputFlags,
33219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->navigation,
33229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->screenWidth,
33239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->screenHeight));
33249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
33259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            NOISY(printf("New entry at %s:%d: NULL config\n",
33269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      sourcePos.file.string(), sourcePos.line));
33279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
33289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        e = new Entry(entry, sourcePos);
33299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        c->addEntry(cdesc, e);
33309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*
33319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (doSetIndex) {
33329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (pos < 0) {
33339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (pos=0; pos<(int)mOrderedConfigs.size(); pos++) {
33349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (mOrderedConfigs[pos] == c) {
33359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        break;
33369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
33379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
33389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (pos >= (int)mOrderedConfigs.size()) {
33399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sourcePos.error("Internal error: config not found in mOrderedConfigs when adding entry");
33409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return NULL;
33419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
33429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
33439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            e->setEntryIndex(pos);
33449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
33459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        */
33469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
33479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
33489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mUniqueConfigs.add(cdesc);
33499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
33509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return e;
33519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
33529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
33539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::Type::applyPublicEntryOrder()
33549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
33559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t N = mOrderedConfigs.size();
33569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Vector<sp<ConfigList> > origOrder(mOrderedConfigs);
33579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool hasError = false;
33589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
33599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t i;
33609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (i=0; i<N; i++) {
33619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOrderedConfigs.replaceAt(NULL, i);
33629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
33639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
33649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t NP = mPublic.size();
33659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //printf("Ordering %d configs from %d public defs\n", N, NP);
33669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t j;
33679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (j=0; j<NP; j++) {
33689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const String16& name = mPublic.keyAt(j);
33699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const Public& p = mPublic.valueAt(j);
33709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int32_t idx = Res_GETENTRY(p.ident);
33719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //printf("Looking for entry \"%s\"/\"%s\" (0x%08x) in %d...\n",
33729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //       String8(mName).string(), String8(name).string(), p.ident, N);
33739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bool found = false;
33749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (i=0; i<N; i++) {
33759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<ConfigList> e = origOrder.itemAt(i);
33769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //printf("#%d: \"%s\"\n", i, String8(e->getName()).string());
33779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (e->getName() == name) {
33789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (idx >= (int32_t)mOrderedConfigs.size()) {
33799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    p.sourcePos.error("Public entry identifier 0x%x entry index "
33809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            "is larger than available symbols (index %d, total symbols %d).\n",
33819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            p.ident, idx, mOrderedConfigs.size());
33829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hasError = true;
33839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (mOrderedConfigs.itemAt(idx) == NULL) {
33849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    e->setPublic(true);
33859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    e->setPublicSourcePos(p.sourcePos);
33869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mOrderedConfigs.replaceAt(e, idx);
33879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    origOrder.removeAt(i);
33889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    N--;
33899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    found = true;
33909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
33919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
33929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sp<ConfigList> oe = mOrderedConfigs.itemAt(idx);
33939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
33949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    p.sourcePos.error("Multiple entry names declared for public entry"
33959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            " identifier 0x%x in type %s (%s vs %s).\n"
33969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            "%s:%d: Originally defined here.",
33979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            idx+1, String8(mName).string(),
33989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            String8(oe->getName()).string(),
33999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            String8(name).string(),
34009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            oe->getPublicSourcePos().file.string(),
34019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            oe->getPublicSourcePos().line);
34029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hasError = true;
34039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
34049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
34059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
34069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!found) {
34089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.sourcePos.error("Public symbol %s/%s declared here is not defined.",
34099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(mName).string(), String8(name).string());
34109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            hasError = true;
34119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
34129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
34139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //printf("Copying back in %d non-public configs, have %d\n", N, origOrder.size());
34159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (N != origOrder.size()) {
34179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        printf("Internal error: remaining private symbol count mismatch\n");
34189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        N = origOrder.size();
34199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
34209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    j = 0;
34229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (i=0; i<N; i++) {
34239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<ConfigList> e = origOrder.itemAt(i);
34249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // There will always be enough room for the remaining entries.
34259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (mOrderedConfigs.itemAt(j) != NULL) {
34269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            j++;
34279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
34289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOrderedConfigs.replaceAt(e, j);
34299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        j++;
34309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
34319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return hasError ? UNKNOWN_ERROR : NO_ERROR;
34339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
34349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResourceTable::Package::Package(const String16& name, ssize_t includedId)
34369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    : mName(name), mIncludedId(includedId),
34379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      mTypeStringsMapping(0xffffffff),
34389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      mKeyStringsMapping(0xffffffff)
34399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
34409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
34419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsp<ResourceTable::Type> ResourceTable::Package::getType(const String16& type,
34439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                        const SourcePos& sourcePos,
34449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                        bool doSetIndex)
34459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
34469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Type> t = mTypes.valueFor(type);
34479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (t == NULL) {
34489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        t = new Type(type, sourcePos);
34499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mTypes.add(type, t);
34509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOrderedTypes.add(t);
34519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (doSetIndex) {
34529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // For some reason the type's index is set to one plus the index
34539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // in the mOrderedTypes list, rather than just the index.
34549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            t->setIndex(mOrderedTypes.size());
34559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
34569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
34579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return t;
34589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
34599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::Package::setTypeStrings(const sp<AaptFile>& data)
34619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
34629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mTypeStringsData = data;
34639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = setStrings(data, &mTypeStrings, &mTypeStringsMapping);
34649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != NO_ERROR) {
34659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fprintf(stderr, "ERROR: Type string data is corrupt!\n");
34669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
34679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err;
34689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
34699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::Package::setKeyStrings(const sp<AaptFile>& data)
34719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
34729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mKeyStringsData = data;
34739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = setStrings(data, &mKeyStrings, &mKeyStringsMapping);
34749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != NO_ERROR) {
34759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fprintf(stderr, "ERROR: Key string data is corrupt!\n");
34769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
34779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err;
34789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
34799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::Package::setStrings(const sp<AaptFile>& data,
34819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                            ResStringPool* strings,
34829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                            DefaultKeyedVector<String16, uint32_t>* mappings)
34839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
34849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (data->getData() == NULL) {
34859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
34869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
34879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    NOISY(aout << "Setting restable string pool: "
34899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project          << HexDump(data->getData(), data->getSize()) << endl);
34909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = strings->setTo(data->getData(), data->getSize());
34929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err == NO_ERROR) {
34939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t N = strings->size();
34949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (size_t i=0; i<N; i++) {
34959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            size_t len;
34969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mappings->add(String16(strings->stringAt(i, &len)), i);
34979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
34989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
34999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err;
35009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
35019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
35029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::Package::applyPublicTypeOrder()
35039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
35049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t N = mOrderedTypes.size();
35059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Vector<sp<Type> > origOrder(mOrderedTypes);
35069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
35079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t i;
35089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (i=0; i<N; i++) {
35099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOrderedTypes.replaceAt(NULL, i);
35109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
35119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
35129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (i=0; i<N; i++) {
35139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<Type> t = origOrder.itemAt(i);
35149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int32_t idx = t->getPublicIndex();
35159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (idx > 0) {
35169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            idx--;
35179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            while (idx >= (int32_t)mOrderedTypes.size()) {
35189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mOrderedTypes.add();
35199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
35209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mOrderedTypes.itemAt(idx) != NULL) {
35219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sp<Type> ot = mOrderedTypes.itemAt(idx);
35229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                t->getFirstPublicSourcePos().error("Multiple type names declared for public type"
35239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        " identifier 0x%x (%s vs %s).\n"
35249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        "%s:%d: Originally defined here.",
35259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        idx, String8(ot->getName()).string(),
35269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String8(t->getName()).string(),
35279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ot->getFirstPublicSourcePos().file.string(),
35289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ot->getFirstPublicSourcePos().line);
35299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return UNKNOWN_ERROR;
35309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
35319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mOrderedTypes.replaceAt(t, idx);
35329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            origOrder.removeAt(i);
35339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            i--;
35349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            N--;
35359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
35369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
35379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
35389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t j=0;
35399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (i=0; i<N; i++) {
35409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<Type> t = origOrder.itemAt(i);
35419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // There will always be enough room for the remaining types.
35429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (mOrderedTypes.itemAt(j) != NULL) {
35439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            j++;
35449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
35459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOrderedTypes.replaceAt(t, j);
35469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
35479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
35489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
35499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
35509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
35519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsp<ResourceTable::Package> ResourceTable::getPackage(const String16& package)
35529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
35539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Package> p = mPackages.valueFor(package);
35549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (p == NULL) {
35559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mIsAppPackage) {
35569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mHaveAppPackage) {
35579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                fprintf(stderr, "Adding multiple application package resources; only one is allowed.\n"
35589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                "Use -x to create extended resources.\n");
35599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return NULL;
35609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
35619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mHaveAppPackage = true;
35629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p = new Package(package, 127);
35639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
35649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p = new Package(package, mNextPackageId);
35659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
35669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //printf("*** NEW PACKAGE: \"%s\" id=%d\n",
35679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //       String8(package).string(), p->getAssignedId());
35689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPackages.add(package, p);
35699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOrderedPackages.add(p);
35709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mNextPackageId++;
35719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
35729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return p;
35739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
35749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
35759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsp<ResourceTable::Type> ResourceTable::getType(const String16& package,
35769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                               const String16& type,
35779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                               const SourcePos& sourcePos,
35789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                               bool doSetIndex)
35799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
35809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Package> p = getPackage(package);
35819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (p == NULL) {
35829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
35839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
35849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return p->getType(type, sourcePos, doSetIndex);
35859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
35869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
35879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsp<ResourceTable::Entry> ResourceTable::getEntry(const String16& package,
35889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                 const String16& type,
35899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                 const String16& name,
35909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                 const SourcePos& sourcePos,
3591f878e2d80c3a0afefe3b018d232df6066379e1d5Robert Greenwalt                                                 bool overlay,
35929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                 const ResTable_config* config,
35939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                 bool doSetIndex)
35949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
35959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Type> t = getType(package, type, sourcePos, doSetIndex);
35969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (t == NULL) {
35979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
35989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3599f878e2d80c3a0afefe3b018d232df6066379e1d5Robert Greenwalt    return t->getEntry(name, sourcePos, config, doSetIndex, overlay);
36009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
36019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsp<const ResourceTable::Entry> ResourceTable::getEntry(uint32_t resID,
36039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                       const ResTable_config* config) const
36049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
36059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int pid = Res_GETPACKAGE(resID)+1;
36069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t N = mOrderedPackages.size();
36079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t i;
36089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Package> p;
36099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (i=0; i<N; i++) {
36109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<Package> check = mOrderedPackages[i];
36119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (check->getAssignedId() == pid) {
36129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p = check;
36139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
36149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
36159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
36179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (p == NULL) {
3618dd931864209eac0b4182d7a0d1ca965fcc3b8c03Marco Nelissen        fprintf(stderr, "warning: Package not found for resource #%08x\n", resID);
36199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
36209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
36219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int tid = Res_GETTYPE(resID);
36239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (tid < 0 || tid >= (int)p->getOrderedTypes().size()) {
3624dd931864209eac0b4182d7a0d1ca965fcc3b8c03Marco Nelissen        fprintf(stderr, "warning: Type not found for resource #%08x\n", resID);
36259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
36269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
36279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Type> t = p->getOrderedTypes()[tid];
36289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int eid = Res_GETENTRY(resID);
36309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (eid < 0 || eid >= (int)t->getOrderedConfigs().size()) {
3631dd931864209eac0b4182d7a0d1ca965fcc3b8c03Marco Nelissen        fprintf(stderr, "warning: Entry not found for resource #%08x\n", resID);
36329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
36339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
36349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<ConfigList> c = t->getOrderedConfigs()[eid];
36369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (c == NULL) {
3637dd931864209eac0b4182d7a0d1ca965fcc3b8c03Marco Nelissen        fprintf(stderr, "warning: Entry not found for resource #%08x\n", resID);
36389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
36399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
36409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ConfigDescription cdesc;
36429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (config) cdesc = *config;
36439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Entry> e = c->getEntries().valueFor(cdesc);
36449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (c == NULL) {
3645dd931864209eac0b4182d7a0d1ca965fcc3b8c03Marco Nelissen        fprintf(stderr, "warning: Entry configuration not found for resource #%08x\n", resID);
36469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
36479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
36489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return e;
36509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
36519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst ResourceTable::Item* ResourceTable::getItem(uint32_t resID, uint32_t attrID) const
36539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
36549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<const Entry> e = getEntry(resID);
36559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (e == NULL) {
36569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
36579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
36589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t N = e->getBag().size();
36609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (size_t i=0; i<N; i++) {
36619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const Item& it = e->getBag().valueAt(i);
36629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (it.bagKeyId == 0) {
3663dd931864209eac0b4182d7a0d1ca965fcc3b8c03Marco Nelissen            fprintf(stderr, "warning: ID not yet assigned to '%s' in bag '%s'\n",
36649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(e->getName()).string(),
36659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(e->getBag().keyAt(i)).string());
36669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
36679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (it.bagKeyId == attrID) {
36689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return &it;
36699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
36709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
36719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NULL;
36739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
36749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::getItemValue(
36769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t resID, uint32_t attrID, Res_value* outValue)
36779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
36789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const Item* item = getItem(resID, attrID);
36799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool res = false;
36819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (item != NULL) {
36829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (item->evaluating) {
36839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<const Entry> e = getEntry(resID);
36849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const size_t N = e->getBag().size();
36859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            size_t i;
36869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (i=0; i<N; i++) {
36879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (&e->getBag().valueAt(i) == item) {
36889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
36899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
36909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3691dd931864209eac0b4182d7a0d1ca965fcc3b8c03Marco Nelissen            fprintf(stderr, "warning: Circular reference detected in key '%s' of bag '%s'\n",
36929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(e->getName()).string(),
36939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(e->getBag().keyAt(i)).string());
36949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
36959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
36969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        item->evaluating = true;
36979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        res = stringToValue(outValue, NULL, item->value, false, false, item->bagKeyId);
36989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NOISY(
36999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (res) {
37009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                printf("getItemValue of #%08x[#%08x] (%s): type=#%08x, data=#%08x\n",
37019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                       resID, attrID, String8(getEntry(resID)->getName()).string(),
37029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                       outValue->dataType, outValue->data);
37039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
37049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                printf("getItemValue of #%08x[#%08x]: failed\n",
37059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                       resID, attrID);
37069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
37079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        );
37089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        item->evaluating = false;
37099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
37109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return res;
37119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3712