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