ResourceTable.cpp revision e6b680364dd992907a8d2037685a2e500d188dfb
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"
10e6b680364dd992907a8d2037685a2e500d188dfbDianne Hackborn#include "ResourceFilter.h"
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/ByteOrder.h>
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/ResourceTypes.h>
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdarg.h>
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define NOISY(x) //x
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t compileXmlFile(const sp<AaptAssets>& assets,
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const sp<AaptFile>& target,
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ResourceTable* table,
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        int options)
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<XMLNode> root = XMLNode::parse(target);
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (root == NULL) {
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
27a96cbb435d7b2197ab2b61fd98d14cbd6e0c5c3dDianne Hackborn
28a96cbb435d7b2197ab2b61fd98d14cbd6e0c5c3dDianne Hackborn    return compileXmlFile(assets, root, target, table, options);
29a96cbb435d7b2197ab2b61fd98d14cbd6e0c5c3dDianne Hackborn}
30a96cbb435d7b2197ab2b61fd98d14cbd6e0c5c3dDianne Hackborn
31a96cbb435d7b2197ab2b61fd98d14cbd6e0c5c3dDianne Hackbornstatus_t compileXmlFile(const sp<AaptAssets>& assets,
32cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackborn                        const sp<AaptFile>& target,
33cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackborn                        const sp<AaptFile>& outTarget,
34cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackborn                        ResourceTable* table,
35cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackborn                        int options)
36cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackborn{
37cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackborn    sp<XMLNode> root = XMLNode::parse(target);
38cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackborn    if (root == NULL) {
39cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackborn        return UNKNOWN_ERROR;
40cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackborn    }
41cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackborn
42cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackborn    return compileXmlFile(assets, root, outTarget, table, options);
43cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackborn}
44cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackborn
45cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackbornstatus_t compileXmlFile(const sp<AaptAssets>& assets,
46a96cbb435d7b2197ab2b61fd98d14cbd6e0c5c3dDianne Hackborn                        const sp<XMLNode>& root,
47a96cbb435d7b2197ab2b61fd98d14cbd6e0c5c3dDianne Hackborn                        const sp<AaptFile>& target,
48a96cbb435d7b2197ab2b61fd98d14cbd6e0c5c3dDianne Hackborn                        ResourceTable* table,
49a96cbb435d7b2197ab2b61fd98d14cbd6e0c5c3dDianne Hackborn                        int options)
50a96cbb435d7b2197ab2b61fd98d14cbd6e0c5c3dDianne Hackborn{
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if ((options&XML_COMPILE_STRIP_WHITESPACE) != 0) {
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        root->removeWhitespace(true, NULL);
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else  if ((options&XML_COMPILE_COMPACT_WHITESPACE) != 0) {
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        root->removeWhitespace(false, NULL);
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5719138468caf7050d482dc15f35a344eab11bb756Kenny Root    if ((options&XML_COMPILE_UTF8) != 0) {
5819138468caf7050d482dc15f35a344eab11bb756Kenny Root        root->setUTF8(true);
5919138468caf7050d482dc15f35a344eab11bb756Kenny Root    }
6019138468caf7050d482dc15f35a344eab11bb756Kenny Root
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool hasErrors = false;
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if ((options&XML_COMPILE_ASSIGN_ATTRIBUTE_IDS) != 0) {
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        status_t err = root->assignResourceIds(assets, table);
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != NO_ERROR) {
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            hasErrors = true;
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = root->parseValues(assets, table);
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != NO_ERROR) {
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        hasErrors = true;
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (hasErrors) {
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    NOISY(printf("Input XML Resource:\n"));
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    NOISY(root->print());
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    err = root->flatten(target,
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (options&XML_COMPILE_STRIP_COMMENTS) != 0,
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (options&XML_COMPILE_STRIP_RAW_VALUES) != 0);
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != NO_ERROR) {
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return err;
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    NOISY(printf("Output XML Resource:\n"));
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    NOISY(ResXMLTree tree;
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        tree.setTo(target->getData(), target->getSize());
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        printXMLBlock(&tree));
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    target->setCompressionMethod(ZipEntry::kCompressDeflated);
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err;
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#undef NOISY
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define NOISY(x) //x
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct flag_entry
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char16_t* name;
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t nameLen;
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t value;
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char* description;
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char16_t referenceArray[] =
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { 'r', 'e', 'f', 'e', 'r', 'e', 'n', 'c', 'e' };
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char16_t stringArray[] =
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { 's', 't', 'r', 'i', 'n', 'g' };
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char16_t integerArray[] =
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { 'i', 'n', 't', 'e', 'g', 'e', 'r' };
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char16_t booleanArray[] =
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { 'b', 'o', 'o', 'l', 'e', 'a', 'n' };
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char16_t colorArray[] =
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { 'c', 'o', 'l', 'o', 'r' };
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char16_t floatArray[] =
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { 'f', 'l', 'o', 'a', 't' };
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char16_t dimensionArray[] =
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n' };
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char16_t fractionArray[] =
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { 'f', 'r', 'a', 'c', 't', 'i', 'o', 'n' };
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char16_t enumArray[] =
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { 'e', 'n', 'u', 'm' };
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char16_t flagsArray[] =
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { 'f', 'l', 'a', 'g', 's' };
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const flag_entry gFormatFlags[] = {
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { referenceArray, sizeof(referenceArray)/2, ResTable_map::TYPE_REFERENCE,
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "a reference to another resource, in the form \"<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>\"\n"
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "or to a theme attribute in the form \"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>\"."},
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { stringArray, sizeof(stringArray)/2, ResTable_map::TYPE_STRING,
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "a string value, using '\\\\;' to escape characters such as '\\\\n' or '\\\\uxxxx' for a unicode character." },
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { integerArray, sizeof(integerArray)/2, ResTable_map::TYPE_INTEGER,
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "an integer value, such as \"<code>100</code>\"." },
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { booleanArray, sizeof(booleanArray)/2, ResTable_map::TYPE_BOOLEAN,
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "a boolean value, either \"<code>true</code>\" or \"<code>false</code>\"." },
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { colorArray, sizeof(colorArray)/2, ResTable_map::TYPE_COLOR,
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "a color value, in the form of \"<code>#<i>rgb</i></code>\", \"<code>#<i>argb</i></code>\",\n"
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "\"<code>#<i>rrggbb</i></code>\", or \"<code>#<i>aarrggbb</i></code>\"." },
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { floatArray, sizeof(floatArray)/2, ResTable_map::TYPE_FLOAT,
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "a floating point value, such as \"<code>1.2</code>\"."},
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { dimensionArray, sizeof(dimensionArray)/2, ResTable_map::TYPE_DIMENSION,
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "a dimension value, which is a floating point number appended with a unit such as \"<code>14.5sp</code>\".\n"
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size),\n"
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "in (inches), mm (millimeters)." },
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { fractionArray, sizeof(fractionArray)/2, ResTable_map::TYPE_FRACTION,
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The 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"
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "The % suffix always means a percentage of the base size; the optional %p suffix provides a size relative to\n"
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "some parent container." },
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { enumArray, sizeof(enumArray)/2, ResTable_map::TYPE_ENUM, NULL },
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { flagsArray, sizeof(flagsArray)/2, ResTable_map::TYPE_FLAGS, NULL },
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { NULL, 0, 0, NULL }
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char16_t suggestedArray[] = { 's', 'u', 'g', 'g', 'e', 's', 't', 'e', 'd' };
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const flag_entry l10nRequiredFlags[] = {
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { suggestedArray, sizeof(suggestedArray)/2, ResTable_map::L10N_SUGGESTED, NULL },
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { NULL, 0, 0, NULL }
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char16_t nulStr[] = { 0 };
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic uint32_t parse_flags(const char16_t* str, size_t len,
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             const flag_entry* flags, bool* outError = NULL)
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (len > 0 && isspace(*str)) {
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        str++;
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        len--;
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (len > 0 && isspace(str[len-1])) {
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        len--;
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char16_t* const end = str + len;
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t value = 0;
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (str < end) {
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const char16_t* div = str;
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (div < end && *div != '|') {
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            div++;
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const flag_entry* cur = flags;
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (cur->name) {
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (strzcmp16(cur->name, cur->nameLen, str, div-str) == 0) {
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                value |= cur->value;
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            cur++;
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!cur->name) {
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (outError) *outError = true;
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        str = div < end ? div+1 : div;
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (outError) *outError = false;
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return value;
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic String16 mayOrMust(int type, int flags)
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if ((type&(~flags)) == 0) {
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return String16("<p>Must");
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return String16("<p>May");
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void appendTypeInfo(ResourceTable* outTable, const String16& pkg,
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const String16& typeName, const String16& ident, int type,
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const flag_entry* flags)
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool hadType = false;
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (flags->name) {
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((type&flags->value) != 0 && flags->description != NULL) {
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String16 fullMsg(mayOrMust(type, flags->value));
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fullMsg.append(String16(" be "));
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fullMsg.append(String16(flags->description));
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            outTable->appendTypeComment(pkg, typeName, ident, fullMsg);
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            hadType = true;
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        flags++;
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (hadType && (type&ResTable_map::TYPE_REFERENCE) == 0) {
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        outTable->appendTypeComment(pkg, typeName, ident,
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String16("<p>This may also be a reference to a resource (in the form\n"
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                         "\"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>\") or\n"
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                         "theme attribute (in the form\n"
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                         "\"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>\")\n"
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                         "containing a value of this type."));
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct PendingAttribute
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 myPackage;
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const SourcePos sourcePos;
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const bool appendComment;
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t type;
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String16 ident;
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String16 comment;
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool hasErrors;
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool added;
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    PendingAttribute(String16 _package, const sp<AaptFile>& in,
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ResXMLTree& block, bool _appendComment)
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        : myPackage(_package)
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        , sourcePos(in->getPrintableSource(), block.getLineNumber())
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        , appendComment(_appendComment)
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        , type(ResTable_map::TYPE_ANY)
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        , hasErrors(false)
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        , added(false)
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t createIfNeeded(ResourceTable* outTable)
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (added || hasErrors) {
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return NO_ERROR;
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        added = true;
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String16 attr16("attr");
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (outTable->hasBagOrEntry(myPackage, attr16, ident)) {
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sourcePos.error("Attribute \"%s\" has already been defined\n",
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(ident).string());
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            hasErrors = true;
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return UNKNOWN_ERROR;
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        char numberStr[16];
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sprintf(numberStr, "%d", type);
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        status_t err = outTable->addBag(sourcePos, myPackage,
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                attr16, ident, String16(""),
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String16("^type"),
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String16(numberStr), NULL, NULL);
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != NO_ERROR) {
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            hasErrors = true;
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return err;
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        outTable->appendComment(myPackage, attr16, ident, comment, appendComment);
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //printf("Attribute %s comment: %s\n", String8(ident).string(),
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //     String8(comment).string());
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return err;
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic status_t compileAttribute(const sp<AaptFile>& in,
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 ResXMLTree& block,
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16& myPackage,
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 ResourceTable* outTable,
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 String16* outIdent = NULL,
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 bool inStyleable = false)
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    PendingAttribute attr(myPackage, in, block, inStyleable);
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 attr16("attr");
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 id16("id");
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Attribute type constants.
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 enum16("enum");
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 flag16("flag");
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ResXMLTree::event_code_t code;
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t len;
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err;
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ssize_t identIdx = block.indexOfAttribute(NULL, "name");
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (identIdx >= 0) {
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        attr.ident = String16(block.getAttributeStringValue(identIdx, &len));
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (outIdent) {
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            *outIdent = attr.ident;
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        attr.sourcePos.error("A 'name' attribute is required for <attr>\n");
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        attr.hasErrors = true;
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    attr.comment = String16(
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            block.getComment(&len) ? block.getComment(&len) : nulStr);
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ssize_t typeIdx = block.indexOfAttribute(NULL, "format");
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (typeIdx >= 0) {
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String16 typeStr = String16(block.getAttributeStringValue(typeIdx, &len));
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        attr.type = parse_flags(typeStr.string(), typeStr.size(), gFormatFlags);
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (attr.type == 0) {
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            attr.sourcePos.error("Tag <attr> 'format' attribute value \"%s\" not valid\n",
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(typeStr).string());
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            attr.hasErrors = true;
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        attr.createIfNeeded(outTable);
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (!inStyleable) {
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Attribute definitions outside of styleables always define the
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // attribute as a generic value.
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        attr.createIfNeeded(outTable);
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //printf("Attribute %s: type=0x%08x\n", String8(attr.ident).string(), attr.type);
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ssize_t minIdx = block.indexOfAttribute(NULL, "min");
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (minIdx >= 0) {
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String16 val = String16(block.getAttributeStringValue(minIdx, &len));
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!ResTable::stringToInt(val.string(), val.size(), NULL)) {
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            attr.sourcePos.error("Tag <attr> 'min' attribute must be a number, not \"%s\"\n",
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(val).string());
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            attr.hasErrors = true;
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        attr.createIfNeeded(outTable);
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!attr.hasErrors) {
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident,
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String16(""), String16("^min"), String16(val), NULL, NULL);
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (err != NO_ERROR) {
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                attr.hasErrors = true;
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ssize_t maxIdx = block.indexOfAttribute(NULL, "max");
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (maxIdx >= 0) {
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String16 val = String16(block.getAttributeStringValue(maxIdx, &len));
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!ResTable::stringToInt(val.string(), val.size(), NULL)) {
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            attr.sourcePos.error("Tag <attr> 'max' attribute must be a number, not \"%s\"\n",
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(val).string());
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            attr.hasErrors = true;
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        attr.createIfNeeded(outTable);
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!attr.hasErrors) {
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident,
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String16(""), String16("^max"), String16(val), NULL, NULL);
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            attr.hasErrors = true;
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if ((minIdx >= 0 || maxIdx >= 0) && (attr.type&ResTable_map::TYPE_INTEGER) == 0) {
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        attr.sourcePos.error("Tag <attr> must have format=integer attribute if using max or min\n");
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        attr.hasErrors = true;
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ssize_t l10nIdx = block.indexOfAttribute(NULL, "localization");
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (l10nIdx >= 0) {
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const uint16_t* str = block.getAttributeStringValue(l10nIdx, &len);
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bool error;
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        uint32_t l10n_required = parse_flags(str, len, l10nRequiredFlags, &error);
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (error) {
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            attr.sourcePos.error("Tag <attr> 'localization' attribute value \"%s\" not valid\n",
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(str).string());
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            attr.hasErrors = true;
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        attr.createIfNeeded(outTable);
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!attr.hasErrors) {
400f5a7c121dd3abb9763c30115c772fd1fc03caea2Kenny Root            char buf[11];
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sprintf(buf, "%d", l10n_required);
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident,
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String16(""), String16("^l10n"), String16(buf), NULL, NULL);
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (err != NO_ERROR) {
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                attr.hasErrors = true;
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String16 enumOrFlagsComment;
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (code == ResXMLTree::START_TAG) {
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            uint32_t localType = 0;
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (strcmp16(block.getElementName(&len), enum16.string()) == 0) {
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                localType = ResTable_map::TYPE_ENUM;
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), flag16.string()) == 0) {
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                localType = ResTable_map::TYPE_FLAGS;
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                SourcePos(in->getPrintableSource(), block.getLineNumber())
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        .error("Tag <%s> can not appear inside <attr>, only <enum> or <flag>\n",
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String8(block.getElementName(&len)).string());
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return UNKNOWN_ERROR;
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            attr.createIfNeeded(outTable);
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (attr.type == ResTable_map::TYPE_ANY) {
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // No type was explicitly stated, so supplying enum tags
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // implicitly creates an enum or flag.
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                attr.type = 0;
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if ((attr.type&(ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS)) == 0) {
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Wasn't originally specified as an enum, so update its type.
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                attr.type |= localType;
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!attr.hasErrors) {
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    char numberStr[16];
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sprintf(numberStr, "%d", attr.type);
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    err = outTable->addBag(SourcePos(in->getPrintableSource(), block.getLineNumber()),
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            myPackage, attr16, attr.ident, String16(""),
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            String16("^type"), String16(numberStr), NULL, NULL, true);
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (err != NO_ERROR) {
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        attr.hasErrors = true;
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if ((uint32_t)(attr.type&(ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS)) != localType) {
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (localType == ResTable_map::TYPE_ENUM) {
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    SourcePos(in->getPrintableSource(), block.getLineNumber())
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            .error("<enum> attribute can not be used inside a flags format\n");
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    attr.hasErrors = true;
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    SourcePos(in->getPrintableSource(), block.getLineNumber())
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            .error("<flag> attribute can not be used inside a enum format\n");
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    attr.hasErrors = true;
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String16 itemIdent;
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ssize_t itemIdentIdx = block.indexOfAttribute(NULL, "name");
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (itemIdentIdx >= 0) {
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                itemIdent = String16(block.getAttributeStringValue(itemIdentIdx, &len));
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                SourcePos(in->getPrintableSource(), block.getLineNumber())
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        .error("A 'name' attribute is required for <enum> or <flag>\n");
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                attr.hasErrors = true;
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String16 value;
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ssize_t valueIdx = block.indexOfAttribute(NULL, "value");
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (valueIdx >= 0) {
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                value = String16(block.getAttributeStringValue(valueIdx, &len));
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                SourcePos(in->getPrintableSource(), block.getLineNumber())
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        .error("A 'value' attribute is required for <enum> or <flag>\n");
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                attr.hasErrors = true;
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!attr.hasErrors && !ResTable::stringToInt(value.string(), value.size(), NULL)) {
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                SourcePos(in->getPrintableSource(), block.getLineNumber())
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        .error("Tag <enum> or <flag> 'value' attribute must be a number,"
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        " not \"%s\"\n",
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String8(value).string());
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                attr.hasErrors = true;
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Make sure an id is defined for this enum/flag identifier...
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!attr.hasErrors && !outTable->hasBagOrEntry(itemIdent, &id16, &myPackage)) {
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                err = outTable->startBag(SourcePos(in->getPrintableSource(), block.getLineNumber()),
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                         myPackage, id16, itemIdent, String16(), NULL);
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (err != NO_ERROR) {
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    attr.hasErrors = true;
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!attr.hasErrors) {
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (enumOrFlagsComment.size() == 0) {
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    enumOrFlagsComment.append(mayOrMust(attr.type,
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS));
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    enumOrFlagsComment.append((attr.type&ResTable_map::TYPE_ENUM)
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       ? String16(" be one of the following constant values.")
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       : String16(" be one or more (separated by '|') of the following constant values."));
50259ad275e937bb3c32e59bc01d86f484e7b4bdbe1Dirk Dougherty                    enumOrFlagsComment.append(String16("</p>\n<table>\n"
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                "<colgroup align=\"left\" />\n"
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                "<colgroup align=\"left\" />\n"
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                "<colgroup align=\"left\" />\n"
50659ad275e937bb3c32e59bc01d86f484e7b4bdbe1Dirk Dougherty                                                "<tr><th>Constant</th><th>Value</th><th>Description</th></tr>"));
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
50959ad275e937bb3c32e59bc01d86f484e7b4bdbe1Dirk Dougherty                enumOrFlagsComment.append(String16("\n<tr><td><code>"));
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                enumOrFlagsComment.append(itemIdent);
51159ad275e937bb3c32e59bc01d86f484e7b4bdbe1Dirk Dougherty                enumOrFlagsComment.append(String16("</code></td><td>"));
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                enumOrFlagsComment.append(value);
51359ad275e937bb3c32e59bc01d86f484e7b4bdbe1Dirk Dougherty                enumOrFlagsComment.append(String16("</td><td>"));
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (block.getComment(&len)) {
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    enumOrFlagsComment.append(String16(block.getComment(&len)));
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
51759ad275e937bb3c32e59bc01d86f484e7b4bdbe1Dirk Dougherty                enumOrFlagsComment.append(String16("</td></tr>"));
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                err = outTable->addBag(SourcePos(in->getPrintableSource(), block.getLineNumber()),
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       myPackage,
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       attr16, attr.ident, String16(""),
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       itemIdent, value, NULL, NULL, false, true);
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (err != NO_ERROR) {
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    attr.hasErrors = true;
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (code == ResXMLTree::END_TAG) {
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (strcmp16(block.getElementName(&len), attr16.string()) == 0) {
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if ((attr.type&ResTable_map::TYPE_ENUM) != 0) {
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (strcmp16(block.getElementName(&len), enum16.string()) != 0) {
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    SourcePos(in->getPrintableSource(), block.getLineNumber())
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            .error("Found tag </%s> where </enum> is expected\n",
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            String8(block.getElementName(&len)).string());
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return UNKNOWN_ERROR;
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (strcmp16(block.getElementName(&len), flag16.string()) != 0) {
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    SourcePos(in->getPrintableSource(), block.getLineNumber())
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            .error("Found tag </%s> where </flag> is expected\n",
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            String8(block.getElementName(&len)).string());
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return UNKNOWN_ERROR;
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!attr.hasErrors && attr.added) {
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        appendTypeInfo(outTable, myPackage, attr16, attr.ident, attr.type, gFormatFlags);
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!attr.hasErrors && enumOrFlagsComment.size() > 0) {
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        enumOrFlagsComment.append(String16("\n</table>"));
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        outTable->appendTypeComment(myPackage, attr16, attr.ident, enumOrFlagsComment);
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool localeIsDefined(const ResTable_config& config)
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return config.locale == 0;
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t parseAndAddBag(Bundle* bundle,
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const sp<AaptFile>& in,
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ResXMLTree* block,
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const ResTable_config& config,
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const String16& myPackage,
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const String16& curType,
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const String16& ident,
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const String16& parentIdent,
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const String16& itemIdent,
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        int32_t curFormat,
57715fe2cb73b0770316db302f6502f568062d68e74Kenny Root                        bool isFormatted,
57890964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer                        const String16& product,
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        bool pseudolocalize,
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const bool overwrite,
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ResourceTable* outTable)
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err;
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 item16("item");
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String16 str;
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Vector<StringPool::entry_style_span> spans;
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    err = parseStyledString(bundle, in->getPrintableSource().string(),
58915fe2cb73b0770316db302f6502f568062d68e74Kenny Root                            block, item16, &str, &spans, isFormatted,
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            pseudolocalize);
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != NO_ERROR) {
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return err;
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    NOISY(printf("Adding resource bag entry l=%c%c c=%c%c orien=%d d=%d "
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 " pid=%s, bag=%s, id=%s: %s\n",
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 config.language[0], config.language[1],
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 config.country[0], config.country[1],
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 config.orientation, config.density,
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 String8(parentIdent).string(),
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 String8(ident).string(),
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 String8(itemIdent).string(),
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 String8(str).string()));
6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    err = outTable->addBag(SourcePos(in->getPrintableSource(), block->getLineNumber()),
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           myPackage, curType, ident, parentIdent, itemIdent, str,
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           &spans, &config, overwrite, false, curFormat);
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err;
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
61190964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer/*
61290964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer * Returns true if needle is one of the elements in the comma-separated list
61390964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer * haystack, false otherwise.
61490964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer */
61590964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischerbool isInProductList(const String16& needle, const String16& haystack) {
61690964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer    const char16_t *needle2 = needle.string();
61790964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer    const char16_t *haystack2 = haystack.string();
61890964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer    size_t needlesize = needle.size();
61990964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer
62090964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer    while (*haystack2 != '\0') {
62190964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer        if (strncmp16(haystack2, needle2, needlesize) == 0) {
62290964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer            if (haystack2[needlesize] == '\0' || haystack2[needlesize] == ',') {
62390964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer                return true;
62490964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer            }
62590964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer        }
62690964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer
62790964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer        while (*haystack2 != '\0' && *haystack2 != ',') {
62890964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer            haystack2++;
62990964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer        }
63090964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer        if (*haystack2 == ',') {
63190964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer            haystack2++;
63290964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer        }
63390964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer    }
63490964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer
63590964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer    return false;
63690964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer}
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t parseAndAddEntry(Bundle* bundle,
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const sp<AaptFile>& in,
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ResXMLTree* block,
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const ResTable_config& config,
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const String16& myPackage,
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const String16& curType,
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const String16& ident,
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const String16& curTag,
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        bool curIsStyled,
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        int32_t curFormat,
64815fe2cb73b0770316db302f6502f568062d68e74Kenny Root                        bool isFormatted,
64990964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer                        const String16& product,
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        bool pseudolocalize,
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const bool overwrite,
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ResourceTable* outTable)
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err;
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String16 str;
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Vector<StringPool::entry_style_span> spans;
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    err = parseStyledString(bundle, in->getPrintableSource().string(), block,
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            curTag, &str, curIsStyled ? &spans : NULL,
66015fe2cb73b0770316db302f6502f568062d68e74Kenny Root                            isFormatted, pseudolocalize);
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err < NO_ERROR) {
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return err;
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
66690964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer    /*
66790964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer     * If a product type was specified on the command line
66890964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer     * and also in the string, and the two are not the same,
66990964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer     * return without adding the string.
67090964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer     */
67190964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer
67290964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer    const char *bundleProduct = bundle->getProduct();
67390964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer    if (bundleProduct == NULL) {
67490964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer        bundleProduct = "";
67590964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer    }
67690964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer
67790964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer    if (product.size() != 0) {
67890964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer        /*
67990964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer         * If the command-line-specified product is empty, only "default"
68090964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer         * matches.  Other variants are skipped.  This is so generation
68190964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer         * of the R.java file when the product is not known is predictable.
68290964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer         */
68390964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer
68490964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer        if (bundleProduct[0] == '\0') {
68590964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer            if (strcmp16(String16("default").string(), product.string()) != 0) {
68690964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer                return NO_ERROR;
68790964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer            }
68890964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer        } else {
68990964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer            /*
69090964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer             * The command-line product is not empty.
69190964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer             * If the product for this string is on the command-line list,
69290964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer             * it matches.  "default" also matches, but only if nothing
69390964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer             * else has matched already.
69490964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer             */
69590964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer
69690964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer            if (isInProductList(product, String16(bundleProduct))) {
69790964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer                ;
69890964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer            } else if (strcmp16(String16("default").string(), product.string()) == 0 &&
699914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer                       !outTable->hasBagOrEntry(myPackage, curType, ident, config)) {
70090964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer                ;
70190964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer            } else {
70290964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer                return NO_ERROR;
70390964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer            }
70490964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer        }
70590964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer    }
70690964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    NOISY(printf("Adding resource entry l=%c%c c=%c%c orien=%d d=%d id=%s: %s\n",
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 config.language[0], config.language[1],
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 config.country[0], config.country[1],
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 config.orientation, config.density,
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 String8(ident).string(), String8(str).string()));
7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    err = outTable->addEntry(SourcePos(in->getPrintableSource(), block->getLineNumber()),
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             myPackage, curType, ident, str, &spans, &config,
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             false, curFormat, overwrite);
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err;
7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t compileResourceFile(Bundle* bundle,
7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             const sp<AaptAssets>& assets,
7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             const sp<AaptFile>& in,
7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             const ResTable_config& defParams,
7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             const bool overwrite,
7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             ResourceTable* outTable)
7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ResXMLTree block;
7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = parseXMLResource(in, &block, false, true);
7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != NO_ERROR) {
7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return err;
7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Top-level tag.
7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 resources16("resources");
7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Identifier declaration tags.
7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 declare_styleable16("declare-styleable");
7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 attr16("attr");
7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Data creation organizational tags.
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 string16("string");
7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 drawable16("drawable");
7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 color16("color");
7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 bool16("bool");
7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 integer16("integer");
7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 dimen16("dimen");
7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 fraction16("fraction");
7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 style16("style");
7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 plurals16("plurals");
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 array16("array");
7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 string_array16("string-array");
7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 integer_array16("integer-array");
7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 public16("public");
754f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn    const String16 public_padding16("public-padding");
7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 private_symbols16("private-symbols");
75658c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn    const String16 add_resource16("add-resource");
7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 skip16("skip");
7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 eat_comment16("eat-comment");
7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Data creation tags.
7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 bag16("bag");
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 item16("item");
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Attribute type constants.
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 enum16("enum");
7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // plural values
7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 other16("other");
7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 quantityOther16("^other");
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 zero16("zero");
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 quantityZero16("^zero");
7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 one16("one");
7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 quantityOne16("^one");
7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 two16("two");
7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 quantityTwo16("^two");
7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 few16("few");
7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 quantityFew16("^few");
7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 many16("many");
7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 quantityMany16("^many");
7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // useful attribute names and special values
7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 name16("name");
7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 translatable16("translatable");
78415fe2cb73b0770316db302f6502f568062d68e74Kenny Root    const String16 formatted16("formatted");
7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 false16("false");
7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 myPackage(assets->getPackage());
7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool hasErrors = false;
79015fe2cb73b0770316db302f6502f568062d68e74Kenny Root
79115fe2cb73b0770316db302f6502f568062d68e74Kenny Root    bool fileIsTranslatable = true;
79215fe2cb73b0770316db302f6502f568062d68e74Kenny Root    if (strstr(in->getPrintableSource().string(), "donottranslate") != NULL) {
79315fe2cb73b0770316db302f6502f568062d68e74Kenny Root        fileIsTranslatable = false;
79415fe2cb73b0770316db302f6502f568062d68e74Kenny Root    }
79515fe2cb73b0770316db302f6502f568062d68e74Kenny Root
796f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn    DefaultKeyedVector<String16, uint32_t> nextPublicId(0);
7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ResXMLTree::event_code_t code;
7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    do {
8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        code = block.next();
8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } while (code == ResXMLTree::START_NAMESPACE);
8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t len;
8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (code != ResXMLTree::START_TAG) {
8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "No start tag found\n");
8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (strcmp16(block.getElementName(&len), resources16.string()) != 0) {
8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "Invalid start tag %s\n", String8(block.getElementName(&len)).string());
8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ResTable_config curParams(defParams);
8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ResTable_config pseudoParams(curParams);
8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pseudoParams.language[0] = 'z';
8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pseudoParams.language[1] = 'z';
8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pseudoParams.country[0] = 'Z';
8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pseudoParams.country[1] = 'Z';
8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (code == ResXMLTree::START_TAG) {
8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const String16* curTag = NULL;
8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String16 curType;
8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int32_t curFormat = ResTable_map::TYPE_ANY;
8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bool curIsBag = false;
8291aa8170e6a448afad86e5d62927d3b8ca4cd9707Robert Greenwalt            bool curIsBagReplaceOnOverwrite = false;
8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bool curIsStyled = false;
8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bool curIsPseudolocalizable = false;
83215fe2cb73b0770316db302f6502f568062d68e74Kenny Root            bool curIsFormatted = fileIsTranslatable;
8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bool localHasErrors = false;
8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {
8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                while ((code=block.next()) != ResXMLTree::END_DOCUMENT
8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        && code != ResXMLTree::BAD_DOCUMENT) {
8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (code == ResXMLTree::END_TAG) {
8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {
8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            break;
8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) {
8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                while ((code=block.next()) != ResXMLTree::END_DOCUMENT
8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        && code != ResXMLTree::BAD_DOCUMENT) {
8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (code == ResXMLTree::END_TAG) {
8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) {
8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            break;
8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), public16.string()) == 0) {
8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());
8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String16 type;
8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ssize_t typeIdx = block.indexOfAttribute(NULL, "type");
8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (typeIdx < 0) {
8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    srcPos.error("A 'type' attribute is required for <public>\n");
8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hasErrors = localHasErrors = true;
8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                type = String16(block.getAttributeStringValue(typeIdx, &len));
8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String16 name;
8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ssize_t nameIdx = block.indexOfAttribute(NULL, "name");
8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (nameIdx < 0) {
8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    srcPos.error("A 'name' attribute is required for <public>\n");
8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hasErrors = localHasErrors = true;
8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                name = String16(block.getAttributeStringValue(nameIdx, &len));
8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                uint32_t ident = 0;
8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ssize_t identIdx = block.indexOfAttribute(NULL, "id");
8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (identIdx >= 0) {
8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    const char16_t* identStr = block.getAttributeStringValue(identIdx, &len);
8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Res_value identValue;
8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (!ResTable::stringToInt(identStr, len, &identValue)) {
8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        srcPos.error("Given 'id' attribute is not an integer: %s\n",
8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                String8(block.getAttributeStringValue(identIdx, &len)).string());
8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        hasErrors = localHasErrors = true;
8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else {
8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ident = identValue.data;
887f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        nextPublicId.replaceValueFor(type, ident+1);
8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
889f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                } else if (nextPublicId.indexOfKey(type) < 0) {
8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    srcPos.error("No 'id' attribute supplied <public>,"
8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            " and no previous id defined in this file.\n");
8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hasErrors = localHasErrors = true;
8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (!localHasErrors) {
894f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    ident = nextPublicId.valueFor(type);
895f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    nextPublicId.replaceValueFor(type, ident+1);
8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!localHasErrors) {
8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    err = outTable->addPublic(srcPos, myPackage, type, name, ident);
9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (err < NO_ERROR) {
9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        hasErrors = localHasErrors = true;
9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!localHasErrors) {
9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R"));
9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (symbols != NULL) {
9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        symbols = symbols->addNestedSymbol(String8(type), srcPos);
9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (symbols != NULL) {
9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        symbols->makeSymbolPublic(String8(name), srcPos);
9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String16 comment(
9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            block.getComment(&len) ? block.getComment(&len) : nulStr);
9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        symbols->appendComment(String8(name), comment, srcPos);
9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else {
9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        srcPos.error("Unable to create symbols!\n");
9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        hasErrors = localHasErrors = true;
9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (code == ResXMLTree::END_TAG) {
9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (strcmp16(block.getElementName(&len), public16.string()) == 0) {
9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            break;
9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
929f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn            } else if (strcmp16(block.getElementName(&len), public_padding16.string()) == 0) {
930f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());
931f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn
932f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                String16 type;
933f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                ssize_t typeIdx = block.indexOfAttribute(NULL, "type");
934f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                if (typeIdx < 0) {
935f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    srcPos.error("A 'type' attribute is required for <public-padding>\n");
936f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    hasErrors = localHasErrors = true;
937f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                }
938f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                type = String16(block.getAttributeStringValue(typeIdx, &len));
939f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn
940f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                String16 name;
941f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                ssize_t nameIdx = block.indexOfAttribute(NULL, "name");
942f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                if (nameIdx < 0) {
943f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    srcPos.error("A 'name' attribute is required for <public-padding>\n");
944f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    hasErrors = localHasErrors = true;
945f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                }
946f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                name = String16(block.getAttributeStringValue(nameIdx, &len));
947f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn
948f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                uint32_t start = 0;
949f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                ssize_t startIdx = block.indexOfAttribute(NULL, "start");
950f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                if (startIdx >= 0) {
951f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    const char16_t* startStr = block.getAttributeStringValue(startIdx, &len);
952f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    Res_value startValue;
953f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    if (!ResTable::stringToInt(startStr, len, &startValue)) {
954f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        srcPos.error("Given 'start' attribute is not an integer: %s\n",
955f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                                String8(block.getAttributeStringValue(startIdx, &len)).string());
956f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        hasErrors = localHasErrors = true;
957f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    } else {
958f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        start = startValue.data;
959f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    }
960f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                } else if (nextPublicId.indexOfKey(type) < 0) {
961f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    srcPos.error("No 'start' attribute supplied <public-padding>,"
962f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                            " and no previous id defined in this file.\n");
963f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    hasErrors = localHasErrors = true;
964f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                } else if (!localHasErrors) {
965f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    start = nextPublicId.valueFor(type);
966f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                }
967f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn
968f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                uint32_t end = 0;
969f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                ssize_t endIdx = block.indexOfAttribute(NULL, "end");
970f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                if (endIdx >= 0) {
971f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    const char16_t* endStr = block.getAttributeStringValue(endIdx, &len);
972f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    Res_value endValue;
973f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    if (!ResTable::stringToInt(endStr, len, &endValue)) {
974f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        srcPos.error("Given 'end' attribute is not an integer: %s\n",
975f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                                String8(block.getAttributeStringValue(endIdx, &len)).string());
976f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        hasErrors = localHasErrors = true;
977f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    } else {
978f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        end = endValue.data;
979f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    }
980f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                } else {
981f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    srcPos.error("No 'end' attribute supplied <public-padding>\n");
982f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    hasErrors = localHasErrors = true;
983f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                }
984f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn
985f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                if (end >= start) {
986f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    nextPublicId.replaceValueFor(type, end+1);
987f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                } else {
988f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    srcPos.error("Padding start '%ul' is after end '%ul'\n",
989f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                            start, end);
990f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    hasErrors = localHasErrors = true;
991f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                }
992f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn
993f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                String16 comment(
994f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    block.getComment(&len) ? block.getComment(&len) : nulStr);
995f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                for (uint32_t curIdent=start; curIdent<=end; curIdent++) {
996f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    if (localHasErrors) {
997f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        break;
998f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    }
999f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    String16 curName(name);
1000f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    char buf[64];
1001f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    sprintf(buf, "%d", (int)(end-curIdent+1));
1002f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    curName.append(String16(buf));
1003f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn
1004f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    err = outTable->addEntry(srcPos, myPackage, type, curName,
1005f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                                             String16("padding"), NULL, &curParams, false,
1006f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                                             ResTable_map::TYPE_STRING, overwrite);
1007f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    if (err < NO_ERROR) {
1008f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        hasErrors = localHasErrors = true;
1009f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        break;
1010f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    }
1011f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    err = outTable->addPublic(srcPos, myPackage, type,
1012f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                            curName, curIdent);
1013f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    if (err < NO_ERROR) {
1014f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        hasErrors = localHasErrors = true;
1015f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        break;
1016f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    }
1017f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R"));
1018f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    if (symbols != NULL) {
1019f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        symbols = symbols->addNestedSymbol(String8(type), srcPos);
1020f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    }
1021f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    if (symbols != NULL) {
1022f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        symbols->makeSymbolPublic(String8(curName), srcPos);
1023f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        symbols->appendComment(String8(curName), comment, srcPos);
1024f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    } else {
1025f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        srcPos.error("Unable to create symbols!\n");
1026f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        hasErrors = localHasErrors = true;
1027f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    }
1028f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                }
1029f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn
1030f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
1031f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    if (code == ResXMLTree::END_TAG) {
1032f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        if (strcmp16(block.getElementName(&len), public_padding16.string()) == 0) {
1033f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                            break;
1034f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        }
1035f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    }
1036f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                }
1037f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                continue;
1038f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn
10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), private_symbols16.string()) == 0) {
10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String16 pkg;
10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ssize_t pkgIdx = block.indexOfAttribute(NULL, "package");
10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (pkgIdx < 0) {
10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            "A 'package' attribute is required for <private-symbols>\n");
10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hasErrors = localHasErrors = true;
10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pkg = String16(block.getAttributeStringValue(pkgIdx, &len));
10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!localHasErrors) {
10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    assets->setSymbolsPrivatePackage(String8(pkg));
10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (code == ResXMLTree::END_TAG) {
10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (strcmp16(block.getElementName(&len), private_symbols16.string()) == 0) {
10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            break;
10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
106158c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn            } else if (strcmp16(block.getElementName(&len), add_resource16.string()) == 0) {
106258c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());
106358c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn
106458c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                String16 typeName;
106558c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                ssize_t typeIdx = block.indexOfAttribute(NULL, "type");
106658c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                if (typeIdx < 0) {
106758c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                    srcPos.error("A 'type' attribute is required for <add-resource>\n");
106858c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                    hasErrors = localHasErrors = true;
106958c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                }
107058c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                typeName = String16(block.getAttributeStringValue(typeIdx, &len));
107158c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn
107258c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                String16 name;
107358c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                ssize_t nameIdx = block.indexOfAttribute(NULL, "name");
107458c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                if (nameIdx < 0) {
107558c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                    srcPos.error("A 'name' attribute is required for <add-resource>\n");
107658c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                    hasErrors = localHasErrors = true;
107758c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                }
107858c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                name = String16(block.getAttributeStringValue(nameIdx, &len));
107958c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn
108058c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                outTable->canAddEntry(srcPos, myPackage, typeName, name);
108158c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn
108258c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
108358c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                    if (code == ResXMLTree::END_TAG) {
108493d72516994277acdd3894a169ec1f1cbc50db97Robert Greenwalt                        if (strcmp16(block.getElementName(&len), add_resource16.string()) == 0) {
108558c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                            break;
108658c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                        }
108758c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                    }
108858c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                }
108958c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                continue;
109058c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn
10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), declare_styleable16.string()) == 0) {
10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());
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                    srcPos.error("A 'name' attribute is required for <declare-styleable>\n");
10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hasErrors = localHasErrors = true;
10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ident = String16(block.getAttributeStringValue(identIdx, &len));
11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R"));
11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!localHasErrors) {
11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (symbols != NULL) {
11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        symbols = symbols->addNestedSymbol(String8("styleable"), srcPos);
11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sp<AaptSymbols> styleSymbols = symbols;
11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (symbols != NULL) {
11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        symbols = symbols->addNestedSymbol(String8(ident), srcPos);
11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (symbols == NULL) {
11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        srcPos.error("Unable to create symbols!\n");
11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        return UNKNOWN_ERROR;
11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String16 comment(
11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        block.getComment(&len) ? block.getComment(&len) : nulStr);
11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    styleSymbols->appendComment(String8(ident), comment, srcPos);
11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    symbols = NULL;
11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (code == ResXMLTree::START_TAG) {
11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {
11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            while ((code=block.next()) != ResXMLTree::END_DOCUMENT
11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                   && code != ResXMLTree::BAD_DOCUMENT) {
11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                if (code == ResXMLTree::END_TAG) {
11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {
11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        break;
11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    }
11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                }
11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            continue;
11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } else if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) {
11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            while ((code=block.next()) != ResXMLTree::END_DOCUMENT
11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                   && code != ResXMLTree::BAD_DOCUMENT) {
11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                if (code == ResXMLTree::END_TAG) {
11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) {
11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        break;
11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    }
11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                }
11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            continue;
11459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } else if (strcmp16(block.getElementName(&len), attr16.string()) != 0) {
11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    "Tag <%s> can not appear inside <declare-styleable>, only <attr>\n",
11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    String8(block.getElementName(&len)).string());
11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            return UNKNOWN_ERROR;
11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String16 comment(
11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            block.getComment(&len) ? block.getComment(&len) : nulStr);
11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String16 itemIdent;
11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        err = compileAttribute(in, block, myPackage, outTable, &itemIdent, true);
11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (err != NO_ERROR) {
11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            hasErrors = localHasErrors = true;
11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (symbols != NULL) {
11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            SourcePos srcPos(String8(in->getPrintableSource()), block.getLineNumber());
11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            symbols->addSymbol(String8(itemIdent), 0, srcPos);
11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            symbols->appendComment(String8(itemIdent), comment, srcPos);
11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            //printf("Attribute %s comment: %s\n", String8(itemIdent).string(),
11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            //     String8(comment).string());
11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else if (code == ResXMLTree::END_TAG) {
11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (strcmp16(block.getElementName(&len), declare_styleable16.string()) == 0) {
11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            break;
11709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                "Found tag </%s> where </attr> is expected\n",
11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                String8(block.getElementName(&len)).string());
11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        return UNKNOWN_ERROR;
11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), attr16.string()) == 0) {
11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                err = compileAttribute(in, block, myPackage, outTable, NULL);
11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (err != NO_ERROR) {
11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hasErrors = true;
11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), item16.string()) == 0) {
11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &item16;
11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ssize_t attri = block.indexOfAttribute(NULL, "type");
11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (attri >= 0) {
11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    curType = String16(block.getAttributeStringValue(attri, &len));
11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ssize_t formatIdx = block.indexOfAttribute(NULL, "format");
11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (formatIdx >= 0) {
11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String16 formatStr = String16(block.getAttributeStringValue(
11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                formatIdx, &len));
11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        curFormat = parse_flags(formatStr.string(), formatStr.size(),
11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                gFormatFlags);
11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (curFormat == 0) {
11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    "Tag <item> 'format' attribute value \"%s\" not valid\n",
12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    String8(formatStr).string());
12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            hasErrors = localHasErrors = true;
12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            "A 'type' attribute is required for <item>\n");
12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hasErrors = localHasErrors = true;
12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curIsStyled = true;
12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), string16.string()) == 0) {
12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Note the existence and locale of every string we process
12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                char rawLocale[16];
12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curParams.getLocale(rawLocale);
12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String8 locale(rawLocale);
12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String16 name;
12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String16 translatable;
121815fe2cb73b0770316db302f6502f568062d68e74Kenny Root                String16 formatted;
12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                size_t n = block.getAttributeCount();
12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (size_t i = 0; i < n; i++) {
12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    size_t length;
12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    const uint16_t* attr = block.getAttributeName(i, &length);
12249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (strcmp16(attr, name16.string()) == 0) {
12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        name.setTo(block.getAttributeStringValue(i, &length));
12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else if (strcmp16(attr, translatable16.string()) == 0) {
12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        translatable.setTo(block.getAttributeStringValue(i, &length));
122815fe2cb73b0770316db302f6502f568062d68e74Kenny Root                    } else if (strcmp16(attr, formatted16.string()) == 0) {
122915fe2cb73b0770316db302f6502f568062d68e74Kenny Root                        formatted.setTo(block.getAttributeStringValue(i, &length));
12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
12319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (name.size() > 0) {
12349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (translatable == false16) {
123515fe2cb73b0770316db302f6502f568062d68e74Kenny Root                        curIsFormatted = false;
12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // Untranslatable strings must only exist in the default [empty] locale
12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (locale.size() > 0) {
12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            fprintf(stderr, "aapt: warning: string '%s' in %s marked untranslatable but exists"
12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    " in locale '%s'\n", String8(name).string(),
12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    bundle->getResourceSourceDirs()[0],
12419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    locale.string());
12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            // hasErrors = localHasErrors = true;
12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } else {
12449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            // Intentionally empty block:
12459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            //
12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            // Don't add untranslatable strings to the localization table; that
12479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            // way if we later see localizations of them, they'll be flagged as
12489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            // having no default translation.
12499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
12509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else {
12519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        outTable->addLocalization(name, locale);
12529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
125315fe2cb73b0770316db302f6502f568062d68e74Kenny Root
125415fe2cb73b0770316db302f6502f568062d68e74Kenny Root                    if (formatted == false16) {
125515fe2cb73b0770316db302f6502f568062d68e74Kenny Root                        curIsFormatted = false;
125615fe2cb73b0770316db302f6502f568062d68e74Kenny Root                    }
12579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
12589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &string16;
12609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curType = string16;
12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_STRING;
12629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curIsStyled = true;
12639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curIsPseudolocalizable = true;
12649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), drawable16.string()) == 0) {
12659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &drawable16;
12669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curType = drawable16;
12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_COLOR;
12689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), color16.string()) == 0) {
12699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &color16;
12709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curType = color16;
12719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_COLOR;
12729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), bool16.string()) == 0) {
12739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &bool16;
12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curType = bool16;
12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_BOOLEAN;
12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), integer16.string()) == 0) {
12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &integer16;
12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curType = integer16;
12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_INTEGER;
12809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), dimen16.string()) == 0) {
12819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &dimen16;
12829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curType = dimen16;
12839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_DIMENSION;
12849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), fraction16.string()) == 0) {
12859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &fraction16;
12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curType = fraction16;
12879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_FRACTION;
12889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), bag16.string()) == 0) {
12899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &bag16;
12909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curIsBag = true;
12919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ssize_t attri = block.indexOfAttribute(NULL, "type");
12929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (attri >= 0) {
12939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    curType = String16(block.getAttributeStringValue(attri, &len));
12949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            "A 'type' attribute is required for <bag>\n");
12979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hasErrors = localHasErrors = true;
12989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
12999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), style16.string()) == 0) {
13009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &style16;
13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curType = style16;
13029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curIsBag = true;
13039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), plurals16.string()) == 0) {
13049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &plurals16;
13059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curType = plurals16;
13069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curIsBag = true;
13079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), array16.string()) == 0) {
13089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &array16;
13099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curType = array16;
13109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curIsBag = true;
13111aa8170e6a448afad86e5d62927d3b8ca4cd9707Robert Greenwalt                curIsBagReplaceOnOverwrite = true;
13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ssize_t formatIdx = block.indexOfAttribute(NULL, "format");
13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (formatIdx >= 0) {
13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String16 formatStr = String16(block.getAttributeStringValue(
13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            formatIdx, &len));
13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    curFormat = parse_flags(formatStr.string(), formatStr.size(),
13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                            gFormatFlags);
13189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (curFormat == 0) {
13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
13209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                "Tag <array> 'format' attribute value \"%s\" not valid\n",
13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                String8(formatStr).string());
13229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        hasErrors = localHasErrors = true;
13239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
13249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
13259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), string_array16.string()) == 0) {
132602feeb4b2bb6515491cf3dd7ae2b204caac81baeJosh Stone                // Check whether these strings need valid formats.
132702feeb4b2bb6515491cf3dd7ae2b204caac81baeJosh Stone                // (simplified form of what string16 does above)
132802feeb4b2bb6515491cf3dd7ae2b204caac81baeJosh Stone                size_t n = block.getAttributeCount();
132902feeb4b2bb6515491cf3dd7ae2b204caac81baeJosh Stone                for (size_t i = 0; i < n; i++) {
133002feeb4b2bb6515491cf3dd7ae2b204caac81baeJosh Stone                    size_t length;
133102feeb4b2bb6515491cf3dd7ae2b204caac81baeJosh Stone                    const uint16_t* attr = block.getAttributeName(i, &length);
133202feeb4b2bb6515491cf3dd7ae2b204caac81baeJosh Stone                    if (strcmp16(attr, translatable16.string()) == 0
133302feeb4b2bb6515491cf3dd7ae2b204caac81baeJosh Stone                            || strcmp16(attr, formatted16.string()) == 0) {
133402feeb4b2bb6515491cf3dd7ae2b204caac81baeJosh Stone                        const uint16_t* value = block.getAttributeStringValue(i, &length);
133502feeb4b2bb6515491cf3dd7ae2b204caac81baeJosh Stone                        if (strcmp16(value, false16.string()) == 0) {
133602feeb4b2bb6515491cf3dd7ae2b204caac81baeJosh Stone                            curIsFormatted = false;
133702feeb4b2bb6515491cf3dd7ae2b204caac81baeJosh Stone                            break;
133802feeb4b2bb6515491cf3dd7ae2b204caac81baeJosh Stone                        }
133902feeb4b2bb6515491cf3dd7ae2b204caac81baeJosh Stone                    }
134002feeb4b2bb6515491cf3dd7ae2b204caac81baeJosh Stone                }
134102feeb4b2bb6515491cf3dd7ae2b204caac81baeJosh Stone
13429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &string_array16;
13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curType = array16;
13449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_STRING;
13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curIsBag = true;
13461aa8170e6a448afad86e5d62927d3b8ca4cd9707Robert Greenwalt                curIsBagReplaceOnOverwrite = true;
13479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curIsPseudolocalizable = true;
13489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), integer_array16.string()) == 0) {
13499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &integer_array16;
13509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curType = array16;
13519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_INTEGER;
13529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curIsBag = true;
13531aa8170e6a448afad86e5d62927d3b8ca4cd9707Robert Greenwalt                curIsBagReplaceOnOverwrite = true;
13549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
13559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
13569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        "Found tag %s where item is expected\n",
13579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String8(block.getElementName(&len)).string());
13589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return UNKNOWN_ERROR;
13599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
13609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String16 ident;
13629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ssize_t identIdx = block.indexOfAttribute(NULL, "name");
13639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (identIdx >= 0) {
13649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ident = String16(block.getAttributeStringValue(identIdx, &len));
13659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
13669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
13679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        "A 'name' attribute is required for <%s>\n",
13689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String8(*curTag).string());
13699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                hasErrors = localHasErrors = true;
13709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
13719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1372407f625a9b8e356e765a5ec587c443af1f3aadb5Dianne Hackborn            String16 product;
1373407f625a9b8e356e765a5ec587c443af1f3aadb5Dianne Hackborn            identIdx = block.indexOfAttribute(NULL, "product");
1374407f625a9b8e356e765a5ec587c443af1f3aadb5Dianne Hackborn            if (identIdx >= 0) {
1375407f625a9b8e356e765a5ec587c443af1f3aadb5Dianne Hackborn                product = String16(block.getAttributeStringValue(identIdx, &len));
1376407f625a9b8e356e765a5ec587c443af1f3aadb5Dianne Hackborn            }
1377407f625a9b8e356e765a5ec587c443af1f3aadb5Dianne Hackborn
13789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String16 comment(block.getComment(&len) ? block.getComment(&len) : nulStr);
13799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (curIsBag) {
13819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Figure out the parent of this bag...
13829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String16 parentIdent;
13839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ssize_t parentIdentIdx = block.indexOfAttribute(NULL, "parent");
13849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (parentIdentIdx >= 0) {
13859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    parentIdent = String16(block.getAttributeStringValue(parentIdentIdx, &len));
13869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
13879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ssize_t sep = ident.findLast('.');
13889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (sep >= 0) {
13899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        parentIdent.setTo(ident, sep);
13909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
13919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
13929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!localHasErrors) {
13941aa8170e6a448afad86e5d62927d3b8ca4cd9707Robert Greenwalt                    err = outTable->startBag(SourcePos(in->getPrintableSource(),
13951aa8170e6a448afad86e5d62927d3b8ca4cd9707Robert Greenwalt                            block.getLineNumber()), myPackage, curType, ident,
13961aa8170e6a448afad86e5d62927d3b8ca4cd9707Robert Greenwalt                            parentIdent, &curParams,
13971aa8170e6a448afad86e5d62927d3b8ca4cd9707Robert Greenwalt                            overwrite, curIsBagReplaceOnOverwrite);
13989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (err != NO_ERROR) {
13999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        hasErrors = localHasErrors = true;
14009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
14019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
14029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ssize_t elmIndex = 0;
14049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                char elmIndexStr[14];
14059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                while ((code=block.next()) != ResXMLTree::END_DOCUMENT
14069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        && code != ResXMLTree::BAD_DOCUMENT) {
14079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (code == ResXMLTree::START_TAG) {
14099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (strcmp16(block.getElementName(&len), item16.string()) != 0) {
14109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
14119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    "Tag <%s> can not appear inside <%s>, only <item>\n",
14129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    String8(block.getElementName(&len)).string(),
14139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    String8(*curTag).string());
14149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            return UNKNOWN_ERROR;
14159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
14169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String16 itemIdent;
14189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (curType == array16) {
14199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            sprintf(elmIndexStr, "^index_%d", (int)elmIndex++);
14209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            itemIdent = String16(elmIndexStr);
14219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } else if (curType == plurals16) {
14229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            ssize_t itemIdentIdx = block.indexOfAttribute(NULL, "quantity");
14239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            if (itemIdentIdx >= 0) {
14249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                String16 quantity16(block.getAttributeStringValue(itemIdentIdx, &len));
14259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                if (quantity16 == other16) {
14269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    itemIdent = quantityOther16;
14279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                }
14289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                else if (quantity16 == zero16) {
14299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    itemIdent = quantityZero16;
14309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                }
14319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                else if (quantity16 == one16) {
14329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    itemIdent = quantityOne16;
14339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                }
14349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                else if (quantity16 == two16) {
14359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    itemIdent = quantityTwo16;
14369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                }
14379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                else if (quantity16 == few16) {
14389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    itemIdent = quantityFew16;
14399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                }
14409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                else if (quantity16 == many16) {
14419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    itemIdent = quantityMany16;
14429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                }
14439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                else {
14449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
14459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                            "Illegal 'quantity' attribute is <item> inside <plurals>\n");
14469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    hasErrors = localHasErrors = true;
14479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                }
14489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            } else {
14499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
14509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        "A 'quantity' attribute is required for <item> inside <plurals>\n");
14519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                hasErrors = localHasErrors = true;
14529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
14539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } else {
14549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            ssize_t itemIdentIdx = block.indexOfAttribute(NULL, "name");
14559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            if (itemIdentIdx >= 0) {
14569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                itemIdent = String16(block.getAttributeStringValue(itemIdentIdx, &len));
14579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            } else {
14589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
14599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        "A 'name' attribute is required for <item>\n");
14609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                hasErrors = localHasErrors = true;
14619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
14629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
14639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ResXMLParser::ResXMLPosition parserPosition;
14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        block.getPosition(&parserPosition);
14669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        err = parseAndAddBag(bundle, in, &block, curParams, myPackage, curType,
146815fe2cb73b0770316db302f6502f568062d68e74Kenny Root                                ident, parentIdent, itemIdent, curFormat, curIsFormatted,
1469407f625a9b8e356e765a5ec587c443af1f3aadb5Dianne Hackborn                                product, false, overwrite, outTable);
14709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (err == NO_ERROR) {
14719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            if (curIsPseudolocalizable && localeIsDefined(curParams)
14729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    && bundle->getPseudolocalize()) {
14739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                // pseudolocalize here
14749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 1
14759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                block.setPosition(parserPosition);
14769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                err = parseAndAddBag(bundle, in, &block, pseudoParams, myPackage,
147715fe2cb73b0770316db302f6502f568062d68e74Kenny Root                                        curType, ident, parentIdent, itemIdent, curFormat,
1478407f625a9b8e356e765a5ec587c443af1f3aadb5Dianne Hackborn                                        curIsFormatted, product, true, overwrite, outTable);
14799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
14809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
14819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
14829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (err != NO_ERROR) {
14839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            hasErrors = localHasErrors = true;
14849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
14859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else if (code == ResXMLTree::END_TAG) {
14869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (strcmp16(block.getElementName(&len), curTag->string()) != 0) {
14879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
14889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    "Found tag </%s> where </%s> is expected\n",
14899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    String8(block.getElementName(&len)).string(),
14909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    String8(*curTag).string());
14919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            return UNKNOWN_ERROR;
14929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
14939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        break;
14949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
14959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
14969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
14979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ResXMLParser::ResXMLPosition parserPosition;
14989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                block.getPosition(&parserPosition);
14999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                err = parseAndAddEntry(bundle, in, &block, curParams, myPackage, curType, ident,
150115fe2cb73b0770316db302f6502f568062d68e74Kenny Root                        *curTag, curIsStyled, curFormat, curIsFormatted,
1502407f625a9b8e356e765a5ec587c443af1f3aadb5Dianne Hackborn                        product, false, overwrite, outTable);
15039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (err < NO_ERROR) { // Why err < NO_ERROR instead of err != NO_ERROR?
15059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hasErrors = localHasErrors = true;
15069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
15079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                else if (err == NO_ERROR) {
15089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (curIsPseudolocalizable && localeIsDefined(curParams)
15099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            && bundle->getPseudolocalize()) {
15109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // pseudolocalize here
15119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        block.setPosition(parserPosition);
15129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        err = parseAndAddEntry(bundle, in, &block, pseudoParams, myPackage, curType,
151315fe2cb73b0770316db302f6502f568062d68e74Kenny Root                                ident, *curTag, curIsStyled, curFormat,
1514407f625a9b8e356e765a5ec587c443af1f3aadb5Dianne Hackborn                                curIsFormatted, product,
151590964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer                                true, overwrite, outTable);
15169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (err != NO_ERROR) {
15179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            hasErrors = localHasErrors = true;
15189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
15199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
15209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
15219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
15229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 0
15249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (comment.size() > 0) {
15259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                printf("Comment for @%s:%s/%s: %s\n", String8(myPackage).string(),
15269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                       String8(curType).string(), String8(ident).string(),
15279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                       String8(comment).string());
15289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
15299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
15309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!localHasErrors) {
15319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                outTable->appendComment(myPackage, curType, ident, comment, false);
15329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
15339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        else if (code == ResXMLTree::END_TAG) {
15359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (strcmp16(block.getElementName(&len), resources16.string()) != 0) {
15369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
15379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        "Unexpected end tag %s\n", String8(block.getElementName(&len)).string());
15389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return UNKNOWN_ERROR;
15399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
15409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        else if (code == ResXMLTree::START_NAMESPACE || code == ResXMLTree::END_NAMESPACE) {
15429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        else if (code == ResXMLTree::TEXT) {
15449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (isWhitespace(block.getText(&len))) {
15459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
15469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
15479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
15489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    "Found text \"%s\" where item tag is expected\n",
15499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(block.getText(&len)).string());
15509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return UNKNOWN_ERROR;
15519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
15559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
15569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResourceTable::ResourceTable(Bundle* bundle, const String16& assetsPackage)
15589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    : mAssetsPackage(assetsPackage), mNextPackageId(1), mHaveAppPackage(false),
15599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      mIsAppPackage(!bundle->getExtending()),
15609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      mNumLocal(0),
15619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      mBundle(bundle)
15629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
15639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
15649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::addIncludedResources(Bundle* bundle, const sp<AaptAssets>& assets)
15669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
15679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = assets->buildIncludedResources(bundle);
15689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != NO_ERROR) {
15699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return err;
15709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // For future reference to included resources.
15739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mAssets = assets;
15749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const ResTable& incl = assets->getIncludedResources();
15769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Retrieve all the packages.
15789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t N = incl.getBasePackageCount();
15799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (size_t phase=0; phase<2; phase++) {
15809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (size_t i=0; i<N; i++) {
15819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String16 name(incl.getBasePackageName(i));
15829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            uint32_t id = incl.getBasePackageId(i);
15839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // First time through: only add base packages (id
15849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // is not 0); second time through add the other
15859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // packages.
15869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (phase != 0) {
15879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (id != 0) {
15889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Skip base packages -- already one.
15899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    id = 0;
15909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
15919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Assign a dynamic id.
15929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    id = mNextPackageId;
15939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
15949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (id != 0) {
15959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (id == 127) {
15969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (mHaveAppPackage) {
1597a96cbb435d7b2197ab2b61fd98d14cbd6e0c5c3dDianne Hackborn                        fprintf(stderr, "Included resources have two application packages!\n");
15989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        return UNKNOWN_ERROR;
15999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
16009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mHaveAppPackage = true;
16019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
16029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mNextPackageId > id) {
16039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    fprintf(stderr, "Included base package ID %d already in use!\n", id);
16049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return UNKNOWN_ERROR;
16059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
16069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
16079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (id != 0) {
16089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                NOISY(printf("Including package %s with ID=%d\n",
16099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             String8(name).string(), id));
16109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sp<Package> p = new Package(name, id);
16119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mPackages.add(name, p);
16129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mOrderedPackages.add(p);
16139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (id >= mNextPackageId) {
16159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mNextPackageId = id+1;
16169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
16179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
16189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Every resource table always has one first entry, the bag attributes.
16229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const SourcePos unknown(String8("????"), 0);
16239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Type> attr = getType(mAssetsPackage, String16("attr"), unknown);
16249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
16269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
16279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::addPublic(const SourcePos& sourcePos,
16299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const String16& package,
16309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const String16& type,
16319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const String16& name,
16329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const uint32_t ident)
16339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
16349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t rid = mAssets->getIncludedResources()
16359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        .identifierForName(name.string(), name.size(),
16369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           type.string(), type.size(),
16379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           package.string(), package.size());
16389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (rid != 0) {
16399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sourcePos.error("Error declaring public resource %s/%s for included package %s\n",
16409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String8(type).string(), String8(name).string(),
16419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String8(package).string());
16429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
16439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Type> t = getType(package, type, sourcePos);
16469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (t == NULL) {
16479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
16489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return t->addPublic(sourcePos, name, ident);
16509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
16519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::addEntry(const SourcePos& sourcePos,
16539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16& package,
16549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16& type,
16559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16& name,
16569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16& value,
16579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const Vector<StringPool::entry_style_span>* style,
16589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const ResTable_config* params,
16599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const bool doSetIndex,
16609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const int32_t format,
16619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const bool overwrite)
16629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
16639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Check for adding entries in other packages...  for now we do
16649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // nothing.  We need to do the right thing here to support skinning.
16659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t rid = mAssets->getIncludedResources()
16669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        .identifierForName(name.string(), name.size(),
16679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           type.string(), type.size(),
16689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           package.string(), package.size());
16699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (rid != 0) {
16709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NO_ERROR;
16719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 0
16749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (name == String16("left")) {
16759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        printf("Adding entry left: file=%s, line=%d, type=%s, value=%s\n",
16769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project               sourcePos.file.string(), sourcePos.line, String8(type).string(),
16779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project               String8(value).string());
16789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
1680f878e2d80c3a0afefe3b018d232df6066379e1d5Robert Greenwalt
1681f878e2d80c3a0afefe3b018d232df6066379e1d5Robert Greenwalt    sp<Entry> e = getEntry(package, type, name, sourcePos, overwrite,
1682f878e2d80c3a0afefe3b018d232df6066379e1d5Robert Greenwalt                           params, doSetIndex);
16839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (e == NULL) {
16849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
16859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = e->setItem(sourcePos, value, style, format, overwrite);
16879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err == NO_ERROR) {
16889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mNumLocal++;
16899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err;
16919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
16929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::startBag(const SourcePos& sourcePos,
16949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16& package,
16959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16& type,
16969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16& name,
16979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16& bagParent,
16989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const ResTable_config* params,
16991aa8170e6a448afad86e5d62927d3b8ca4cd9707Robert Greenwalt                                 bool overlay,
17009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 bool replace, bool isId)
17019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
17024b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt    status_t result = NO_ERROR;
17034b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt
17049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Check for adding entries in other packages...  for now we do
17059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // nothing.  We need to do the right thing here to support skinning.
17069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t rid = mAssets->getIncludedResources()
17079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    .identifierForName(name.string(), name.size(),
17089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                       type.string(), type.size(),
17099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                       package.string(), package.size());
17109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (rid != 0) {
17119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NO_ERROR;
17129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 0
17159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (name == String16("left")) {
17169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        printf("Adding bag left: file=%s, line=%d, type=%s\n",
17179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project               sourcePos.file.striing(), sourcePos.line, String8(type).string());
17189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
172099080c7d9ad9e5ccfec70dd10e4c24468a960c45Xavier Ducrohet    if (overlay && !mBundle->getAutoAddOverlay() && !hasBagOrEntry(package, type, name)) {
172158c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn        bool canAdd = false;
172258c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn        sp<Package> p = mPackages.valueFor(package);
172358c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn        if (p != NULL) {
172458c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn            sp<Type> t = p->getTypes().valueFor(type);
172558c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn            if (t != NULL) {
172658c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                if (t->getCanAddEntries().indexOf(name) >= 0) {
172758c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                    canAdd = true;
172858c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                }
172958c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn            }
173058c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn        }
173158c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn        if (!canAdd) {
173258c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn            sourcePos.error("Resource does not already exist in overlay at '%s'; use <add-resource> to add.\n",
173358c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                            String8(name).string());
173458c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn            return UNKNOWN_ERROR;
173558c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn        }
17361aa8170e6a448afad86e5d62927d3b8ca4cd9707Robert Greenwalt    }
1737f878e2d80c3a0afefe3b018d232df6066379e1d5Robert Greenwalt    sp<Entry> e = getEntry(package, type, name, sourcePos, overlay, params);
17389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (e == NULL) {
17399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
17409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // If a parent is explicitly specified, set it.
17439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (bagParent.size() > 0) {
17449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        e->setParent(bagParent);
17459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17464b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt
17474b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt    if ((result = e->makeItABag(sourcePos)) != NO_ERROR) {
17484b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt        return result;
17494b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt    }
17509411a39866b749ad0a47f15083f311847eb79178Robert Greenwalt
17511aa8170e6a448afad86e5d62927d3b8ca4cd9707Robert Greenwalt    if (overlay && replace) {
17529411a39866b749ad0a47f15083f311847eb79178Robert Greenwalt        return e->emptyBag(sourcePos);
17539411a39866b749ad0a47f15083f311847eb79178Robert Greenwalt    }
17549411a39866b749ad0a47f15083f311847eb79178Robert Greenwalt    return result;
17559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
17569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::addBag(const SourcePos& sourcePos,
17589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                               const String16& package,
17599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                               const String16& type,
17609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                               const String16& name,
17619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                               const String16& bagParent,
17629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                               const String16& bagKey,
17639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                               const String16& value,
17649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                               const Vector<StringPool::entry_style_span>* style,
17659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                               const ResTable_config* params,
17669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                               bool replace, bool isId, const int32_t format)
17679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
17689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Check for adding entries in other packages...  for now we do
17699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // nothing.  We need to do the right thing here to support skinning.
17709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t rid = mAssets->getIncludedResources()
17719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        .identifierForName(name.string(), name.size(),
17729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           type.string(), type.size(),
17739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           package.string(), package.size());
17749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (rid != 0) {
17759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NO_ERROR;
17769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 0
17799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (name == String16("left")) {
17809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        printf("Adding bag left: file=%s, line=%d, type=%s\n",
17819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project               sourcePos.file.striing(), sourcePos.line, String8(type).string());
17829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
1784f878e2d80c3a0afefe3b018d232df6066379e1d5Robert Greenwalt    sp<Entry> e = getEntry(package, type, name, sourcePos, replace, params);
17859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (e == NULL) {
17869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
17879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // If a parent is explicitly specified, set it.
17909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (bagParent.size() > 0) {
17919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        e->setParent(bagParent);
17929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const bool first = e->getBag().indexOfKey(bagKey) < 0;
17959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = e->addToBag(sourcePos, bagKey, value, style, replace, isId, format);
17969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err == NO_ERROR && first) {
17979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mNumLocal++;
17989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err;
18009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
18019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::hasBagOrEntry(const String16& package,
18039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const String16& type,
18049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const String16& name) const
18059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
18069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // First look for this in the included resources...
18079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t rid = mAssets->getIncludedResources()
18089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        .identifierForName(name.string(), name.size(),
18099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           type.string(), type.size(),
18109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           package.string(), package.size());
18119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (rid != 0) {
18129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
18139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Package> p = mPackages.valueFor(package);
18169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (p != NULL) {
18179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<Type> t = p->getTypes().valueFor(type);
18189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (t != NULL) {
18199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<ConfigList> c =  t->getConfigs().valueFor(name);
18209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (c != NULL) return true;
18219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
18229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return false;
18259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
18269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1827914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischerbool ResourceTable::hasBagOrEntry(const String16& package,
1828914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer                                  const String16& type,
1829914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer                                  const String16& name,
1830914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer                                  const ResTable_config& config) const
1831914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer{
1832914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer    // First look for this in the included resources...
1833914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer    uint32_t rid = mAssets->getIncludedResources()
1834914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer        .identifierForName(name.string(), name.size(),
1835914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer                           type.string(), type.size(),
1836914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer                           package.string(), package.size());
1837914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer    if (rid != 0) {
1838914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer        return true;
1839914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer    }
1840914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer
1841914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer    sp<Package> p = mPackages.valueFor(package);
1842914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer    if (p != NULL) {
1843914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer        sp<Type> t = p->getTypes().valueFor(type);
1844914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer        if (t != NULL) {
1845914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer            sp<ConfigList> c =  t->getConfigs().valueFor(name);
1846914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer            if (c != NULL) {
1847914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer                sp<Entry> e = c->getEntries().valueFor(config);
1848914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer                if (e != NULL) {
1849914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer                    return true;
1850914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer                }
1851914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer            }
1852914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer        }
1853914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer    }
1854914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer
1855914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer    return false;
1856914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer}
1857914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer
18589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::hasBagOrEntry(const String16& ref,
18599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const String16* defType,
18609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const String16* defPackage)
18619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
18629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String16 package, type, name;
18639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!ResTable::expandResourceRef(ref.string(), ref.size(), &package, &type, &name,
18649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                defType, defPackage ? defPackage:&mAssetsPackage, NULL)) {
18659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
18669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return hasBagOrEntry(package, type, name);
18689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
18699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::appendComment(const String16& package,
18719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const String16& type,
18729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const String16& name,
18739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const String16& comment,
18749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  bool onlyIfEmpty)
18759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
18769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (comment.size() <= 0) {
18779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
18789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Package> p = mPackages.valueFor(package);
18819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (p != NULL) {
18829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<Type> t = p->getTypes().valueFor(type);
18839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (t != NULL) {
18849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<ConfigList> c =  t->getConfigs().valueFor(name);
18859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (c != NULL) {
18869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                c->appendComment(comment, onlyIfEmpty);
18879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
18889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
18899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
18909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return false;
18929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
18939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::appendTypeComment(const String16& package,
18959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                      const String16& type,
18969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                      const String16& name,
18979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                      const String16& comment)
18989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
18999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (comment.size() <= 0) {
19009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
19019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Package> p = mPackages.valueFor(package);
19049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (p != NULL) {
19059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<Type> t = p->getTypes().valueFor(type);
19069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (t != NULL) {
19079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<ConfigList> c =  t->getConfigs().valueFor(name);
19089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (c != NULL) {
19099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                c->appendTypeComment(comment);
19109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
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
191758c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackbornvoid ResourceTable::canAddEntry(const SourcePos& pos,
191858c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn        const String16& package, const String16& type, const String16& name)
191958c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn{
192058c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn    sp<Type> t = getType(package, type, pos);
192158c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn    if (t != NULL) {
192258c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn        t->canAddEntry(name);
192358c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn    }
192458c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn}
192558c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn
19269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsize_t ResourceTable::size() const {
19279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return mPackages.size();
19289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
19299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsize_t ResourceTable::numLocalResources() const {
19319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return mNumLocal;
19329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
19339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::hasResources() const {
19359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return mNumLocal > 0;
19369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
19379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsp<AaptFile> ResourceTable::flatten(Bundle* bundle)
19399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
19409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<AaptFile> data = new AaptFile(String8(), AaptGroupEntry(), String8());
19419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = flatten(bundle, data);
19429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err == NO_ERROR ? data : NULL;
19439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
19449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectinline uint32_t ResourceTable::getResId(const sp<Package>& p,
19469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        const sp<Type>& t,
19479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        uint32_t nameId)
19489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
19499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return makeResId(p->getAssignedId(), t->getIndex(), nameId);
19509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
19519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t ResourceTable::getResId(const String16& package,
19539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16& type,
19549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16& name,
19559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 bool onlyPublic) const
19569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
19579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Package> p = mPackages.valueFor(package);
19589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (p == NULL) return 0;
19599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // First look for this in the included resources...
19619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t specFlags = 0;
19629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t rid = mAssets->getIncludedResources()
19639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        .identifierForName(name.string(), name.size(),
19649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           type.string(), type.size(),
19659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           package.string(), package.size(),
19669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           &specFlags);
19679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (rid != 0) {
19689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (onlyPublic) {
19699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if ((specFlags & ResTable_typeSpec::SPEC_PUBLIC) == 0) {
19709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return 0;
19719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
19729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (Res_INTERNALID(rid)) {
19759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return rid;
19769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return Res_MAKEID(p->getAssignedId()-1,
19789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                          Res_GETTYPE(rid),
19799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                          Res_GETENTRY(rid));
19809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Type> t = p->getTypes().valueFor(type);
19839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (t == NULL) return 0;
19849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<ConfigList> c =  t->getConfigs().valueFor(name);
19859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (c == NULL) return 0;
19869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t ei = c->getEntryIndex();
19879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (ei < 0) return 0;
19889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return getResId(p, t, ei);
19899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
19909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t ResourceTable::getResId(const String16& ref,
19929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16* defType,
19939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16* defPackage,
19949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const char** outErrorMsg,
19959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 bool onlyPublic) const
19969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
19979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String16 package, type, name;
1998426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn    bool refOnlyPublic = true;
19999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!ResTable::expandResourceRef(
20009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ref.string(), ref.size(), &package, &type, &name,
20019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        defType, defPackage ? defPackage:&mAssetsPackage,
2002426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn        outErrorMsg, &refOnlyPublic)) {
20039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NOISY(printf("Expanding resource: ref=%s\n",
20049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                     String8(ref).string()));
20059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NOISY(printf("Expanding resource: defType=%s\n",
20069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                     defType ? String8(*defType).string() : "NULL"));
20079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NOISY(printf("Expanding resource: defPackage=%s\n",
20089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                     defPackage ? String8(*defPackage).string() : "NULL"));
20099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NOISY(printf("Expanding resource: ref=%s\n", String8(ref).string()));
20109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NOISY(printf("Expanded resource: p=%s, t=%s, n=%s, res=0\n",
20119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                     String8(package).string(), String8(type).string(),
20129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                     String8(name).string()));
20139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 0;
20149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2015426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn    uint32_t res = getResId(package, type, name, onlyPublic && refOnlyPublic);
20169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    NOISY(printf("Expanded resource: p=%s, t=%s, n=%s, res=%d\n",
20179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 String8(package).string(), String8(type).string(),
20189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 String8(name).string(), res));
20199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (res == 0) {
20209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (outErrorMsg)
20219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            *outErrorMsg = "No resource found that matches the given name";
20229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return res;
20249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
20259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::isValidResourceName(const String16& s)
20279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
20289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char16_t* p = s.string();
20299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool first = true;
20309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (*p) {
20319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((*p >= 'a' && *p <= 'z')
20329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            || (*p >= 'A' && *p <= 'Z')
20339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            || *p == '_'
20349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            || (!first && *p >= '0' && *p <= '9')) {
20359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            first = false;
20369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p++;
20379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            continue;
20389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
20399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
20409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return true;
20429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
20439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::stringToValue(Res_value* outValue, StringPool* pool,
20459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const String16& str,
20469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  bool preserveSpaces, bool coerceType,
20479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  uint32_t attrID,
20489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const Vector<StringPool::entry_style_span>* style,
20499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  String16* outStr, void* accessorCookie,
20509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  uint32_t attrType)
20519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
20529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String16 finalStr;
20539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool res = true;
20559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (style == NULL || style->size() == 0) {
20569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Text is not styled so it can be any type...  let's figure it out.
20579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        res = mAssets->getIncludedResources()
20589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            .stringToValue(outValue, &finalStr, str.string(), str.size(), preserveSpaces,
20599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            coerceType, attrID, NULL, &mAssetsPackage, this,
20609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           accessorCookie, attrType);
20619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
20629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Styled text can only be a string, and while collecting the style
20639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // information we have already processed that string!
20649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        outValue->size = sizeof(Res_value);
20659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        outValue->res0 = 0;
2066774562275fa76681933a0105ed61c672892b23bdKenny Root        outValue->dataType = outValue->TYPE_STRING;
20679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        outValue->data = 0;
20689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        finalStr = str;
20699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!res) {
20729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
20739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2075774562275fa76681933a0105ed61c672892b23bdKenny Root    if (outValue->dataType == outValue->TYPE_STRING) {
20769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Should do better merging styles.
20779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (pool) {
20789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (style != NULL && style->size() > 0) {
20799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                outValue->data = pool->add(finalStr, *style);
20809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
20819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                outValue->data = pool->add(finalStr, true);
20829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
20839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
20849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Caller will fill this in later.
20859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            outValue->data = 0;
20869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
20879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (outStr) {
20899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            *outStr = finalStr;
20909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
20919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return true;
20959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
20969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t ResourceTable::getCustomResource(
20989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16& package, const String16& type, const String16& name) const
20999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
21009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //printf("getCustomResource: %s %s %s\n", String8(package).string(),
21019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //       String8(type).string(), String8(name).string());
21029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Package> p = mPackages.valueFor(package);
21039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (p == NULL) return 0;
21049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Type> t = p->getTypes().valueFor(type);
21059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (t == NULL) return 0;
21069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<ConfigList> c =  t->getConfigs().valueFor(name);
21079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (c == NULL) return 0;
21089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t ei = c->getEntryIndex();
21099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (ei < 0) return 0;
21109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return getResId(p, t, ei);
21119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
21129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t ResourceTable::getCustomResourceWithCreation(
21149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const String16& package, const String16& type, const String16& name,
21159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const bool createIfNotFound)
21169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
21179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t resId = getCustomResource(package, type, name);
21189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (resId != 0 || !createIfNotFound) {
21199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return resId;
21209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String16 value("false");
21229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t status = addEntry(mCurrentXmlPos, package, type, name, value, NULL, NULL, true);
21249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (status == NO_ERROR) {
21259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        resId = getResId(package, type, name);
21269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return resId;
21279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return 0;
21299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
21309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t ResourceTable::getRemappedPackage(uint32_t origPackage) const
21329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
21339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return origPackage;
21349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
21359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::getAttributeType(uint32_t attrID, uint32_t* outType)
21379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
21389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //printf("getAttributeType #%08x\n", attrID);
21399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Res_value value;
21409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (getItemValue(attrID, ResTable_map::ATTR_TYPE, &value)) {
21419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //printf("getAttributeType #%08x (%s): #%08x\n", attrID,
21429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //       String8(getEntry(attrID)->getName()).string(), value.data);
21439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        *outType = value.data;
21449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
21459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return false;
21479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
21489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::getAttributeMin(uint32_t attrID, uint32_t* outMin)
21509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
21519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //printf("getAttributeMin #%08x\n", attrID);
21529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Res_value value;
21539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (getItemValue(attrID, ResTable_map::ATTR_MIN, &value)) {
21549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        *outMin = value.data;
21559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
21569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return false;
21589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
21599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::getAttributeMax(uint32_t attrID, uint32_t* outMax)
21619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
21629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //printf("getAttributeMax #%08x\n", attrID);
21639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Res_value value;
21649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (getItemValue(attrID, ResTable_map::ATTR_MAX, &value)) {
21659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        *outMax = value.data;
21669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
21679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return false;
21699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
21709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t ResourceTable::getAttributeL10N(uint32_t attrID)
21729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
21739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //printf("getAttributeL10N #%08x\n", attrID);
21749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Res_value value;
21759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (getItemValue(attrID, ResTable_map::ATTR_L10N, &value)) {
21769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return value.data;
21779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return ResTable_map::L10N_NOT_REQUIRED;
21799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
21809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::getLocalizationSetting()
21829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
21839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return mBundle->getRequireLocalization();
21849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
21859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResourceTable::reportError(void* accessorCookie, const char* fmt, ...)
21879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
21889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (accessorCookie != NULL && fmt != NULL) {
21899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        AccessorCookie* ac = (AccessorCookie*)accessorCookie;
21909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int retval=0;
21919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        char buf[1024];
21929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        va_list ap;
21939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        va_start(ap, fmt);
21949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        retval = vsnprintf(buf, sizeof(buf), fmt, ap);
21959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        va_end(ap);
21969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ac->sourcePos.error("Error: %s (at '%s' with value '%s').\n",
21979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            buf, ac->attr.string(), ac->value.string());
21989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
22009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::getAttributeKeys(
22029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t attrID, Vector<String16>* outKeys)
22039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
22049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<const Entry> e = getEntry(attrID);
22059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (e != NULL) {
22069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t N = e->getBag().size();
22079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (size_t i=0; i<N; i++) {
22089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const String16& key = e->getBag().keyAt(i);
22099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (key.size() > 0 && key.string()[0] != '^') {
22109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                outKeys->add(key);
22119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
22129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
22139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
22149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return false;
22169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
22179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::getAttributeEnum(
22199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t attrID, const char16_t* name, size_t nameLen,
22209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Res_value* outValue)
22219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
22229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //printf("getAttributeEnum #%08x %s\n", attrID, String8(name, nameLen).string());
22239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String16 nameStr(name, nameLen);
22249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<const Entry> e = getEntry(attrID);
22259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (e != NULL) {
22269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t N = e->getBag().size();
22279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (size_t i=0; i<N; i++) {
22289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //printf("Comparing %s to %s\n", String8(name, nameLen).string(),
22299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //       String8(e->getBag().keyAt(i)).string());
22309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (e->getBag().keyAt(i) == nameStr) {
22319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return getItemValue(attrID, e->getBag().valueAt(i).bagKeyId, outValue);
22329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
22339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
22349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return false;
22369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
22379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::getAttributeFlags(
22399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t attrID, const char16_t* name, size_t nameLen,
22409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Res_value* outValue)
22419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
22429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    outValue->dataType = Res_value::TYPE_INT_HEX;
22439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    outValue->data = 0;
22449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //printf("getAttributeFlags #%08x %s\n", attrID, String8(name, nameLen).string());
22469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String16 nameStr(name, nameLen);
22479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<const Entry> e = getEntry(attrID);
22489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (e != NULL) {
22499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t N = e->getBag().size();
22509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const char16_t* end = name + nameLen;
22529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const char16_t* pos = name;
22539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bool failed = false;
22549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (pos < end && !failed) {
22559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const char16_t* start = pos;
22569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            end++;
22579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            while (pos < end && *pos != '|') {
22589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pos++;
22599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
22609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String16 nameStr(start, pos-start);
22629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            size_t i;
22639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (i=0; i<N; i++) {
22649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                //printf("Comparing \"%s\" to \"%s\"\n", String8(nameStr).string(),
22659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                //       String8(e->getBag().keyAt(i)).string());
22669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (e->getBag().keyAt(i) == nameStr) {
22679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Res_value val;
22689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    bool got = getItemValue(attrID, e->getBag().valueAt(i).bagKeyId, &val);
22699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (!got) {
22709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        return false;
22719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
22729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    //printf("Got value: 0x%08x\n", val.data);
22739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    outValue->data |= val.data;
22749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
22759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
22769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
22779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (i >= N) {
22799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Didn't find this flag identifier.
22809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return false;
22819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
22829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (pos < end) {
22839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pos++;
22849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
22859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
22869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
22889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return false;
22909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
22919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::assignResourceIds()
22939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
22949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t N = mOrderedPackages.size();
22959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t pi;
22969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t firstError = NO_ERROR;
22979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // First generate all bag attributes and assign indices.
22999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (pi=0; pi<N; pi++) {
23009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<Package> p = mOrderedPackages.itemAt(pi);
23019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (p == NULL || p->getTypes().size() == 0) {
23029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Empty, skip!
23039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            continue;
23049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
23059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        status_t err = p->applyPublicTypeOrder();
23079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != NO_ERROR && firstError == NO_ERROR) {
23089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            firstError = err;
23099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
23109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Generate attributes...
23129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t N = p->getOrderedTypes().size();
23139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        size_t ti;
23149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (ti=0; ti<N; ti++) {
23159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<Type> t = p->getOrderedTypes().itemAt(ti);
23169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (t == NULL) {
23179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
23189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
23199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const size_t N = t->getOrderedConfigs().size();
23209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (size_t ci=0; ci<N; ci++) {
23219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);
23229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (c == NULL) {
23239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
23249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
23259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                const size_t N = c->getEntries().size();
23269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (size_t ei=0; ei<N; ei++) {
23279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sp<Entry> e = c->getEntries().valueAt(ei);
23289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (e == NULL) {
23299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        continue;
23309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
23319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    status_t err = e->generateAttributes(this, p->getName());
23329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (err != NO_ERROR && firstError == NO_ERROR) {
23339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        firstError = err;
23349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
23359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
23369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
23379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
23389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const SourcePos unknown(String8("????"), 0);
23409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<Type> attr = p->getType(String16("attr"), unknown);
23419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Assign indices...
23439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (ti=0; ti<N; ti++) {
23449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<Type> t = p->getOrderedTypes().itemAt(ti);
23459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (t == NULL) {
23469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
23479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
23489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            err = t->applyPublicEntryOrder();
23499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (err != NO_ERROR && firstError == NO_ERROR) {
23509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                firstError = err;
23519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
23529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const size_t N = t->getOrderedConfigs().size();
23549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            t->setIndex(ti+1);
23559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOG_ALWAYS_FATAL_IF(ti == 0 && attr != t,
23579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                "First type is not attr!");
23589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (size_t ei=0; ei<N; ei++) {
23609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ei);
23619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (c == NULL) {
23629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
23639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
23649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                c->setEntryIndex(ei);
23659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
23669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
23679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Assign resource IDs to keys in bags...
23699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (ti=0; ti<N; ti++) {
23709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<Type> t = p->getOrderedTypes().itemAt(ti);
23719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (t == NULL) {
23729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
23739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
23749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const size_t N = t->getOrderedConfigs().size();
23759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (size_t ci=0; ci<N; ci++) {
23769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);
23779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                //printf("Ordered config #%d: %p\n", ci, c.get());
23789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                const size_t N = c->getEntries().size();
23799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (size_t ei=0; ei<N; ei++) {
23809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sp<Entry> e = c->getEntries().valueAt(ei);
23819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (e == NULL) {
23829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        continue;
23839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
23849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    status_t err = e->assignResourceIds(this, p->getName());
23859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (err != NO_ERROR && firstError == NO_ERROR) {
23869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        firstError = err;
23879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
23889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
23899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
23909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
23919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
23929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return firstError;
23939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
23949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::addSymbols(const sp<AaptSymbols>& outSymbols) {
23969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t N = mOrderedPackages.size();
23979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t pi;
23989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (pi=0; pi<N; pi++) {
24009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<Package> p = mOrderedPackages.itemAt(pi);
24019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (p->getTypes().size() == 0) {
24029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Empty, skip!
24039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            continue;
24049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
24059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t N = p->getOrderedTypes().size();
24079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        size_t ti;
24089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (ti=0; ti<N; ti++) {
24109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<Type> t = p->getOrderedTypes().itemAt(ti);
24119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (t == NULL) {
24129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
24139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
24149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const size_t N = t->getOrderedConfigs().size();
24159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<AaptSymbols> typeSymbols;
24169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            typeSymbols = outSymbols->addNestedSymbol(String8(t->getName()), t->getPos());
24179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (size_t ci=0; ci<N; ci++) {
24189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);
24199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (c == NULL) {
24209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
24219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
24229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                uint32_t rid = getResId(p, t, ci);
24239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (rid == 0) {
24249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return UNKNOWN_ERROR;
24259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
24269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (Res_GETPACKAGE(rid) == (size_t)(p->getAssignedId()-1)) {
24279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    typeSymbols->addSymbol(String8(c->getName()), rid, c->getPos());
24289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String16 comment(c->getComment());
24309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    typeSymbols->appendComment(String8(c->getName()), comment, c->getPos());
24319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    //printf("Type symbol %s comment: %s\n", String8(e->getName()).string(),
24329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    //     String8(comment).string());
24339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    comment = c->getTypeComment();
24349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    typeSymbols->appendTypeComment(String8(c->getName()), comment);
24359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
24369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 0
24379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    printf("**** NO MATCH: 0x%08x vs 0x%08x\n",
24389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           Res_GETPACKAGE(rid), p->getAssignedId());
24399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
24409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
24419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
24429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
24439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
24449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
24459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
24469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid
24499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResourceTable::addLocalization(const String16& name, const String8& locale)
24509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
24519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mLocalizations[name].insert(locale);
24529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
24539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*!
24569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Flag various sorts of localization problems.  '+' indicates checks already implemented;
24579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * '-' indicates checks that will be implemented in the future.
24589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
24599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * + A localized string for which no default-locale version exists => warning
24609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * + A string for which no version in an explicitly-requested locale exists => warning
24619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * + A localized translation of an translateable="false" string => warning
24629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * - A localized string not provided in every locale used by the table
24639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
24649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t
24659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResourceTable::validateLocalizations(void)
24669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
24679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = NO_ERROR;
24689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String8 defaultLocale;
24699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // For all strings...
24719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (map<String16, set<String8> >::iterator nameIter = mLocalizations.begin();
24729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         nameIter != mLocalizations.end();
24739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         nameIter++) {
24749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const set<String8>& configSet = nameIter->second;   // naming convenience
24759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Look for strings with no default localization
24779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (configSet.count(defaultLocale) == 0) {
24789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stdout, "aapt: warning: string '%s' has no default translation in %s; found:",
24799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(nameIter->first).string(), mBundle->getResourceSourceDirs()[0]);
2480f1ff21ac62a51f5ba8ca0821ea8a90f70957e25dSteve Block            for (set<String8>::const_iterator locales = configSet.begin();
24819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 locales != configSet.end();
24829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 locales++) {
24839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                fprintf(stdout, " %s", (*locales).string());
24849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
24859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stdout, "\n");
24869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // !!! TODO: throw an error here in some circumstances
24879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
24889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Check that all requested localizations are present for this string
24909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mBundle->getConfigurations() != NULL && mBundle->getRequireLocalization()) {
24919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const char* allConfigs = mBundle->getConfigurations();
24929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const char* start = allConfigs;
24939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const char* comma;
24949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            do {
24969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String8 config;
24979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                comma = strchr(start, ',');
24989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (comma != NULL) {
24999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    config.setTo(start, comma - start);
25009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    start = comma + 1;
25019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
25029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    config.setTo(start);
25039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
25049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // don't bother with the pseudolocale "zz_ZZ"
25069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (config != "zz_ZZ") {
25079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (configSet.find(config) == configSet.end()) {
25089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // okay, no specific localization found.  it's possible that we are
25099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // requiring a specific regional localization [e.g. de_DE] but there is an
25109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // available string in the generic language localization [e.g. de];
25119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // consider that string to have fulfilled the localization requirement.
25129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String8 region(config.string(), 2);
25139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (configSet.find(region) == configSet.end()) {
25149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            if (configSet.count(defaultLocale) == 0) {
2515c87d25215c842cea370c6a86ce67585fa8da4900Eric Fischer                                fprintf(stdout, "aapt: warning: "
251665e185b51ec655518f1917418cd6192400ac439dEd Heyl                                        "**** string '%s' has no default or required localization "
25179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        "for '%s' in %s\n",
25189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        String8(nameIter->first).string(),
25199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        config.string(),
25209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        mBundle->getResourceSourceDirs()[0]);
25219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
25229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
25239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
25249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
25259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project           } while (comma != NULL);
25269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
25279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
25289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err;
25309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
25319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest)
25339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
25349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ResourceFilter filter;
25359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = filter.parse(bundle->getConfigurations());
25369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != NO_ERROR) {
25379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return err;
25389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
25399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t N = mOrderedPackages.size();
25419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t pi;
25429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25437c71023b7f5aafac09bd2f0425fccb5fe2d22b27Kenny Root    const static String16 mipmap16("mipmap");
25447c71023b7f5aafac09bd2f0425fccb5fe2d22b27Kenny Root
2545c9f3088036dd7cce6903e307afea3e289a334036Kenny Root    bool useUTF8 = !bundle->getWantUTF16() && bundle->isMinSdkAtLeast(SDK_FROYO);
25461741cd4904414b5b4e768953a8f1abb3f0ef0a0aKenny Root
25479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Iterate through all data, collecting all values (strings,
25489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // references, etc).
25491741cd4904414b5b4e768953a8f1abb3f0ef0a0aKenny Root    StringPool valueStrings = StringPool(false, useUTF8);
25509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (pi=0; pi<N; pi++) {
25519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<Package> p = mOrderedPackages.itemAt(pi);
25529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (p->getTypes().size() == 0) {
25539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Empty, skip!
25549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            continue;
25559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
25569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25571741cd4904414b5b4e768953a8f1abb3f0ef0a0aKenny Root        StringPool typeStrings = StringPool(false, useUTF8);
25581741cd4904414b5b4e768953a8f1abb3f0ef0a0aKenny Root        StringPool keyStrings = StringPool(false, useUTF8);
25599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t N = p->getOrderedTypes().size();
25619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (size_t ti=0; ti<N; ti++) {
25629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<Type> t = p->getOrderedTypes().itemAt(ti);
25639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (t == NULL) {
25649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                typeStrings.add(String16("<empty>"), false);
25659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
25669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
25677c71023b7f5aafac09bd2f0425fccb5fe2d22b27Kenny Root            const String16 typeName(t->getName());
25687c71023b7f5aafac09bd2f0425fccb5fe2d22b27Kenny Root            typeStrings.add(typeName, false);
25697c71023b7f5aafac09bd2f0425fccb5fe2d22b27Kenny Root
25707c71023b7f5aafac09bd2f0425fccb5fe2d22b27Kenny Root            const bool filterable = (typeName != mipmap16);
25719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const size_t N = t->getOrderedConfigs().size();
25739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (size_t ci=0; ci<N; ci++) {
25749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);
25759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (c == NULL) {
25769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
25779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
25789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                const size_t N = c->getEntries().size();
25799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (size_t ei=0; ei<N; ei++) {
25809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ConfigDescription config = c->getEntries().keyAt(ei);
25817c71023b7f5aafac09bd2f0425fccb5fe2d22b27Kenny Root                    if (filterable && !filter.match(config)) {
25829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        continue;
25839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
25849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sp<Entry> e = c->getEntries().valueAt(ei);
25859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (e == NULL) {
25869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        continue;
25879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
25889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    e->setNameIndex(keyStrings.add(e->getName(), true));
25899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    status_t err = e->prepareFlatten(&valueStrings, this);
25909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (err != NO_ERROR) {
25919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        return err;
25929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
25939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
25949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
25959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
25969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p->setTypeStrings(typeStrings.createStringBlock());
25989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p->setKeyStrings(keyStrings.createStringBlock());
25999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
26009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ssize_t strAmt = 0;
26029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Now build the array of package chunks.
26049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Vector<sp<AaptFile> > flatPackages;
26059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (pi=0; pi<N; pi++) {
26069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<Package> p = mOrderedPackages.itemAt(pi);
26079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (p->getTypes().size() == 0) {
26089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Empty, skip!
26099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            continue;
26109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
26119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t N = p->getTypeStrings().size();
26139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t baseSize = sizeof(ResTable_package);
26159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Start the package data.
26179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<AaptFile> data = new AaptFile(String8(), AaptGroupEntry(), String8());
26189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ResTable_package* header = (ResTable_package*)data->editData(baseSize);
26199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (header == NULL) {
26209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "ERROR: out of memory creating ResTable_package\n");
26219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return NO_MEMORY;
26229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
26239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        memset(header, 0, sizeof(*header));
26249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header->header.type = htods(RES_TABLE_PACKAGE_TYPE);
26259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header->header.headerSize = htods(sizeof(*header));
26269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header->id = htodl(p->getAssignedId());
26279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        strcpy16_htod(header->name, p->getName().string());
26289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Write the string blocks.
26309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t typeStringsStart = data->getSize();
26319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<AaptFile> strFile = p->getTypeStringsData();
26329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ssize_t amt = data->writeData(strFile->getData(), strFile->getSize());
26339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        #if PRINT_STRING_METRICS
26349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fprintf(stderr, "**** type strings: %d\n", amt);
26359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        #endif
26369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        strAmt += amt;
26379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (amt < 0) {
26389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return amt;
26399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
26409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t keyStringsStart = data->getSize();
26419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        strFile = p->getKeyStringsData();
26429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        amt = data->writeData(strFile->getData(), strFile->getSize());
26439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        #if PRINT_STRING_METRICS
26449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fprintf(stderr, "**** key strings: %d\n", amt);
26459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        #endif
26469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        strAmt += amt;
26479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (amt < 0) {
26489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return amt;
26499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
26509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Build the type chunks inside of this package.
26529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (size_t ti=0; ti<N; ti++) {
26539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Retrieve them in the same order as the type string block.
26549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            size_t len;
26559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String16 typeName(p->getTypeStrings().stringAt(ti, &len));
26569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<Type> t = p->getTypes().valueFor(typeName);
26579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOG_ALWAYS_FATAL_IF(t == NULL && typeName != String16("<empty>"),
26589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                "Type name %s not found",
26599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                String8(typeName).string());
26609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26617c71023b7f5aafac09bd2f0425fccb5fe2d22b27Kenny Root            const bool filterable = (typeName != mipmap16);
26627c71023b7f5aafac09bd2f0425fccb5fe2d22b27Kenny Root
26639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const size_t N = t != NULL ? t->getOrderedConfigs().size() : 0;
26649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // First write the typeSpec chunk, containing information about
26669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // each resource entry in this type.
26679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            {
26689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                const size_t typeSpecSize = sizeof(ResTable_typeSpec) + sizeof(uint32_t)*N;
26699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                const size_t typeSpecStart = data->getSize();
26709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ResTable_typeSpec* tsHeader = (ResTable_typeSpec*)
26719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    (((uint8_t*)data->editData(typeSpecStart+typeSpecSize)) + typeSpecStart);
26729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (tsHeader == NULL) {
26739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    fprintf(stderr, "ERROR: out of memory creating ResTable_typeSpec\n");
26749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return NO_MEMORY;
26759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
26769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                memset(tsHeader, 0, sizeof(*tsHeader));
26779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tsHeader->header.type = htods(RES_TABLE_TYPE_SPEC_TYPE);
26789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tsHeader->header.headerSize = htods(sizeof(*tsHeader));
26799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tsHeader->header.size = htodl(typeSpecSize);
26809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tsHeader->id = ti+1;
26819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tsHeader->entryCount = htodl(N);
26829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                uint32_t* typeSpecFlags = (uint32_t*)
26849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    (((uint8_t*)data->editData())
26859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + typeSpecStart + sizeof(ResTable_typeSpec));
26869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                memset(typeSpecFlags, 0, sizeof(uint32_t)*N);
26877c71023b7f5aafac09bd2f0425fccb5fe2d22b27Kenny Root
26889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (size_t ei=0; ei<N; ei++) {
26899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sp<ConfigList> cl = t->getOrderedConfigs().itemAt(ei);
26909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (cl->getPublic()) {
26919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        typeSpecFlags[ei] |= htodl(ResTable_typeSpec::SPEC_PUBLIC);
26929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
26939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    const size_t CN = cl->getEntries().size();
26949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    for (size_t ci=0; ci<CN; ci++) {
26957c71023b7f5aafac09bd2f0425fccb5fe2d22b27Kenny Root                        if (filterable && !filter.match(cl->getEntries().keyAt(ci))) {
26969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            continue;
26979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
26989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        for (size_t cj=ci+1; cj<CN; cj++) {
26997c71023b7f5aafac09bd2f0425fccb5fe2d22b27Kenny Root                            if (filterable && !filter.match(cl->getEntries().keyAt(cj))) {
27009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                continue;
27019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
27029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            typeSpecFlags[ei] |= htodl(
27039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                cl->getEntries().keyAt(ci).diff(cl->getEntries().keyAt(cj)));
27049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
27059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
27069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
27079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
27089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // We need to write one type chunk for each configuration for
27109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // which we have entries in this type.
27119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const size_t NC = t->getUniqueConfigs().size();
27129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const size_t typeSize = sizeof(ResTable_type) + sizeof(uint32_t)*N;
27149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (size_t ci=0; ci<NC; ci++) {
27169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ConfigDescription config = t->getUniqueConfigs().itemAt(ci);
27179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                NOISY(printf("Writing config %d config: imsi:%d/%d lang:%c%c cnt:%c%c "
271969cb87576ba163b61bb0e6477a3b7c57a9b11d40Dianne Hackborn                     "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d "
272069cb87576ba163b61bb0e6477a3b7c57a9b11d40Dianne Hackborn                     "sw%ddp w%ddp h%ddp\n",
27219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      ti+1,
27229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.mcc, config.mnc,
27239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.language[0] ? config.language[0] : '-',
27249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.language[1] ? config.language[1] : '-',
27259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.country[0] ? config.country[0] : '-',
27269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.country[1] ? config.country[1] : '-',
27279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.orientation,
272827b28b3f62bd3b54fa13acd5d035940b9be464f3Tobias Haamel                      config.uiMode,
27299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.touchscreen,
27309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.density,
27319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.keyboard,
27329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.inputFlags,
27339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.navigation,
27349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.screenWidth,
2735ebff8f92f13513ce37bd74759eb1db63f2220590Dianne Hackborn                      config.screenHeight,
273669cb87576ba163b61bb0e6477a3b7c57a9b11d40Dianne Hackborn                      config.smallestScreenWidthDp,
2737ebff8f92f13513ce37bd74759eb1db63f2220590Dianne Hackborn                      config.screenWidthDp,
2738ebff8f92f13513ce37bd74759eb1db63f2220590Dianne Hackborn                      config.screenHeightDp));
27399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27407c71023b7f5aafac09bd2f0425fccb5fe2d22b27Kenny Root                if (filterable && !filter.match(config)) {
27419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
27429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
27439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                const size_t typeStart = data->getSize();
27459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ResTable_type* tHeader = (ResTable_type*)
27479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    (((uint8_t*)data->editData(typeStart+typeSize)) + typeStart);
27489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (tHeader == NULL) {
27499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    fprintf(stderr, "ERROR: out of memory creating ResTable_type\n");
27509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return NO_MEMORY;
27519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
27529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                memset(tHeader, 0, sizeof(*tHeader));
27549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tHeader->header.type = htods(RES_TABLE_TYPE_TYPE);
27559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tHeader->header.headerSize = htods(sizeof(*tHeader));
27569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tHeader->id = ti+1;
27579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tHeader->entryCount = htodl(N);
27589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tHeader->entriesStart = htodl(typeSize);
27599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tHeader->config = config;
27609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                NOISY(printf("Writing type %d config: imsi:%d/%d lang:%c%c cnt:%c%c "
276169cb87576ba163b61bb0e6477a3b7c57a9b11d40Dianne Hackborn                     "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d "
276269cb87576ba163b61bb0e6477a3b7c57a9b11d40Dianne Hackborn                     "sw%ddp w%ddp h%ddp\n",
27639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      ti+1,
27649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.mcc, tHeader->config.mnc,
27659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.language[0] ? tHeader->config.language[0] : '-',
27669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.language[1] ? tHeader->config.language[1] : '-',
27679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.country[0] ? tHeader->config.country[0] : '-',
27689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.country[1] ? tHeader->config.country[1] : '-',
27699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.orientation,
277027b28b3f62bd3b54fa13acd5d035940b9be464f3Tobias Haamel                      tHeader->config.uiMode,
27719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.touchscreen,
27729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.density,
27739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.keyboard,
27749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.inputFlags,
27759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.navigation,
27769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.screenWidth,
2777ebff8f92f13513ce37bd74759eb1db63f2220590Dianne Hackborn                      tHeader->config.screenHeight,
277869cb87576ba163b61bb0e6477a3b7c57a9b11d40Dianne Hackborn                      tHeader->config.smallestScreenWidthDp,
2779ebff8f92f13513ce37bd74759eb1db63f2220590Dianne Hackborn                      tHeader->config.screenWidthDp,
2780ebff8f92f13513ce37bd74759eb1db63f2220590Dianne Hackborn                      tHeader->config.screenHeightDp));
27819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tHeader->config.swapHtoD();
27829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Build the entries inside of this type.
27849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (size_t ei=0; ei<N; ei++) {
27859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sp<ConfigList> cl = t->getOrderedConfigs().itemAt(ei);
27869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sp<Entry> e = cl->getEntries().valueFor(config);
27879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Set the offset for this entry in its type.
27899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    uint32_t* index = (uint32_t*)
27909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        (((uint8_t*)data->editData())
27919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            + typeStart + sizeof(ResTable_type));
27929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (e != NULL) {
27939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        index[ei] = htodl(data->getSize()-typeStart-typeSize);
27949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // Create the entry.
27969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ssize_t amt = e->flatten(bundle, data, cl->getPublic());
27979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (amt < 0) {
27989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            return amt;
27999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
28009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else {
28019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        index[ei] = htodl(ResTable_type::NO_ENTRY);
28029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
28039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
28049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Fill in the rest of the type information.
28069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tHeader = (ResTable_type*)
28079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    (((uint8_t*)data->editData()) + typeStart);
28089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tHeader->header.size = htodl(data->getSize()-typeStart);
28099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
28109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
28119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Fill in the rest of the package information.
28139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header = (ResTable_package*)data->editData();
28149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header->header.size = htodl(data->getSize());
28159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header->typeStrings = htodl(typeStringsStart);
28169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header->lastPublicType = htodl(p->getTypeStrings().size());
28179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header->keyStrings = htodl(keyStringsStart);
28189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header->lastPublicKey = htodl(p->getKeyStrings().size());
28199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        flatPackages.add(data);
28219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
28229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // And now write out the final chunks.
28249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t dataStart = dest->getSize();
28259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
28279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // blah
28289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ResTable_header header;
28299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        memset(&header, 0, sizeof(header));
28309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header.header.type = htods(RES_TABLE_TYPE);
28319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header.header.headerSize = htods(sizeof(header));
28329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header.packageCount = htodl(flatPackages.size());
28339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        status_t err = dest->writeData(&header, sizeof(header));
28349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != NO_ERROR) {
28359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "ERROR: out of memory creating ResTable_header\n");
28369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return err;
28379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
28389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
28399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ssize_t strStart = dest->getSize();
28419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    err = valueStrings.writeStringBlock(dest);
28429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != NO_ERROR) {
28439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return err;
28449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
28459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ssize_t amt = (dest->getSize()-strStart);
28479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    strAmt += amt;
28489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    #if PRINT_STRING_METRICS
28499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    fprintf(stderr, "**** value strings: %d\n", amt);
28509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    fprintf(stderr, "**** total strings: %d\n", strAmt);
28519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    #endif
28529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (pi=0; pi<flatPackages.size(); pi++) {
28549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        err = dest->writeData(flatPackages[pi]->getData(),
28559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                              flatPackages[pi]->getSize());
28569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != NO_ERROR) {
28579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "ERROR: out of memory creating package chunk for ResTable_header\n");
28589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return err;
28599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
28609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
28619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ResTable_header* header = (ResTable_header*)
28639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (((uint8_t*)dest->getData()) + dataStart);
28649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    header->header.size = htodl(dest->getSize() - dataStart);
28659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    NOISY(aout << "Resource table:"
28679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project          << HexDump(dest->getData(), dest->getSize()) << endl);
28689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    #if PRINT_STRING_METRICS
28709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    fprintf(stderr, "**** total resource table size: %d / %d%% strings\n",
28719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dest->getSize(), (strAmt*100)/dest->getSize());
28729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    #endif
28739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
28759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
28769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResourceTable::writePublicDefinitions(const String16& package, FILE* fp)
28789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
28799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    fprintf(fp,
28809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    "<!-- This file contains <public> resource definitions for all\n"
28819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    "     resources that were generated from the source data. -->\n"
28829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    "\n"
28839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    "<resources>\n");
28849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    writePublicDefinitions(package, fp, true);
28869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    writePublicDefinitions(package, fp, false);
28879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    fprintf(fp,
28899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    "\n"
28909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    "</resources>\n");
28919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
28929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResourceTable::writePublicDefinitions(const String16& package, FILE* fp, bool pub)
28949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
28959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool didHeader = false;
28969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Package> pkg = mPackages.valueFor(package);
28989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (pkg != NULL) {
28999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t NT = pkg->getOrderedTypes().size();
29009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (size_t i=0; i<NT; i++) {
29019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<Type> t = pkg->getOrderedTypes().itemAt(i);
29029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (t == NULL) {
29039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
29049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
29059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bool didType = false;
29079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const size_t NC = t->getOrderedConfigs().size();
29099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (size_t j=0; j<NC; j++) {
29109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sp<ConfigList> c = t->getOrderedConfigs().itemAt(j);
29119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (c == NULL) {
29129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
29139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
29149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (c->getPublic() != pub) {
29169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
29179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
29189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!didType) {
29209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    fprintf(fp, "\n");
29219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    didType = true;
29229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
29239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!didHeader) {
29249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (pub) {
29259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        fprintf(fp,"  <!-- PUBLIC SECTION.  These resources have been declared public.\n");
29269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        fprintf(fp,"       Changes to these definitions will break binary compatibility. -->\n\n");
29279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else {
29289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        fprintf(fp,"  <!-- PRIVATE SECTION.  These resources have not been declared public.\n");
29299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        fprintf(fp,"       You can make them public my moving these lines into a file in res/values. -->\n\n");
29309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
29319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    didHeader = true;
29329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
29339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!pub) {
29349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    const size_t NE = c->getEntries().size();
29359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    for (size_t k=0; k<NE; k++) {
29369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const SourcePos& pos = c->getEntries().valueAt(k)->getPos();
29379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (pos.file != "") {
29389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            fprintf(fp,"  <!-- Declared at %s:%d -->\n",
29399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    pos.file.string(), pos.line);
29409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
29419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
29429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
29439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                fprintf(fp, "  <public type=\"%s\" name=\"%s\" id=\"0x%08x\" />\n",
29449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String8(t->getName()).string(),
29459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String8(c->getName()).string(),
29469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        getResId(pkg, t, c->getEntryIndex()));
29479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
29489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
29499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
29509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
29519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResourceTable::Item::Item(const SourcePos& _sourcePos,
29539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                          bool _isId,
29549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                          const String16& _value,
29559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                          const Vector<StringPool::entry_style_span>* _style,
29569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                          int32_t _format)
29579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    : sourcePos(_sourcePos)
29589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    , isId(_isId)
29599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    , value(_value)
29609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    , format(_format)
29619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    , bagKeyId(0)
29629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    , evaluating(false)
29639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
29649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (_style) {
29659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        style = *_style;
29669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
29679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
29689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::Entry::makeItABag(const SourcePos& sourcePos)
29709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
29719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mType == TYPE_BAG) {
29729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NO_ERROR;
29739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
29749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mType == TYPE_UNKNOWN) {
29759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mType = TYPE_BAG;
29769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NO_ERROR;
29779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
29789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sourcePos.error("Resource entry %s is already defined as a single item.\n"
29799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    "%s:%d: Originally defined here.\n",
29809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(mName).string(),
29819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mItem.sourcePos.file.string(), mItem.sourcePos.line);
29829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return UNKNOWN_ERROR;
29839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
29849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::Entry::setItem(const SourcePos& sourcePos,
29869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       const String16& value,
29879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       const Vector<StringPool::entry_style_span>* style,
29889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       int32_t format,
29899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       const bool overwrite)
29909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
29919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Item item(sourcePos, false, value, style);
29929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mType == TYPE_BAG) {
29949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const Item& item(mBag.valueAt(0));
29959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sourcePos.error("Resource entry %s is already defined as a bag.\n"
29969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        "%s:%d: Originally defined here.\n",
29979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String8(mName).string(),
29989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        item.sourcePos.file.string(), item.sourcePos.line);
29999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
30009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
30019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if ( (mType != TYPE_UNKNOWN) && (overwrite == false) ) {
30029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sourcePos.error("Resource entry %s is already defined.\n"
30039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        "%s:%d: Originally defined here.\n",
30049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String8(mName).string(),
30059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        mItem.sourcePos.file.string(), mItem.sourcePos.line);
30069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
30079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3008f878e2d80c3a0afefe3b018d232df6066379e1d5Robert Greenwalt
30099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mType = TYPE_ITEM;
30109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mItem = item;
30119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mItemFormat = format;
30129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
30139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
30149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
30159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::Entry::addToBag(const SourcePos& sourcePos,
30169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        const String16& key, const String16& value,
30179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        const Vector<StringPool::entry_style_span>* style,
30189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        bool replace, bool isId, int32_t format)
30199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
30209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = makeItABag(sourcePos);
30219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != NO_ERROR) {
30229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return err;
30239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
30249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
30259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Item item(sourcePos, isId, value, style, format);
30269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
30279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // XXX NOTE: there is an error if you try to have a bag with two keys,
30289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // one an attr and one an id, with the same name.  Not something we
30299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // currently ever have to worry about.
30309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ssize_t origKey = mBag.indexOfKey(key);
30319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (origKey >= 0) {
30329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!replace) {
30339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const Item& item(mBag.valueAt(origKey));
30349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sourcePos.error("Resource entry %s already has bag item %s.\n"
30359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    "%s:%d: Originally defined here.\n",
30369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(mName).string(), String8(key).string(),
30379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    item.sourcePos.file.string(), item.sourcePos.line);
30389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return UNKNOWN_ERROR;
30399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
30409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //printf("Replacing %s with %s\n",
30419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //       String8(mBag.valueFor(key).value).string(), String8(value).string());
30429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mBag.replaceValueFor(key, item);
30439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
30449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
30459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mBag.add(key, item);
30469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
30479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
30489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
30494b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwaltstatus_t ResourceTable::Entry::emptyBag(const SourcePos& sourcePos)
30504b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt{
30514b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt    status_t err = makeItABag(sourcePos);
30524b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt    if (err != NO_ERROR) {
30534b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt        return err;
30544b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt    }
30554b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt
30564b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt    mBag.clear();
30574b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt    return NO_ERROR;
30584b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt}
30594b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt
30609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::Entry::generateAttributes(ResourceTable* table,
30619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                  const String16& package)
30629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
30639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 attr16("attr");
30649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 id16("id");
30659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t N = mBag.size();
30669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (size_t i=0; i<N; i++) {
30679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const String16& key = mBag.keyAt(i);
30689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const Item& it = mBag.valueAt(i);
30699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (it.isId) {
30709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!table->hasBagOrEntry(key, &id16, &package)) {
30719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String16 value("false");
30729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                status_t err = table->addEntry(SourcePos(String8("<generated>"), 0), package,
30739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                               id16, key, value);
30749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (err != NO_ERROR) {
30759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return err;
30769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
30779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
30789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (!table->hasBagOrEntry(key, &attr16, &package)) {
30799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
30809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 1
30819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//             fprintf(stderr, "ERROR: Bag attribute '%s' has not been defined.\n",
30829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//                     String8(key).string());
30839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//             const Item& item(mBag.valueAt(i));
30849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//             fprintf(stderr, "Referenced from file %s line %d\n",
30859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//                     item.sourcePos.file.string(), item.sourcePos.line);
30869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//             return UNKNOWN_ERROR;
30879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else
30889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            char numberStr[16];
30899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sprintf(numberStr, "%d", ResTable_map::TYPE_ANY);
30909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            status_t err = table->addBag(SourcePos("<generated>", 0), package,
30919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                         attr16, key, String16(""),
30929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                         String16("^type"),
30939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                         String16(numberStr), NULL, NULL);
30949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (err != NO_ERROR) {
30959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return err;
30969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
30979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
30989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
30999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
31009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
31019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
31029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
31039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::Entry::assignResourceIds(ResourceTable* table,
31049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                 const String16& package)
31059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
31069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool hasErrors = false;
31079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
31089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mType == TYPE_BAG) {
31099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const char* errorMsg;
31109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const String16 style16("style");
31119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const String16 attr16("attr");
31129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const String16 id16("id");
31139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mParentId = 0;
31149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mParent.size() > 0) {
3115f795e9a86d4f62e5314ef95978c3ea17d90975dbDianne Hackborn            mParentId = table->getResId(mParent, &style16, NULL, &errorMsg);
31169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mParentId == 0) {
31179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mPos.error("Error retrieving parent for item: %s '%s'.\n",
31189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        errorMsg, String8(mParent).string());
31199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                hasErrors = true;
31209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
31219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
31229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t N = mBag.size();
31239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (size_t i=0; i<N; i++) {
31249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const String16& key = mBag.keyAt(i);
31259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Item& it = mBag.editValueAt(i);
31269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            it.bagKeyId = table->getResId(key,
3127f795e9a86d4f62e5314ef95978c3ea17d90975dbDianne Hackborn                    it.isId ? &id16 : &attr16, NULL, &errorMsg);
31289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //printf("Bag key of %s: #%08x\n", String8(key).string(), it.bagKeyId);
31299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (it.bagKeyId == 0) {
31309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                it.sourcePos.error("Error: %s: %s '%s'.\n", errorMsg,
31319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String8(it.isId ? id16 : attr16).string(),
31329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String8(key).string());
31339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                hasErrors = true;
31349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
31359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
31369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
31379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
31389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
31399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
31409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::Entry::prepareFlatten(StringPool* strings, ResourceTable* table)
31419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
31429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mType == TYPE_ITEM) {
31439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Item& it = mItem;
31449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        AccessorCookie ac(it.sourcePos, String8(mName), String8(it.value));
31459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!table->stringToValue(&it.parsedValue, strings,
31469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  it.value, false, true, 0,
31479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  &it.style, NULL, &ac, mItemFormat)) {
31489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return UNKNOWN_ERROR;
31499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
31509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (mType == TYPE_BAG) {
31519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t N = mBag.size();
31529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (size_t i=0; i<N; i++) {
31539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const String16& key = mBag.keyAt(i);
31549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Item& it = mBag.editValueAt(i);
31559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            AccessorCookie ac(it.sourcePos, String8(key), String8(it.value));
31569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!table->stringToValue(&it.parsedValue, strings,
31579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                      it.value, false, true, it.bagKeyId,
31589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                      &it.style, NULL, &ac, it.format)) {
31599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return UNKNOWN_ERROR;
31609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
31619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
31629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
31639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPos.error("Error: entry %s is not a single item or a bag.\n",
31649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                   String8(mName).string());
31659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
31669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
31679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
31689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
31699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
31709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t ResourceTable::Entry::flatten(Bundle* bundle, const sp<AaptFile>& data, bool isPublic)
31719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
31729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t amt = 0;
31739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ResTable_entry header;
31749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    memset(&header, 0, sizeof(header));
31759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    header.size = htods(sizeof(header));
31769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const type ty = this != NULL ? mType : TYPE_ITEM;
31779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (this != NULL) {
31789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ty == TYPE_BAG) {
31799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            header.flags |= htods(header.FLAG_COMPLEX);
31809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
31819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (isPublic) {
31829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            header.flags |= htods(header.FLAG_PUBLIC);
31839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
31849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header.key.index = htodl(mNameIndex);
31859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
31869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (ty != TYPE_BAG) {
31879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        status_t err = data->writeData(&header, sizeof(header));
31889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != NO_ERROR) {
31899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "ERROR: out of memory creating ResTable_entry\n");
31909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return err;
31919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
31929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
31939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const Item& it = mItem;
31949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Res_value par;
31959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        memset(&par, 0, sizeof(par));
31969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        par.size = htods(it.parsedValue.size);
31979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        par.dataType = it.parsedValue.dataType;
31989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        par.res0 = it.parsedValue.res0;
31999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        par.data = htodl(it.parsedValue.data);
32009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        #if 0
32019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        printf("Writing item (%s): type=%d, data=0x%x, res0=0x%x\n",
32029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project               String8(mName).string(), it.parsedValue.dataType,
32039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project               it.parsedValue.data, par.res0);
32049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        #endif
32059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        err = data->writeData(&par, it.parsedValue.size);
32069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != NO_ERROR) {
32079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "ERROR: out of memory creating Res_value\n");
32089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return err;
32099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
32109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        amt += it.parsedValue.size;
32119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
32129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        size_t N = mBag.size();
32139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        size_t i;
32149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Create correct ordering of items.
32159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        KeyedVector<uint32_t, const Item*> items;
32169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (i=0; i<N; i++) {
32179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const Item& it = mBag.valueAt(i);
32189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            items.add(it.bagKeyId, &it);
32199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
32209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        N = items.size();
32219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
32229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ResTable_map_entry mapHeader;
32239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        memcpy(&mapHeader, &header, sizeof(header));
32249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mapHeader.size = htods(sizeof(mapHeader));
32259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mapHeader.parent.ident = htodl(mParentId);
32269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mapHeader.count = htodl(N);
32279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        status_t err = data->writeData(&mapHeader, sizeof(mapHeader));
32289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != NO_ERROR) {
32299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "ERROR: out of memory creating ResTable_entry\n");
32309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return err;
32319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
32329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
32339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (i=0; i<N; i++) {
32349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const Item& it = *items.valueAt(i);
32359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ResTable_map map;
32369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            map.name.ident = htodl(it.bagKeyId);
32379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            map.value.size = htods(it.parsedValue.size);
32389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            map.value.dataType = it.parsedValue.dataType;
32399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            map.value.res0 = it.parsedValue.res0;
32409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            map.value.data = htodl(it.parsedValue.data);
32419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            err = data->writeData(&map, sizeof(map));
32429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (err != NO_ERROR) {
32439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                fprintf(stderr, "ERROR: out of memory creating Res_value\n");
32449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return err;
32459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
32469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            amt += sizeof(map);
32479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
32489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
32499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return amt;
32509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
32519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
32529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResourceTable::ConfigList::appendComment(const String16& comment,
32539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                              bool onlyIfEmpty)
32549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
32559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (comment.size() <= 0) {
32569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
32579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
32589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (onlyIfEmpty && mComment.size() > 0) {
32599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
32609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
32619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mComment.size() > 0) {
32629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mComment.append(String16("\n"));
32639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
32649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mComment.append(comment);
32659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
32669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
32679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResourceTable::ConfigList::appendTypeComment(const String16& comment)
32689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
32699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (comment.size() <= 0) {
32709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
32719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
32729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mTypeComment.size() > 0) {
32739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mTypeComment.append(String16("\n"));
32749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
32759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mTypeComment.append(comment);
32769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
32779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
32789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::Type::addPublic(const SourcePos& sourcePos,
32799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        const String16& name,
32809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        const uint32_t ident)
32819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
32829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    #if 0
32839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t entryIdx = Res_GETENTRY(ident);
32849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (entryIdx < 0) {
32859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sourcePos.error("Public resource %s/%s has an invalid 0 identifier (0x%08x).\n",
32869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String8(mName).string(), String8(name).string(), ident);
32879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
32889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
32899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    #endif
32909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
32919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t typeIdx = Res_GETTYPE(ident);
32929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (typeIdx >= 0) {
32939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        typeIdx++;
32949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mPublicIndex > 0 && mPublicIndex != typeIdx) {
32959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sourcePos.error("Public resource %s/%s has conflicting type codes for its"
32969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    " public identifiers (0x%x vs 0x%x).\n",
32979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(mName).string(), String8(name).string(),
32989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mPublicIndex, typeIdx);
32999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return UNKNOWN_ERROR;
33009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
33019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPublicIndex = typeIdx;
33029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
33039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
33049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mFirstPublicSourcePos == NULL) {
33059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mFirstPublicSourcePos = new SourcePos(sourcePos);
33069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
33079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
33089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mPublic.indexOfKey(name) < 0) {
33099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPublic.add(name, Public(sourcePos, String16(), ident));
33109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
33119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Public& p = mPublic.editValueFor(name);
33129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (p.ident != ident) {
33139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sourcePos.error("Public resource %s/%s has conflicting public identifiers"
33149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    " (0x%08x vs 0x%08x).\n"
33159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    "%s:%d: Originally defined here.\n",
33169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(mName).string(), String8(name).string(), p.ident, ident,
33179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    p.sourcePos.file.string(), p.sourcePos.line);
33189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return UNKNOWN_ERROR;
33199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
33209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
33219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
33229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
33239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
33249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
332558c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackbornvoid ResourceTable::Type::canAddEntry(const String16& name)
332658c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn{
332758c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn    mCanAddEntries.add(name);
332858c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn}
332958c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn
33309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsp<ResourceTable::Entry> ResourceTable::Type::getEntry(const String16& entry,
33319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                       const SourcePos& sourcePos,
33329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                       const ResTable_config* config,
3333f878e2d80c3a0afefe3b018d232df6066379e1d5Robert Greenwalt                                                       bool doSetIndex,
333499080c7d9ad9e5ccfec70dd10e4c24468a960c45Xavier Ducrohet                                                       bool overlay,
333599080c7d9ad9e5ccfec70dd10e4c24468a960c45Xavier Ducrohet                                                       bool autoAddOverlay)
33369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
33379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int pos = -1;
33389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<ConfigList> c = mConfigs.valueFor(entry);
33399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (c == NULL) {
334099080c7d9ad9e5ccfec70dd10e4c24468a960c45Xavier Ducrohet        if (overlay && !autoAddOverlay && mCanAddEntries.indexOf(entry) < 0) {
334158c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn            sourcePos.error("Resource at %s appears in overlay but not"
334258c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                            " in the base package; use <add-resource> to add.\n",
334358c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                            String8(entry).string());
3344f878e2d80c3a0afefe3b018d232df6066379e1d5Robert Greenwalt            return NULL;
3345f878e2d80c3a0afefe3b018d232df6066379e1d5Robert Greenwalt        }
33469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        c = new ConfigList(entry, sourcePos);
33479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mConfigs.add(entry, c);
33489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pos = (int)mOrderedConfigs.size();
33499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOrderedConfigs.add(c);
33509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (doSetIndex) {
33519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            c->setEntryIndex(pos);
33529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
33539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
33549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
33559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ConfigDescription cdesc;
33569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (config) cdesc = *config;
33579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
33589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Entry> e = c->getEntries().valueFor(cdesc);
33599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (e == NULL) {
33609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (config != NULL) {
33619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            NOISY(printf("New entry at %s:%d: imsi:%d/%d lang:%c%c cnt:%c%c "
336269cb87576ba163b61bb0e6477a3b7c57a9b11d40Dianne Hackborn                    "orien:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d "
336369cb87576ba163b61bb0e6477a3b7c57a9b11d40Dianne Hackborn                    "sw%ddp w%ddp h%ddp\n",
33649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      sourcePos.file.string(), sourcePos.line,
33659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->mcc, config->mnc,
33669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->language[0] ? config->language[0] : '-',
33679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->language[1] ? config->language[1] : '-',
33689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->country[0] ? config->country[0] : '-',
33699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->country[1] ? config->country[1] : '-',
33709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->orientation,
33719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->touchscreen,
33729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->density,
33739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->keyboard,
33749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->inputFlags,
33759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->navigation,
33769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->screenWidth,
3377ebff8f92f13513ce37bd74759eb1db63f2220590Dianne Hackborn                      config->screenHeight,
337869cb87576ba163b61bb0e6477a3b7c57a9b11d40Dianne Hackborn                      config->smallestScreenWidthDp,
3379ebff8f92f13513ce37bd74759eb1db63f2220590Dianne Hackborn                      config->screenWidthDp,
3380ebff8f92f13513ce37bd74759eb1db63f2220590Dianne Hackborn                      config->screenHeightDp));
33819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
33829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            NOISY(printf("New entry at %s:%d: NULL config\n",
33839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      sourcePos.file.string(), sourcePos.line));
33849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
33859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        e = new Entry(entry, sourcePos);
33869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        c->addEntry(cdesc, e);
33879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*
33889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (doSetIndex) {
33899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (pos < 0) {
33909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (pos=0; pos<(int)mOrderedConfigs.size(); pos++) {
33919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (mOrderedConfigs[pos] == c) {
33929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        break;
33939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
33949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
33959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (pos >= (int)mOrderedConfigs.size()) {
33969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sourcePos.error("Internal error: config not found in mOrderedConfigs when adding entry");
33979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return NULL;
33989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
33999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
34009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            e->setEntryIndex(pos);
34019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
34029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        */
34039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
34049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mUniqueConfigs.add(cdesc);
34069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return e;
34089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
34099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::Type::applyPublicEntryOrder()
34119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
34129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t N = mOrderedConfigs.size();
34139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Vector<sp<ConfigList> > origOrder(mOrderedConfigs);
34149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool hasError = false;
34159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t i;
34179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (i=0; i<N; i++) {
34189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOrderedConfigs.replaceAt(NULL, i);
34199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
34209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t NP = mPublic.size();
34229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //printf("Ordering %d configs from %d public defs\n", N, NP);
34239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t j;
34249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (j=0; j<NP; j++) {
34259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const String16& name = mPublic.keyAt(j);
34269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const Public& p = mPublic.valueAt(j);
34279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int32_t idx = Res_GETENTRY(p.ident);
34289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //printf("Looking for entry \"%s\"/\"%s\" (0x%08x) in %d...\n",
34299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //       String8(mName).string(), String8(name).string(), p.ident, N);
34309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bool found = false;
34319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (i=0; i<N; i++) {
34329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<ConfigList> e = origOrder.itemAt(i);
34339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //printf("#%d: \"%s\"\n", i, String8(e->getName()).string());
34349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (e->getName() == name) {
34359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (idx >= (int32_t)mOrderedConfigs.size()) {
34369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    p.sourcePos.error("Public entry identifier 0x%x entry index "
34379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            "is larger than available symbols (index %d, total symbols %d).\n",
34389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            p.ident, idx, mOrderedConfigs.size());
34399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hasError = true;
34409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (mOrderedConfigs.itemAt(idx) == NULL) {
34419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    e->setPublic(true);
34429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    e->setPublicSourcePos(p.sourcePos);
34439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mOrderedConfigs.replaceAt(e, idx);
34449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    origOrder.removeAt(i);
34459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    N--;
34469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    found = true;
34479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
34489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
34499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sp<ConfigList> oe = mOrderedConfigs.itemAt(idx);
34509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    p.sourcePos.error("Multiple entry names declared for public entry"
34529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            " identifier 0x%x in type %s (%s vs %s).\n"
34539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            "%s:%d: Originally defined here.",
34549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            idx+1, String8(mName).string(),
34559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            String8(oe->getName()).string(),
34569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            String8(name).string(),
34579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            oe->getPublicSourcePos().file.string(),
34589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            oe->getPublicSourcePos().line);
34599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hasError = true;
34609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
34619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
34629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
34639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!found) {
34659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.sourcePos.error("Public symbol %s/%s declared here is not defined.",
34669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(mName).string(), String8(name).string());
34679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            hasError = true;
34689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
34699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
34709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //printf("Copying back in %d non-public configs, have %d\n", N, origOrder.size());
34729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (N != origOrder.size()) {
34749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        printf("Internal error: remaining private symbol count mismatch\n");
34759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        N = origOrder.size();
34769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
34779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    j = 0;
34799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (i=0; i<N; i++) {
34809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<ConfigList> e = origOrder.itemAt(i);
34819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // There will always be enough room for the remaining entries.
34829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (mOrderedConfigs.itemAt(j) != NULL) {
34839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            j++;
34849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
34859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOrderedConfigs.replaceAt(e, j);
34869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        j++;
34879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
34889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return hasError ? UNKNOWN_ERROR : NO_ERROR;
34909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
34919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResourceTable::Package::Package(const String16& name, ssize_t includedId)
34939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    : mName(name), mIncludedId(includedId),
34949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      mTypeStringsMapping(0xffffffff),
34959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      mKeyStringsMapping(0xffffffff)
34969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
34979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
34989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsp<ResourceTable::Type> ResourceTable::Package::getType(const String16& type,
35009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                        const SourcePos& sourcePos,
35019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                        bool doSetIndex)
35029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
35039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Type> t = mTypes.valueFor(type);
35049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (t == NULL) {
35059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        t = new Type(type, sourcePos);
35069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mTypes.add(type, t);
35079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOrderedTypes.add(t);
35089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (doSetIndex) {
35099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // For some reason the type's index is set to one plus the index
35109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // in the mOrderedTypes list, rather than just the index.
35119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            t->setIndex(mOrderedTypes.size());
35129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
35139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
35149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return t;
35159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
35169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
35179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::Package::setTypeStrings(const sp<AaptFile>& data)
35189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
35199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mTypeStringsData = data;
35209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = setStrings(data, &mTypeStrings, &mTypeStringsMapping);
35219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != NO_ERROR) {
35229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fprintf(stderr, "ERROR: Type string data is corrupt!\n");
35239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
35249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err;
35259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
35269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
35279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::Package::setKeyStrings(const sp<AaptFile>& data)
35289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
35299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mKeyStringsData = data;
35309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = setStrings(data, &mKeyStrings, &mKeyStringsMapping);
35319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != NO_ERROR) {
35329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fprintf(stderr, "ERROR: Key string data is corrupt!\n");
35339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
35349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err;
35359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
35369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
35379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::Package::setStrings(const sp<AaptFile>& data,
35389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                            ResStringPool* strings,
35399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                            DefaultKeyedVector<String16, uint32_t>* mappings)
35409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
35419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (data->getData() == NULL) {
35429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
35439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
35449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
35459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    NOISY(aout << "Setting restable string pool: "
35469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project          << HexDump(data->getData(), data->getSize()) << endl);
35479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
35489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = strings->setTo(data->getData(), data->getSize());
35499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err == NO_ERROR) {
35509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t N = strings->size();
35519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (size_t i=0; i<N; i++) {
35529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            size_t len;
35539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mappings->add(String16(strings->stringAt(i, &len)), i);
35549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
35559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
35569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err;
35579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
35589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
35599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::Package::applyPublicTypeOrder()
35609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
35619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t N = mOrderedTypes.size();
35629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Vector<sp<Type> > origOrder(mOrderedTypes);
35639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
35649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t i;
35659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (i=0; i<N; i++) {
35669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOrderedTypes.replaceAt(NULL, i);
35679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
35689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
35699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (i=0; i<N; i++) {
35709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<Type> t = origOrder.itemAt(i);
35719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int32_t idx = t->getPublicIndex();
35729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (idx > 0) {
35739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            idx--;
35749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            while (idx >= (int32_t)mOrderedTypes.size()) {
35759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mOrderedTypes.add();
35769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
35779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mOrderedTypes.itemAt(idx) != NULL) {
35789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sp<Type> ot = mOrderedTypes.itemAt(idx);
35799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                t->getFirstPublicSourcePos().error("Multiple type names declared for public type"
35809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        " identifier 0x%x (%s vs %s).\n"
35819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        "%s:%d: Originally defined here.",
35829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        idx, String8(ot->getName()).string(),
35839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String8(t->getName()).string(),
35849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ot->getFirstPublicSourcePos().file.string(),
35859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ot->getFirstPublicSourcePos().line);
35869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return UNKNOWN_ERROR;
35879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
35889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mOrderedTypes.replaceAt(t, idx);
35899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            origOrder.removeAt(i);
35909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            i--;
35919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            N--;
35929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
35939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
35949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
35959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t j=0;
35969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (i=0; i<N; i++) {
35979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<Type> t = origOrder.itemAt(i);
35989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // There will always be enough room for the remaining types.
35999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (mOrderedTypes.itemAt(j) != NULL) {
36009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            j++;
36019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
36029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOrderedTypes.replaceAt(t, j);
36039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
36049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
36069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
36079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsp<ResourceTable::Package> ResourceTable::getPackage(const String16& package)
36099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
36109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Package> p = mPackages.valueFor(package);
36119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (p == NULL) {
361257f4b77c89bafedf9468f9a636561c0c193405c9MÃ¥rten Kongstad        if (mBundle->getIsOverlayPackage()) {
361357f4b77c89bafedf9468f9a636561c0c193405c9MÃ¥rten Kongstad            p = new Package(package, 0x00);
361457f4b77c89bafedf9468f9a636561c0c193405c9MÃ¥rten Kongstad        } else if (mIsAppPackage) {
36159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mHaveAppPackage) {
36169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                fprintf(stderr, "Adding multiple application package resources; only one is allowed.\n"
36179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                "Use -x to create extended resources.\n");
36189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return NULL;
36199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
36209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mHaveAppPackage = true;
36219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p = new Package(package, 127);
36229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
36239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p = new Package(package, mNextPackageId);
36249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
36259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //printf("*** NEW PACKAGE: \"%s\" id=%d\n",
36269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //       String8(package).string(), p->getAssignedId());
36279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPackages.add(package, p);
36289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOrderedPackages.add(p);
36299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mNextPackageId++;
36309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
36319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return p;
36329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
36339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsp<ResourceTable::Type> ResourceTable::getType(const String16& package,
36359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                               const String16& type,
36369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                               const SourcePos& sourcePos,
36379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                               bool doSetIndex)
36389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
36399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Package> p = getPackage(package);
36409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (p == NULL) {
36419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
36429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
36439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return p->getType(type, sourcePos, doSetIndex);
36449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
36459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsp<ResourceTable::Entry> ResourceTable::getEntry(const String16& package,
36479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                 const String16& type,
36489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                 const String16& name,
36499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                 const SourcePos& sourcePos,
3650f878e2d80c3a0afefe3b018d232df6066379e1d5Robert Greenwalt                                                 bool overlay,
36519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                 const ResTable_config* config,
36529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                 bool doSetIndex)
36539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
36549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Type> t = getType(package, type, sourcePos, doSetIndex);
36559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (t == NULL) {
36569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
36579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
365899080c7d9ad9e5ccfec70dd10e4c24468a960c45Xavier Ducrohet    return t->getEntry(name, sourcePos, config, doSetIndex, overlay, mBundle->getAutoAddOverlay());
36599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
36609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsp<const ResourceTable::Entry> ResourceTable::getEntry(uint32_t resID,
36629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                       const ResTable_config* config) const
36639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
36649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int pid = Res_GETPACKAGE(resID)+1;
36659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t N = mOrderedPackages.size();
36669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t i;
36679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Package> p;
36689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (i=0; i<N; i++) {
36699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<Package> check = mOrderedPackages[i];
36709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (check->getAssignedId() == pid) {
36719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p = check;
36729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
36739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
36749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
36769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (p == NULL) {
3677dd931864209eac0b4182d7a0d1ca965fcc3b8c03Marco Nelissen        fprintf(stderr, "warning: Package not found for resource #%08x\n", resID);
36789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
36799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
36809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int tid = Res_GETTYPE(resID);
36829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (tid < 0 || tid >= (int)p->getOrderedTypes().size()) {
3683dd931864209eac0b4182d7a0d1ca965fcc3b8c03Marco Nelissen        fprintf(stderr, "warning: Type not found for resource #%08x\n", resID);
36849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
36859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
36869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Type> t = p->getOrderedTypes()[tid];
36879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int eid = Res_GETENTRY(resID);
36899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (eid < 0 || eid >= (int)t->getOrderedConfigs().size()) {
3690dd931864209eac0b4182d7a0d1ca965fcc3b8c03Marco Nelissen        fprintf(stderr, "warning: Entry not found for resource #%08x\n", resID);
36919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
36929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
36939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<ConfigList> c = t->getOrderedConfigs()[eid];
36959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (c == NULL) {
3696dd931864209eac0b4182d7a0d1ca965fcc3b8c03Marco Nelissen        fprintf(stderr, "warning: Entry not found for resource #%08x\n", resID);
36979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
36989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
36999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
37009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ConfigDescription cdesc;
37019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (config) cdesc = *config;
37029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Entry> e = c->getEntries().valueFor(cdesc);
37039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (c == NULL) {
3704dd931864209eac0b4182d7a0d1ca965fcc3b8c03Marco Nelissen        fprintf(stderr, "warning: Entry configuration not found for resource #%08x\n", resID);
37059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
37069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
37079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
37089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return e;
37099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
37109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
37119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst ResourceTable::Item* ResourceTable::getItem(uint32_t resID, uint32_t attrID) const
37129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
37139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<const Entry> e = getEntry(resID);
37149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (e == NULL) {
37159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
37169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
37179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
37189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t N = e->getBag().size();
37199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (size_t i=0; i<N; i++) {
37209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const Item& it = e->getBag().valueAt(i);
37219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (it.bagKeyId == 0) {
3722dd931864209eac0b4182d7a0d1ca965fcc3b8c03Marco Nelissen            fprintf(stderr, "warning: ID not yet assigned to '%s' in bag '%s'\n",
37239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(e->getName()).string(),
37249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(e->getBag().keyAt(i)).string());
37259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
37269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (it.bagKeyId == attrID) {
37279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return &it;
37289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
37299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
37309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
37319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NULL;
37329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
37339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
37349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::getItemValue(
37359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t resID, uint32_t attrID, Res_value* outValue)
37369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
37379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const Item* item = getItem(resID, attrID);
37389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
37399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool res = false;
37409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (item != NULL) {
37419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (item->evaluating) {
37429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<const Entry> e = getEntry(resID);
37439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const size_t N = e->getBag().size();
37449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            size_t i;
37459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (i=0; i<N; i++) {
37469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (&e->getBag().valueAt(i) == item) {
37479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
37489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
37499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3750dd931864209eac0b4182d7a0d1ca965fcc3b8c03Marco Nelissen            fprintf(stderr, "warning: Circular reference detected in key '%s' of bag '%s'\n",
37519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(e->getName()).string(),
37529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(e->getBag().keyAt(i)).string());
37539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
37549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
37559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        item->evaluating = true;
37569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        res = stringToValue(outValue, NULL, item->value, false, false, item->bagKeyId);
37579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NOISY(
37589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (res) {
37599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                printf("getItemValue of #%08x[#%08x] (%s): type=#%08x, data=#%08x\n",
37609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                       resID, attrID, String8(getEntry(resID)->getName()).string(),
37619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                       outValue->dataType, outValue->data);
37629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
37639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                printf("getItemValue of #%08x[#%08x]: failed\n",
37649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                       resID, attrID);
37659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
37669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        );
37679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        item->evaluating = false;
37689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
37699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return res;
37709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3771