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