19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Copyright 2006 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Build resource files from raw assets.
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "ResourceTable.h"
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "XMLNode.h"
10e6b680364dd992907a8d2037685a2e500d188dfbDianne Hackborn#include "ResourceFilter.h"
1167b38c44e8b04b97e357664804d593823b2a34edChristopher Tate#include "ResourceIdCache.h"
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13b13b9bdad2baf6ad1ec2e56b6b7598fa20f55fc4Mathias Agopian#include <androidfw/ResourceTypes.h>
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/ByteOrder.h>
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdarg.h>
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define NOISY(x) //x
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t compileXmlFile(const sp<AaptAssets>& assets,
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const sp<AaptFile>& target,
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ResourceTable* table,
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        int options)
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<XMLNode> root = XMLNode::parse(target);
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (root == NULL) {
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
28a96cbb435d7b2197ab2b61fd98d14cbd6e0c5c3dDianne Hackborn
29a96cbb435d7b2197ab2b61fd98d14cbd6e0c5c3dDianne Hackborn    return compileXmlFile(assets, root, target, table, options);
30a96cbb435d7b2197ab2b61fd98d14cbd6e0c5c3dDianne Hackborn}
31a96cbb435d7b2197ab2b61fd98d14cbd6e0c5c3dDianne Hackborn
32a96cbb435d7b2197ab2b61fd98d14cbd6e0c5c3dDianne Hackbornstatus_t compileXmlFile(const sp<AaptAssets>& assets,
33cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackborn                        const sp<AaptFile>& target,
34cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackborn                        const sp<AaptFile>& outTarget,
35cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackborn                        ResourceTable* table,
36cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackborn                        int options)
37cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackborn{
38cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackborn    sp<XMLNode> root = XMLNode::parse(target);
39cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackborn    if (root == NULL) {
40cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackborn        return UNKNOWN_ERROR;
41cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackborn    }
42cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackborn
43cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackborn    return compileXmlFile(assets, root, outTarget, table, options);
44cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackborn}
45cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackborn
46cf244ada58539ce857ec041d7288d0271204fbb6Dianne Hackbornstatus_t compileXmlFile(const sp<AaptAssets>& assets,
47a96cbb435d7b2197ab2b61fd98d14cbd6e0c5c3dDianne Hackborn                        const sp<XMLNode>& root,
48a96cbb435d7b2197ab2b61fd98d14cbd6e0c5c3dDianne Hackborn                        const sp<AaptFile>& target,
49a96cbb435d7b2197ab2b61fd98d14cbd6e0c5c3dDianne Hackborn                        ResourceTable* table,
50a96cbb435d7b2197ab2b61fd98d14cbd6e0c5c3dDianne Hackborn                        int options)
51a96cbb435d7b2197ab2b61fd98d14cbd6e0c5c3dDianne Hackborn{
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if ((options&XML_COMPILE_STRIP_WHITESPACE) != 0) {
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        root->removeWhitespace(true, NULL);
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else  if ((options&XML_COMPILE_COMPACT_WHITESPACE) != 0) {
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        root->removeWhitespace(false, NULL);
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5819138468caf7050d482dc15f35a344eab11bb756Kenny Root    if ((options&XML_COMPILE_UTF8) != 0) {
5919138468caf7050d482dc15f35a344eab11bb756Kenny Root        root->setUTF8(true);
6019138468caf7050d482dc15f35a344eab11bb756Kenny Root    }
6119138468caf7050d482dc15f35a344eab11bb756Kenny Root
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool hasErrors = false;
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if ((options&XML_COMPILE_ASSIGN_ATTRIBUTE_IDS) != 0) {
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        status_t err = root->assignResourceIds(assets, table);
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != NO_ERROR) {
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            hasErrors = true;
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = root->parseValues(assets, table);
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != NO_ERROR) {
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        hasErrors = true;
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (hasErrors) {
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    NOISY(printf("Input XML Resource:\n"));
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    NOISY(root->print());
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    err = root->flatten(target,
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (options&XML_COMPILE_STRIP_COMMENTS) != 0,
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (options&XML_COMPILE_STRIP_RAW_VALUES) != 0);
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != NO_ERROR) {
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return err;
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    NOISY(printf("Output XML Resource:\n"));
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    NOISY(ResXMLTree tree;
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        tree.setTo(target->getData(), target->getSize());
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        printXMLBlock(&tree));
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    target->setCompressionMethod(ZipEntry::kCompressDeflated);
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err;
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#undef NOISY
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define NOISY(x) //x
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct flag_entry
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char16_t* name;
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t nameLen;
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t value;
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char* description;
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char16_t referenceArray[] =
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { 'r', 'e', 'f', 'e', 'r', 'e', 'n', 'c', 'e' };
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char16_t stringArray[] =
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { 's', 't', 'r', 'i', 'n', 'g' };
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char16_t integerArray[] =
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { 'i', 'n', 't', 'e', 'g', 'e', 'r' };
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char16_t booleanArray[] =
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { 'b', 'o', 'o', 'l', 'e', 'a', 'n' };
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char16_t colorArray[] =
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { 'c', 'o', 'l', 'o', 'r' };
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char16_t floatArray[] =
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { 'f', 'l', 'o', 'a', 't' };
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char16_t dimensionArray[] =
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n' };
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char16_t fractionArray[] =
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { 'f', 'r', 'a', 'c', 't', 'i', 'o', 'n' };
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char16_t enumArray[] =
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { 'e', 'n', 'u', 'm' };
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char16_t flagsArray[] =
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { 'f', 'l', 'a', 'g', 's' };
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const flag_entry gFormatFlags[] = {
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { referenceArray, sizeof(referenceArray)/2, ResTable_map::TYPE_REFERENCE,
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "a reference to another resource, in the form \"<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>\"\n"
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "or to a theme attribute in the form \"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>\"."},
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { stringArray, sizeof(stringArray)/2, ResTable_map::TYPE_STRING,
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "a string value, using '\\\\;' to escape characters such as '\\\\n' or '\\\\uxxxx' for a unicode character." },
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { integerArray, sizeof(integerArray)/2, ResTable_map::TYPE_INTEGER,
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "an integer value, such as \"<code>100</code>\"." },
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { booleanArray, sizeof(booleanArray)/2, ResTable_map::TYPE_BOOLEAN,
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "a boolean value, either \"<code>true</code>\" or \"<code>false</code>\"." },
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { colorArray, sizeof(colorArray)/2, ResTable_map::TYPE_COLOR,
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "a color value, in the form of \"<code>#<i>rgb</i></code>\", \"<code>#<i>argb</i></code>\",\n"
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "\"<code>#<i>rrggbb</i></code>\", or \"<code>#<i>aarrggbb</i></code>\"." },
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { floatArray, sizeof(floatArray)/2, ResTable_map::TYPE_FLOAT,
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "a floating point value, such as \"<code>1.2</code>\"."},
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { dimensionArray, sizeof(dimensionArray)/2, ResTable_map::TYPE_DIMENSION,
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "a dimension value, which is a floating point number appended with a unit such as \"<code>14.5sp</code>\".\n"
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size),\n"
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "in (inches), mm (millimeters)." },
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { fractionArray, sizeof(fractionArray)/2, ResTable_map::TYPE_FRACTION,
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The 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"
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "The % suffix always means a percentage of the base size; the optional %p suffix provides a size relative to\n"
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "some parent container." },
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { enumArray, sizeof(enumArray)/2, ResTable_map::TYPE_ENUM, NULL },
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { flagsArray, sizeof(flagsArray)/2, ResTable_map::TYPE_FLAGS, NULL },
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { NULL, 0, 0, NULL }
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char16_t suggestedArray[] = { 's', 'u', 'g', 'g', 'e', 's', 't', 'e', 'd' };
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const flag_entry l10nRequiredFlags[] = {
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { suggestedArray, sizeof(suggestedArray)/2, ResTable_map::L10N_SUGGESTED, NULL },
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { NULL, 0, 0, NULL }
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char16_t nulStr[] = { 0 };
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic uint32_t parse_flags(const char16_t* str, size_t len,
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             const flag_entry* flags, bool* outError = NULL)
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (len > 0 && isspace(*str)) {
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        str++;
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        len--;
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (len > 0 && isspace(str[len-1])) {
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        len--;
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char16_t* const end = str + len;
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t value = 0;
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (str < end) {
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const char16_t* div = str;
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (div < end && *div != '|') {
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            div++;
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const flag_entry* cur = flags;
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (cur->name) {
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (strzcmp16(cur->name, cur->nameLen, str, div-str) == 0) {
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                value |= cur->value;
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            cur++;
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!cur->name) {
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (outError) *outError = true;
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        str = div < end ? div+1 : div;
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (outError) *outError = false;
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return value;
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic String16 mayOrMust(int type, int flags)
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if ((type&(~flags)) == 0) {
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return String16("<p>Must");
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return String16("<p>May");
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void appendTypeInfo(ResourceTable* outTable, const String16& pkg,
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const String16& typeName, const String16& ident, int type,
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const flag_entry* flags)
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool hadType = false;
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (flags->name) {
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((type&flags->value) != 0 && flags->description != NULL) {
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String16 fullMsg(mayOrMust(type, flags->value));
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fullMsg.append(String16(" be "));
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fullMsg.append(String16(flags->description));
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            outTable->appendTypeComment(pkg, typeName, ident, fullMsg);
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            hadType = true;
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        flags++;
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (hadType && (type&ResTable_map::TYPE_REFERENCE) == 0) {
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        outTable->appendTypeComment(pkg, typeName, ident,
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String16("<p>This may also be a reference to a resource (in the form\n"
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                         "\"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>\") or\n"
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                         "theme attribute (in the form\n"
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                         "\"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>\")\n"
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                         "containing a value of this type."));
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct PendingAttribute
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 myPackage;
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const SourcePos sourcePos;
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const bool appendComment;
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t type;
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String16 ident;
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String16 comment;
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool hasErrors;
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool added;
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    PendingAttribute(String16 _package, const sp<AaptFile>& in,
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ResXMLTree& block, bool _appendComment)
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        : myPackage(_package)
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        , sourcePos(in->getPrintableSource(), block.getLineNumber())
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        , appendComment(_appendComment)
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        , type(ResTable_map::TYPE_ANY)
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        , hasErrors(false)
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        , added(false)
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t createIfNeeded(ResourceTable* outTable)
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (added || hasErrors) {
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return NO_ERROR;
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        added = true;
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String16 attr16("attr");
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (outTable->hasBagOrEntry(myPackage, attr16, ident)) {
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sourcePos.error("Attribute \"%s\" has already been defined\n",
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(ident).string());
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            hasErrors = true;
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return UNKNOWN_ERROR;
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        char numberStr[16];
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sprintf(numberStr, "%d", type);
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        status_t err = outTable->addBag(sourcePos, myPackage,
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                attr16, ident, String16(""),
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String16("^type"),
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String16(numberStr), NULL, NULL);
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != NO_ERROR) {
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            hasErrors = true;
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return err;
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        outTable->appendComment(myPackage, attr16, ident, comment, appendComment);
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //printf("Attribute %s comment: %s\n", String8(ident).string(),
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //     String8(comment).string());
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return err;
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic status_t compileAttribute(const sp<AaptFile>& in,
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 ResXMLTree& block,
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16& myPackage,
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 ResourceTable* outTable,
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 String16* outIdent = NULL,
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 bool inStyleable = false)
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    PendingAttribute attr(myPackage, in, block, inStyleable);
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 attr16("attr");
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 id16("id");
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Attribute type constants.
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 enum16("enum");
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 flag16("flag");
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ResXMLTree::event_code_t code;
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t len;
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err;
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ssize_t identIdx = block.indexOfAttribute(NULL, "name");
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (identIdx >= 0) {
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        attr.ident = String16(block.getAttributeStringValue(identIdx, &len));
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (outIdent) {
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            *outIdent = attr.ident;
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        attr.sourcePos.error("A 'name' attribute is required for <attr>\n");
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        attr.hasErrors = true;
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    attr.comment = String16(
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            block.getComment(&len) ? block.getComment(&len) : nulStr);
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ssize_t typeIdx = block.indexOfAttribute(NULL, "format");
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (typeIdx >= 0) {
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String16 typeStr = String16(block.getAttributeStringValue(typeIdx, &len));
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        attr.type = parse_flags(typeStr.string(), typeStr.size(), gFormatFlags);
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (attr.type == 0) {
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            attr.sourcePos.error("Tag <attr> 'format' attribute value \"%s\" not valid\n",
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(typeStr).string());
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            attr.hasErrors = true;
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        attr.createIfNeeded(outTable);
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (!inStyleable) {
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Attribute definitions outside of styleables always define the
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // attribute as a generic value.
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        attr.createIfNeeded(outTable);
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //printf("Attribute %s: type=0x%08x\n", String8(attr.ident).string(), attr.type);
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ssize_t minIdx = block.indexOfAttribute(NULL, "min");
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (minIdx >= 0) {
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String16 val = String16(block.getAttributeStringValue(minIdx, &len));
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!ResTable::stringToInt(val.string(), val.size(), NULL)) {
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            attr.sourcePos.error("Tag <attr> 'min' attribute must be a number, not \"%s\"\n",
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(val).string());
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            attr.hasErrors = true;
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        attr.createIfNeeded(outTable);
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!attr.hasErrors) {
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident,
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String16(""), String16("^min"), String16(val), NULL, NULL);
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (err != NO_ERROR) {
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                attr.hasErrors = true;
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ssize_t maxIdx = block.indexOfAttribute(NULL, "max");
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (maxIdx >= 0) {
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String16 val = String16(block.getAttributeStringValue(maxIdx, &len));
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!ResTable::stringToInt(val.string(), val.size(), NULL)) {
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            attr.sourcePos.error("Tag <attr> 'max' attribute must be a number, not \"%s\"\n",
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(val).string());
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            attr.hasErrors = true;
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        attr.createIfNeeded(outTable);
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!attr.hasErrors) {
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident,
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String16(""), String16("^max"), String16(val), NULL, NULL);
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            attr.hasErrors = true;
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if ((minIdx >= 0 || maxIdx >= 0) && (attr.type&ResTable_map::TYPE_INTEGER) == 0) {
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        attr.sourcePos.error("Tag <attr> must have format=integer attribute if using max or min\n");
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        attr.hasErrors = true;
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ssize_t l10nIdx = block.indexOfAttribute(NULL, "localization");
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (l10nIdx >= 0) {
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const uint16_t* str = block.getAttributeStringValue(l10nIdx, &len);
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bool error;
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        uint32_t l10n_required = parse_flags(str, len, l10nRequiredFlags, &error);
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (error) {
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            attr.sourcePos.error("Tag <attr> 'localization' attribute value \"%s\" not valid\n",
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(str).string());
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            attr.hasErrors = true;
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        attr.createIfNeeded(outTable);
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!attr.hasErrors) {
401f5a7c121dd3abb9763c30115c772fd1fc03caea2Kenny Root            char buf[11];
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sprintf(buf, "%d", l10n_required);
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident,
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String16(""), String16("^l10n"), String16(buf), NULL, NULL);
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (err != NO_ERROR) {
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                attr.hasErrors = true;
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String16 enumOrFlagsComment;
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (code == ResXMLTree::START_TAG) {
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            uint32_t localType = 0;
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (strcmp16(block.getElementName(&len), enum16.string()) == 0) {
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                localType = ResTable_map::TYPE_ENUM;
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), flag16.string()) == 0) {
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                localType = ResTable_map::TYPE_FLAGS;
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                SourcePos(in->getPrintableSource(), block.getLineNumber())
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        .error("Tag <%s> can not appear inside <attr>, only <enum> or <flag>\n",
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String8(block.getElementName(&len)).string());
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return UNKNOWN_ERROR;
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            attr.createIfNeeded(outTable);
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (attr.type == ResTable_map::TYPE_ANY) {
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // No type was explicitly stated, so supplying enum tags
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // implicitly creates an enum or flag.
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                attr.type = 0;
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if ((attr.type&(ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS)) == 0) {
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Wasn't originally specified as an enum, so update its type.
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                attr.type |= localType;
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!attr.hasErrors) {
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    char numberStr[16];
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sprintf(numberStr, "%d", attr.type);
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    err = outTable->addBag(SourcePos(in->getPrintableSource(), block.getLineNumber()),
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            myPackage, attr16, attr.ident, String16(""),
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            String16("^type"), String16(numberStr), NULL, NULL, true);
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (err != NO_ERROR) {
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        attr.hasErrors = true;
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if ((uint32_t)(attr.type&(ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS)) != localType) {
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (localType == ResTable_map::TYPE_ENUM) {
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    SourcePos(in->getPrintableSource(), block.getLineNumber())
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            .error("<enum> attribute can not be used inside a flags format\n");
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    attr.hasErrors = true;
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    SourcePos(in->getPrintableSource(), block.getLineNumber())
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            .error("<flag> attribute can not be used inside a enum format\n");
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    attr.hasErrors = true;
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String16 itemIdent;
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ssize_t itemIdentIdx = block.indexOfAttribute(NULL, "name");
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (itemIdentIdx >= 0) {
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                itemIdent = String16(block.getAttributeStringValue(itemIdentIdx, &len));
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                SourcePos(in->getPrintableSource(), block.getLineNumber())
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        .error("A 'name' attribute is required for <enum> or <flag>\n");
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                attr.hasErrors = true;
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String16 value;
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ssize_t valueIdx = block.indexOfAttribute(NULL, "value");
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (valueIdx >= 0) {
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                value = String16(block.getAttributeStringValue(valueIdx, &len));
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                SourcePos(in->getPrintableSource(), block.getLineNumber())
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        .error("A 'value' attribute is required for <enum> or <flag>\n");
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                attr.hasErrors = true;
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!attr.hasErrors && !ResTable::stringToInt(value.string(), value.size(), NULL)) {
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                SourcePos(in->getPrintableSource(), block.getLineNumber())
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        .error("Tag <enum> or <flag> 'value' attribute must be a number,"
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        " not \"%s\"\n",
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String8(value).string());
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                attr.hasErrors = true;
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Make sure an id is defined for this enum/flag identifier...
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!attr.hasErrors && !outTable->hasBagOrEntry(itemIdent, &id16, &myPackage)) {
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                err = outTable->startBag(SourcePos(in->getPrintableSource(), block.getLineNumber()),
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                         myPackage, id16, itemIdent, String16(), NULL);
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (err != NO_ERROR) {
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    attr.hasErrors = true;
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!attr.hasErrors) {
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (enumOrFlagsComment.size() == 0) {
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    enumOrFlagsComment.append(mayOrMust(attr.type,
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS));
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    enumOrFlagsComment.append((attr.type&ResTable_map::TYPE_ENUM)
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       ? String16(" be one of the following constant values.")
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       : String16(" be one or more (separated by '|') of the following constant values."));
50359ad275e937bb3c32e59bc01d86f484e7b4bdbe1Dirk Dougherty                    enumOrFlagsComment.append(String16("</p>\n<table>\n"
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                "<colgroup align=\"left\" />\n"
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                "<colgroup align=\"left\" />\n"
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                "<colgroup align=\"left\" />\n"
50759ad275e937bb3c32e59bc01d86f484e7b4bdbe1Dirk Dougherty                                                "<tr><th>Constant</th><th>Value</th><th>Description</th></tr>"));
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
51059ad275e937bb3c32e59bc01d86f484e7b4bdbe1Dirk Dougherty                enumOrFlagsComment.append(String16("\n<tr><td><code>"));
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                enumOrFlagsComment.append(itemIdent);
51259ad275e937bb3c32e59bc01d86f484e7b4bdbe1Dirk Dougherty                enumOrFlagsComment.append(String16("</code></td><td>"));
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                enumOrFlagsComment.append(value);
51459ad275e937bb3c32e59bc01d86f484e7b4bdbe1Dirk Dougherty                enumOrFlagsComment.append(String16("</td><td>"));
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (block.getComment(&len)) {
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    enumOrFlagsComment.append(String16(block.getComment(&len)));
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
51859ad275e937bb3c32e59bc01d86f484e7b4bdbe1Dirk Dougherty                enumOrFlagsComment.append(String16("</td></tr>"));
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                err = outTable->addBag(SourcePos(in->getPrintableSource(), block.getLineNumber()),
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       myPackage,
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       attr16, attr.ident, String16(""),
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       itemIdent, value, NULL, NULL, false, true);
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (err != NO_ERROR) {
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    attr.hasErrors = true;
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (code == ResXMLTree::END_TAG) {
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (strcmp16(block.getElementName(&len), attr16.string()) == 0) {
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if ((attr.type&ResTable_map::TYPE_ENUM) != 0) {
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (strcmp16(block.getElementName(&len), enum16.string()) != 0) {
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    SourcePos(in->getPrintableSource(), block.getLineNumber())
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            .error("Found tag </%s> where </enum> is expected\n",
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            String8(block.getElementName(&len)).string());
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return UNKNOWN_ERROR;
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (strcmp16(block.getElementName(&len), flag16.string()) != 0) {
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    SourcePos(in->getPrintableSource(), block.getLineNumber())
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            .error("Found tag </%s> where </flag> is expected\n",
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            String8(block.getElementName(&len)).string());
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return UNKNOWN_ERROR;
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!attr.hasErrors && attr.added) {
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        appendTypeInfo(outTable, myPackage, attr16, attr.ident, attr.type, gFormatFlags);
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!attr.hasErrors && enumOrFlagsComment.size() > 0) {
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        enumOrFlagsComment.append(String16("\n</table>"));
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        outTable->appendTypeComment(myPackage, attr16, attr.ident, enumOrFlagsComment);
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool localeIsDefined(const ResTable_config& config)
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return config.locale == 0;
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t parseAndAddBag(Bundle* bundle,
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const sp<AaptFile>& in,
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ResXMLTree* block,
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const ResTable_config& config,
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const String16& myPackage,
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const String16& curType,
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const String16& ident,
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const String16& parentIdent,
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const String16& itemIdent,
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        int32_t curFormat,
57815fe2cb73b0770316db302f6502f568062d68e74Kenny Root                        bool isFormatted,
57990964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer                        const String16& product,
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        bool pseudolocalize,
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const bool overwrite,
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ResourceTable* outTable)
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err;
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 item16("item");
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String16 str;
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Vector<StringPool::entry_style_span> spans;
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    err = parseStyledString(bundle, in->getPrintableSource().string(),
59015fe2cb73b0770316db302f6502f568062d68e74Kenny Root                            block, item16, &str, &spans, isFormatted,
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            pseudolocalize);
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != NO_ERROR) {
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return err;
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    NOISY(printf("Adding resource bag entry l=%c%c c=%c%c orien=%d d=%d "
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 " pid=%s, bag=%s, id=%s: %s\n",
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 config.language[0], config.language[1],
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 config.country[0], config.country[1],
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 config.orientation, config.density,
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 String8(parentIdent).string(),
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 String8(ident).string(),
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 String8(itemIdent).string(),
6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 String8(str).string()));
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    err = outTable->addBag(SourcePos(in->getPrintableSource(), block->getLineNumber()),
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           myPackage, curType, ident, parentIdent, itemIdent, str,
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           &spans, &config, overwrite, false, curFormat);
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err;
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
61290964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer/*
61390964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer * Returns true if needle is one of the elements in the comma-separated list
61490964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer * haystack, false otherwise.
61590964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer */
61690964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischerbool isInProductList(const String16& needle, const String16& haystack) {
61790964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer    const char16_t *needle2 = needle.string();
61890964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer    const char16_t *haystack2 = haystack.string();
61990964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer    size_t needlesize = needle.size();
62090964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer
62190964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer    while (*haystack2 != '\0') {
62290964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer        if (strncmp16(haystack2, needle2, needlesize) == 0) {
62390964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer            if (haystack2[needlesize] == '\0' || haystack2[needlesize] == ',') {
62490964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer                return true;
62590964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer            }
62690964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer        }
62790964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer
62890964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer        while (*haystack2 != '\0' && *haystack2 != ',') {
62990964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer            haystack2++;
63090964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer        }
63190964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer        if (*haystack2 == ',') {
63290964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer            haystack2++;
63390964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer        }
63490964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer    }
63590964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer
63690964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer    return false;
63790964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer}
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t parseAndAddEntry(Bundle* bundle,
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const sp<AaptFile>& in,
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ResXMLTree* block,
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const ResTable_config& config,
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const String16& myPackage,
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const String16& curType,
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const String16& ident,
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const String16& curTag,
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        bool curIsStyled,
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        int32_t curFormat,
64915fe2cb73b0770316db302f6502f568062d68e74Kenny Root                        bool isFormatted,
65090964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer                        const String16& product,
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        bool pseudolocalize,
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const bool overwrite,
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ResourceTable* outTable)
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err;
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String16 str;
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Vector<StringPool::entry_style_span> spans;
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    err = parseStyledString(bundle, in->getPrintableSource().string(), block,
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            curTag, &str, curIsStyled ? &spans : NULL,
66115fe2cb73b0770316db302f6502f568062d68e74Kenny Root                            isFormatted, pseudolocalize);
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err < NO_ERROR) {
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return err;
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
66790964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer    /*
66890964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer     * If a product type was specified on the command line
66990964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer     * and also in the string, and the two are not the same,
67090964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer     * return without adding the string.
67190964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer     */
67290964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer
67390964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer    const char *bundleProduct = bundle->getProduct();
67490964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer    if (bundleProduct == NULL) {
67590964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer        bundleProduct = "";
67690964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer    }
67790964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer
67890964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer    if (product.size() != 0) {
67990964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer        /*
68090964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer         * If the command-line-specified product is empty, only "default"
68190964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer         * matches.  Other variants are skipped.  This is so generation
68290964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer         * of the R.java file when the product is not known is predictable.
68390964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer         */
68490964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer
68590964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer        if (bundleProduct[0] == '\0') {
68690964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer            if (strcmp16(String16("default").string(), product.string()) != 0) {
68790964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer                return NO_ERROR;
68890964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer            }
68990964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer        } else {
69090964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer            /*
69190964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer             * The command-line product is not empty.
69290964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer             * If the product for this string is on the command-line list,
69390964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer             * it matches.  "default" also matches, but only if nothing
69490964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer             * else has matched already.
69590964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer             */
69690964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer
69790964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer            if (isInProductList(product, String16(bundleProduct))) {
69890964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer                ;
69990964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer            } else if (strcmp16(String16("default").string(), product.string()) == 0 &&
700914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer                       !outTable->hasBagOrEntry(myPackage, curType, ident, config)) {
70190964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer                ;
70290964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer            } else {
70390964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer                return NO_ERROR;
70490964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer            }
70590964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer        }
70690964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer    }
70790964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    NOISY(printf("Adding resource entry l=%c%c c=%c%c orien=%d d=%d id=%s: %s\n",
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 config.language[0], config.language[1],
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 config.country[0], config.country[1],
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 config.orientation, config.density,
7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 String8(ident).string(), String8(str).string()));
7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    err = outTable->addEntry(SourcePos(in->getPrintableSource(), block->getLineNumber()),
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             myPackage, curType, ident, str, &spans, &config,
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             false, curFormat, overwrite);
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err;
7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t compileResourceFile(Bundle* bundle,
7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             const sp<AaptAssets>& assets,
7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             const sp<AaptFile>& in,
7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             const ResTable_config& defParams,
7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             const bool overwrite,
7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             ResourceTable* outTable)
7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ResXMLTree block;
7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = parseXMLResource(in, &block, false, true);
7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != NO_ERROR) {
7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return err;
7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Top-level tag.
7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 resources16("resources");
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Identifier declaration tags.
7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 declare_styleable16("declare-styleable");
7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 attr16("attr");
7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Data creation organizational tags.
7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 string16("string");
7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 drawable16("drawable");
7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 color16("color");
7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 bool16("bool");
7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 integer16("integer");
7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 dimen16("dimen");
7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 fraction16("fraction");
7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 style16("style");
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 plurals16("plurals");
7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 array16("array");
7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 string_array16("string-array");
7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 integer_array16("integer-array");
7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 public16("public");
755f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn    const String16 public_padding16("public-padding");
7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 private_symbols16("private-symbols");
7571644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn    const String16 java_symbol16("java-symbol");
75858c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn    const String16 add_resource16("add-resource");
7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 skip16("skip");
7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 eat_comment16("eat-comment");
7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Data creation tags.
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 bag16("bag");
7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 item16("item");
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Attribute type constants.
7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 enum16("enum");
7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // plural values
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 other16("other");
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 quantityOther16("^other");
7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 zero16("zero");
7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 quantityZero16("^zero");
7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 one16("one");
7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 quantityOne16("^one");
7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 two16("two");
7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 quantityTwo16("^two");
7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 few16("few");
7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 quantityFew16("^few");
7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 many16("many");
7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 quantityMany16("^many");
7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // useful attribute names and special values
7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 name16("name");
7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 translatable16("translatable");
78615fe2cb73b0770316db302f6502f568062d68e74Kenny Root    const String16 formatted16("formatted");
7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 false16("false");
7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 myPackage(assets->getPackage());
7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool hasErrors = false;
79215fe2cb73b0770316db302f6502f568062d68e74Kenny Root
79315fe2cb73b0770316db302f6502f568062d68e74Kenny Root    bool fileIsTranslatable = true;
79415fe2cb73b0770316db302f6502f568062d68e74Kenny Root    if (strstr(in->getPrintableSource().string(), "donottranslate") != NULL) {
79515fe2cb73b0770316db302f6502f568062d68e74Kenny Root        fileIsTranslatable = false;
79615fe2cb73b0770316db302f6502f568062d68e74Kenny Root    }
79715fe2cb73b0770316db302f6502f568062d68e74Kenny Root
798f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn    DefaultKeyedVector<String16, uint32_t> nextPublicId(0);
7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ResXMLTree::event_code_t code;
8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    do {
8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        code = block.next();
8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } while (code == ResXMLTree::START_NAMESPACE);
8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t len;
8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (code != ResXMLTree::START_TAG) {
8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "No start tag found\n");
8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (strcmp16(block.getElementName(&len), resources16.string()) != 0) {
8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "Invalid start tag %s\n", String8(block.getElementName(&len)).string());
8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ResTable_config curParams(defParams);
8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ResTable_config pseudoParams(curParams);
8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pseudoParams.language[0] = 'z';
8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pseudoParams.language[1] = 'z';
8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pseudoParams.country[0] = 'Z';
8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pseudoParams.country[1] = 'Z';
8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (code == ResXMLTree::START_TAG) {
8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const String16* curTag = NULL;
8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String16 curType;
8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int32_t curFormat = ResTable_map::TYPE_ANY;
8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bool curIsBag = false;
8311aa8170e6a448afad86e5d62927d3b8ca4cd9707Robert Greenwalt            bool curIsBagReplaceOnOverwrite = false;
8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bool curIsStyled = false;
8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bool curIsPseudolocalizable = false;
83415fe2cb73b0770316db302f6502f568062d68e74Kenny Root            bool curIsFormatted = fileIsTranslatable;
8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bool localHasErrors = false;
8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {
8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                while ((code=block.next()) != ResXMLTree::END_DOCUMENT
8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        && code != ResXMLTree::BAD_DOCUMENT) {
8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (code == ResXMLTree::END_TAG) {
8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {
8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            break;
8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) {
8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                while ((code=block.next()) != ResXMLTree::END_DOCUMENT
8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        && code != ResXMLTree::BAD_DOCUMENT) {
8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (code == ResXMLTree::END_TAG) {
8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) {
8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            break;
8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), public16.string()) == 0) {
8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());
8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String16 type;
8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ssize_t typeIdx = block.indexOfAttribute(NULL, "type");
8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (typeIdx < 0) {
8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    srcPos.error("A 'type' attribute is required for <public>\n");
8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hasErrors = localHasErrors = true;
8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                type = String16(block.getAttributeStringValue(typeIdx, &len));
8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String16 name;
8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ssize_t nameIdx = block.indexOfAttribute(NULL, "name");
8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (nameIdx < 0) {
8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    srcPos.error("A 'name' attribute is required for <public>\n");
8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hasErrors = localHasErrors = true;
8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                name = String16(block.getAttributeStringValue(nameIdx, &len));
8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                uint32_t ident = 0;
8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ssize_t identIdx = block.indexOfAttribute(NULL, "id");
8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (identIdx >= 0) {
8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    const char16_t* identStr = block.getAttributeStringValue(identIdx, &len);
8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Res_value identValue;
8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (!ResTable::stringToInt(identStr, len, &identValue)) {
8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        srcPos.error("Given 'id' attribute is not an integer: %s\n",
8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                String8(block.getAttributeStringValue(identIdx, &len)).string());
8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        hasErrors = localHasErrors = true;
8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else {
8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ident = identValue.data;
889f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        nextPublicId.replaceValueFor(type, ident+1);
8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
891f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                } else if (nextPublicId.indexOfKey(type) < 0) {
8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    srcPos.error("No 'id' attribute supplied <public>,"
8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            " and no previous id defined in this file.\n");
8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hasErrors = localHasErrors = true;
8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (!localHasErrors) {
896f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    ident = nextPublicId.valueFor(type);
897f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    nextPublicId.replaceValueFor(type, ident+1);
8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!localHasErrors) {
9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    err = outTable->addPublic(srcPos, myPackage, type, name, ident);
9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (err < NO_ERROR) {
9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        hasErrors = localHasErrors = true;
9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!localHasErrors) {
9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R"));
9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (symbols != NULL) {
9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        symbols = symbols->addNestedSymbol(String8(type), srcPos);
9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (symbols != NULL) {
9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        symbols->makeSymbolPublic(String8(name), srcPos);
9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String16 comment(
9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            block.getComment(&len) ? block.getComment(&len) : nulStr);
9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        symbols->appendComment(String8(name), comment, srcPos);
9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else {
9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        srcPos.error("Unable to create symbols!\n");
9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        hasErrors = localHasErrors = true;
9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (code == ResXMLTree::END_TAG) {
9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (strcmp16(block.getElementName(&len), public16.string()) == 0) {
9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            break;
9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
931f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn            } else if (strcmp16(block.getElementName(&len), public_padding16.string()) == 0) {
932f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());
933f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn
934f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                String16 type;
935f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                ssize_t typeIdx = block.indexOfAttribute(NULL, "type");
936f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                if (typeIdx < 0) {
937f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    srcPos.error("A 'type' attribute is required for <public-padding>\n");
938f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    hasErrors = localHasErrors = true;
939f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                }
940f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                type = String16(block.getAttributeStringValue(typeIdx, &len));
941f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn
942f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                String16 name;
943f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                ssize_t nameIdx = block.indexOfAttribute(NULL, "name");
944f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                if (nameIdx < 0) {
945f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    srcPos.error("A 'name' attribute is required for <public-padding>\n");
946f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    hasErrors = localHasErrors = true;
947f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                }
948f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                name = String16(block.getAttributeStringValue(nameIdx, &len));
949f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn
950f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                uint32_t start = 0;
951f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                ssize_t startIdx = block.indexOfAttribute(NULL, "start");
952f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                if (startIdx >= 0) {
953f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    const char16_t* startStr = block.getAttributeStringValue(startIdx, &len);
954f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    Res_value startValue;
955f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    if (!ResTable::stringToInt(startStr, len, &startValue)) {
956f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        srcPos.error("Given 'start' attribute is not an integer: %s\n",
957f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                                String8(block.getAttributeStringValue(startIdx, &len)).string());
958f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        hasErrors = localHasErrors = true;
959f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    } else {
960f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        start = startValue.data;
961f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    }
962f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                } else if (nextPublicId.indexOfKey(type) < 0) {
963f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    srcPos.error("No 'start' attribute supplied <public-padding>,"
964f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                            " and no previous id defined in this file.\n");
965f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    hasErrors = localHasErrors = true;
966f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                } else if (!localHasErrors) {
967f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    start = nextPublicId.valueFor(type);
968f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                }
969f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn
970f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                uint32_t end = 0;
971f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                ssize_t endIdx = block.indexOfAttribute(NULL, "end");
972f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                if (endIdx >= 0) {
973f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    const char16_t* endStr = block.getAttributeStringValue(endIdx, &len);
974f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    Res_value endValue;
975f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    if (!ResTable::stringToInt(endStr, len, &endValue)) {
976f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        srcPos.error("Given 'end' attribute is not an integer: %s\n",
977f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                                String8(block.getAttributeStringValue(endIdx, &len)).string());
978f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        hasErrors = localHasErrors = true;
979f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    } else {
980f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        end = endValue.data;
981f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    }
982f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                } else {
983f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    srcPos.error("No 'end' attribute supplied <public-padding>\n");
984f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    hasErrors = localHasErrors = true;
985f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                }
986f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn
987f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                if (end >= start) {
988f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    nextPublicId.replaceValueFor(type, end+1);
989f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                } else {
990f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    srcPos.error("Padding start '%ul' is after end '%ul'\n",
991f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                            start, end);
992f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    hasErrors = localHasErrors = true;
993f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                }
994f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn
995f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                String16 comment(
996f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    block.getComment(&len) ? block.getComment(&len) : nulStr);
997f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                for (uint32_t curIdent=start; curIdent<=end; curIdent++) {
998f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    if (localHasErrors) {
999f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        break;
1000f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    }
1001f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    String16 curName(name);
1002f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    char buf[64];
1003f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    sprintf(buf, "%d", (int)(end-curIdent+1));
1004f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    curName.append(String16(buf));
1005f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn
1006f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    err = outTable->addEntry(srcPos, myPackage, type, curName,
1007f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                                             String16("padding"), NULL, &curParams, false,
1008f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                                             ResTable_map::TYPE_STRING, overwrite);
1009f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    if (err < NO_ERROR) {
1010f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        hasErrors = localHasErrors = true;
1011f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        break;
1012f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    }
1013f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    err = outTable->addPublic(srcPos, myPackage, type,
1014f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                            curName, curIdent);
1015f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    if (err < NO_ERROR) {
1016f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        hasErrors = localHasErrors = true;
1017f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        break;
1018f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    }
1019f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R"));
1020f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    if (symbols != NULL) {
1021f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        symbols = symbols->addNestedSymbol(String8(type), srcPos);
1022f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    }
1023f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    if (symbols != NULL) {
1024f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        symbols->makeSymbolPublic(String8(curName), srcPos);
1025f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        symbols->appendComment(String8(curName), comment, srcPos);
1026f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    } else {
1027f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        srcPos.error("Unable to create symbols!\n");
1028f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        hasErrors = localHasErrors = true;
1029f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    }
1030f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                }
1031f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn
1032f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
1033f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    if (code == ResXMLTree::END_TAG) {
1034f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        if (strcmp16(block.getElementName(&len), public_padding16.string()) == 0) {
1035f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                            break;
1036f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                        }
1037f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                    }
1038f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                }
1039f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn                continue;
1040f479aa0900e9a85afdc78b1048684e37579ebf23Dianne Hackborn
10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), private_symbols16.string()) == 0) {
10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String16 pkg;
10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ssize_t pkgIdx = block.indexOfAttribute(NULL, "package");
10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (pkgIdx < 0) {
10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            "A 'package' attribute is required for <private-symbols>\n");
10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hasErrors = localHasErrors = true;
10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pkg = String16(block.getAttributeStringValue(pkgIdx, &len));
10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!localHasErrors) {
10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    assets->setSymbolsPrivatePackage(String8(pkg));
10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (code == ResXMLTree::END_TAG) {
10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (strcmp16(block.getElementName(&len), private_symbols16.string()) == 0) {
10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            break;
10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10631644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn            } else if (strcmp16(block.getElementName(&len), java_symbol16.string()) == 0) {
10641644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn                SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());
10651644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn
10661644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn                String16 type;
10671644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn                ssize_t typeIdx = block.indexOfAttribute(NULL, "type");
10681644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn                if (typeIdx < 0) {
10691644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn                    srcPos.error("A 'type' attribute is required for <public>\n");
10701644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn                    hasErrors = localHasErrors = true;
10711644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn                }
10721644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn                type = String16(block.getAttributeStringValue(typeIdx, &len));
10731644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn
10741644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn                String16 name;
10751644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn                ssize_t nameIdx = block.indexOfAttribute(NULL, "name");
10761644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn                if (nameIdx < 0) {
10771644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn                    srcPos.error("A 'name' attribute is required for <public>\n");
10781644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn                    hasErrors = localHasErrors = true;
10791644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn                }
10801644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn                name = String16(block.getAttributeStringValue(nameIdx, &len));
10811644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn
10821644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn                sp<AaptSymbols> symbols = assets->getJavaSymbolsFor(String8("R"));
10831644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn                if (symbols != NULL) {
10841644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn                    symbols = symbols->addNestedSymbol(String8(type), srcPos);
10851644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn                }
10861644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn                if (symbols != NULL) {
10871644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn                    symbols->makeSymbolJavaSymbol(String8(name), srcPos);
10881644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn                    String16 comment(
10891644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn                        block.getComment(&len) ? block.getComment(&len) : nulStr);
10901644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn                    symbols->appendComment(String8(name), comment, srcPos);
10911644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn                } else {
10921644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn                    srcPos.error("Unable to create symbols!\n");
10931644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn                    hasErrors = localHasErrors = true;
10941644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn                }
10951644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn
10961644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
10971644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn                    if (code == ResXMLTree::END_TAG) {
10981644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn                        if (strcmp16(block.getElementName(&len), java_symbol16.string()) == 0) {
10991644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn                            break;
11001644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn                        }
11011644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn                    }
11021644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn                }
11031644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn                continue;
11041644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn
11051644c6d7f4931d0b4fe7ea77c63b016af01a46d3Dianne Hackborn
110658c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn            } else if (strcmp16(block.getElementName(&len), add_resource16.string()) == 0) {
110758c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());
110858c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn
110958c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                String16 typeName;
111058c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                ssize_t typeIdx = block.indexOfAttribute(NULL, "type");
111158c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                if (typeIdx < 0) {
111258c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                    srcPos.error("A 'type' attribute is required for <add-resource>\n");
111358c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                    hasErrors = localHasErrors = true;
111458c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                }
111558c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                typeName = String16(block.getAttributeStringValue(typeIdx, &len));
111658c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn
111758c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                String16 name;
111858c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                ssize_t nameIdx = block.indexOfAttribute(NULL, "name");
111958c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                if (nameIdx < 0) {
112058c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                    srcPos.error("A 'name' attribute is required for <add-resource>\n");
112158c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                    hasErrors = localHasErrors = true;
112258c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                }
112358c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                name = String16(block.getAttributeStringValue(nameIdx, &len));
112458c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn
112558c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                outTable->canAddEntry(srcPos, myPackage, typeName, name);
112658c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn
112758c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
112858c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                    if (code == ResXMLTree::END_TAG) {
112993d72516994277acdd3894a169ec1f1cbc50db97Robert Greenwalt                        if (strcmp16(block.getElementName(&len), add_resource16.string()) == 0) {
113058c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                            break;
113158c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                        }
113258c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                    }
113358c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                }
113458c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                continue;
113558c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn
11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), declare_styleable16.string()) == 0) {
11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());
11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String16 ident;
11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ssize_t identIdx = block.indexOfAttribute(NULL, "name");
11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (identIdx < 0) {
11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    srcPos.error("A 'name' attribute is required for <declare-styleable>\n");
11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hasErrors = localHasErrors = true;
11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
11459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ident = String16(block.getAttributeStringValue(identIdx, &len));
11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R"));
11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!localHasErrors) {
11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (symbols != NULL) {
11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        symbols = symbols->addNestedSymbol(String8("styleable"), srcPos);
11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sp<AaptSymbols> styleSymbols = symbols;
11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (symbols != NULL) {
11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        symbols = symbols->addNestedSymbol(String8(ident), srcPos);
11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (symbols == NULL) {
11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        srcPos.error("Unable to create symbols!\n");
11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        return UNKNOWN_ERROR;
11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String16 comment(
11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        block.getComment(&len) ? block.getComment(&len) : nulStr);
11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    styleSymbols->appendComment(String8(ident), comment, srcPos);
11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    symbols = NULL;
11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (code == ResXMLTree::START_TAG) {
11709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {
11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            while ((code=block.next()) != ResXMLTree::END_DOCUMENT
11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                   && code != ResXMLTree::BAD_DOCUMENT) {
11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                if (code == ResXMLTree::END_TAG) {
11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {
11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        break;
11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    }
11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                }
11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            continue;
11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } else if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) {
11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            while ((code=block.next()) != ResXMLTree::END_DOCUMENT
11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                   && code != ResXMLTree::BAD_DOCUMENT) {
11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                if (code == ResXMLTree::END_TAG) {
11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) {
11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        break;
11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    }
11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                }
11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            continue;
11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } else if (strcmp16(block.getElementName(&len), attr16.string()) != 0) {
11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    "Tag <%s> can not appear inside <declare-styleable>, only <attr>\n",
11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    String8(block.getElementName(&len)).string());
11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            return UNKNOWN_ERROR;
11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String16 comment(
11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            block.getComment(&len) ? block.getComment(&len) : nulStr);
11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String16 itemIdent;
12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        err = compileAttribute(in, block, myPackage, outTable, &itemIdent, true);
12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (err != NO_ERROR) {
12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            hasErrors = localHasErrors = true;
12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (symbols != NULL) {
12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            SourcePos srcPos(String8(in->getPrintableSource()), block.getLineNumber());
12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            symbols->addSymbol(String8(itemIdent), 0, srcPos);
12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            symbols->appendComment(String8(itemIdent), comment, srcPos);
12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            //printf("Attribute %s comment: %s\n", String8(itemIdent).string(),
12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            //     String8(comment).string());
12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else if (code == ResXMLTree::END_TAG) {
12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (strcmp16(block.getElementName(&len), declare_styleable16.string()) == 0) {
12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            break;
12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                "Found tag </%s> where </attr> is expected\n",
12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                String8(block.getElementName(&len)).string());
12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        return UNKNOWN_ERROR;
12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
12249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), attr16.string()) == 0) {
12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                err = compileAttribute(in, block, myPackage, outTable, NULL);
12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (err != NO_ERROR) {
12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hasErrors = true;
12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
12319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), item16.string()) == 0) {
12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &item16;
12349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ssize_t attri = block.indexOfAttribute(NULL, "type");
12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (attri >= 0) {
12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    curType = String16(block.getAttributeStringValue(attri, &len));
12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ssize_t formatIdx = block.indexOfAttribute(NULL, "format");
12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (formatIdx >= 0) {
12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String16 formatStr = String16(block.getAttributeStringValue(
12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                formatIdx, &len));
12419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        curFormat = parse_flags(formatStr.string(), formatStr.size(),
12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                gFormatFlags);
12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (curFormat == 0) {
12449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
12459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    "Tag <item> 'format' attribute value \"%s\" not valid\n",
12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    String8(formatStr).string());
12479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            hasErrors = localHasErrors = true;
12489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
12499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
12509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
12519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
12529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            "A 'type' attribute is required for <item>\n");
12539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hasErrors = localHasErrors = true;
12549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curIsStyled = true;
12569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), string16.string()) == 0) {
12579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Note the existence and locale of every string we process
12589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                char rawLocale[16];
12599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curParams.getLocale(rawLocale);
12609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String8 locale(rawLocale);
12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String16 name;
12629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String16 translatable;
126315fe2cb73b0770316db302f6502f568062d68e74Kenny Root                String16 formatted;
12649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                size_t n = block.getAttributeCount();
12669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (size_t i = 0; i < n; i++) {
12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    size_t length;
12689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    const uint16_t* attr = block.getAttributeName(i, &length);
12699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (strcmp16(attr, name16.string()) == 0) {
12709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        name.setTo(block.getAttributeStringValue(i, &length));
12719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else if (strcmp16(attr, translatable16.string()) == 0) {
12729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        translatable.setTo(block.getAttributeStringValue(i, &length));
127315fe2cb73b0770316db302f6502f568062d68e74Kenny Root                    } else if (strcmp16(attr, formatted16.string()) == 0) {
127415fe2cb73b0770316db302f6502f568062d68e74Kenny Root                        formatted.setTo(block.getAttributeStringValue(i, &length));
12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (name.size() > 0) {
12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (translatable == false16) {
128015fe2cb73b0770316db302f6502f568062d68e74Kenny Root                        curIsFormatted = false;
12819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // Untranslatable strings must only exist in the default [empty] locale
12829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (locale.size() > 0) {
12839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            fprintf(stderr, "aapt: warning: string '%s' in %s marked untranslatable but exists"
12849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    " in locale '%s'\n", String8(name).string(),
12859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    bundle->getResourceSourceDirs()[0],
12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    locale.string());
12879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            // hasErrors = localHasErrors = true;
12889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } else {
12899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            // Intentionally empty block:
12909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            //
12919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            // Don't add untranslatable strings to the localization table; that
12929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            // way if we later see localizations of them, they'll be flagged as
12939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            // having no default translation.
12949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else {
12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        outTable->addLocalization(name, locale);
12979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
129815fe2cb73b0770316db302f6502f568062d68e74Kenny Root
129915fe2cb73b0770316db302f6502f568062d68e74Kenny Root                    if (formatted == false16) {
130015fe2cb73b0770316db302f6502f568062d68e74Kenny Root                        curIsFormatted = false;
130115fe2cb73b0770316db302f6502f568062d68e74Kenny Root                    }
13029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
13039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &string16;
13059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curType = string16;
13069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_STRING;
13079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curIsStyled = true;
13089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curIsPseudolocalizable = true;
13099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), drawable16.string()) == 0) {
13109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &drawable16;
13119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curType = drawable16;
13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_COLOR;
13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), color16.string()) == 0) {
13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &color16;
13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curType = color16;
13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_COLOR;
13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), bool16.string()) == 0) {
13189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &bool16;
13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curType = bool16;
13209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_BOOLEAN;
13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), integer16.string()) == 0) {
13229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &integer16;
13239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curType = integer16;
13249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_INTEGER;
13259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), dimen16.string()) == 0) {
13269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &dimen16;
13279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curType = dimen16;
13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_DIMENSION;
13299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), fraction16.string()) == 0) {
13309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &fraction16;
13319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curType = fraction16;
13329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_FRACTION;
13339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), bag16.string()) == 0) {
13349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &bag16;
13359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curIsBag = true;
13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ssize_t attri = block.indexOfAttribute(NULL, "type");
13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (attri >= 0) {
13389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    curType = String16(block.getAttributeStringValue(attri, &len));
13399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
13409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
13419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            "A 'type' attribute is required for <bag>\n");
13429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hasErrors = localHasErrors = true;
13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
13449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), style16.string()) == 0) {
13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &style16;
13469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curType = style16;
13479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curIsBag = true;
13489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), plurals16.string()) == 0) {
13499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &plurals16;
13509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curType = plurals16;
13519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curIsBag = true;
13529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), array16.string()) == 0) {
13539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &array16;
13549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curType = array16;
13559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curIsBag = true;
13561aa8170e6a448afad86e5d62927d3b8ca4cd9707Robert Greenwalt                curIsBagReplaceOnOverwrite = true;
13579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ssize_t formatIdx = block.indexOfAttribute(NULL, "format");
13589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (formatIdx >= 0) {
13599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String16 formatStr = String16(block.getAttributeStringValue(
13609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            formatIdx, &len));
13619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    curFormat = parse_flags(formatStr.string(), formatStr.size(),
13629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                            gFormatFlags);
13639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (curFormat == 0) {
13649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
13659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                "Tag <array> 'format' attribute value \"%s\" not valid\n",
13669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                String8(formatStr).string());
13679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        hasErrors = localHasErrors = true;
13689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
13699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
13709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), string_array16.string()) == 0) {
137102feeb4b2bb6515491cf3dd7ae2b204caac81baeJosh Stone                // Check whether these strings need valid formats.
137202feeb4b2bb6515491cf3dd7ae2b204caac81baeJosh Stone                // (simplified form of what string16 does above)
137302feeb4b2bb6515491cf3dd7ae2b204caac81baeJosh Stone                size_t n = block.getAttributeCount();
137402feeb4b2bb6515491cf3dd7ae2b204caac81baeJosh Stone                for (size_t i = 0; i < n; i++) {
137502feeb4b2bb6515491cf3dd7ae2b204caac81baeJosh Stone                    size_t length;
137602feeb4b2bb6515491cf3dd7ae2b204caac81baeJosh Stone                    const uint16_t* attr = block.getAttributeName(i, &length);
137702feeb4b2bb6515491cf3dd7ae2b204caac81baeJosh Stone                    if (strcmp16(attr, translatable16.string()) == 0
137802feeb4b2bb6515491cf3dd7ae2b204caac81baeJosh Stone                            || strcmp16(attr, formatted16.string()) == 0) {
137902feeb4b2bb6515491cf3dd7ae2b204caac81baeJosh Stone                        const uint16_t* value = block.getAttributeStringValue(i, &length);
138002feeb4b2bb6515491cf3dd7ae2b204caac81baeJosh Stone                        if (strcmp16(value, false16.string()) == 0) {
138102feeb4b2bb6515491cf3dd7ae2b204caac81baeJosh Stone                            curIsFormatted = false;
138202feeb4b2bb6515491cf3dd7ae2b204caac81baeJosh Stone                            break;
138302feeb4b2bb6515491cf3dd7ae2b204caac81baeJosh Stone                        }
138402feeb4b2bb6515491cf3dd7ae2b204caac81baeJosh Stone                    }
138502feeb4b2bb6515491cf3dd7ae2b204caac81baeJosh Stone                }
138602feeb4b2bb6515491cf3dd7ae2b204caac81baeJosh Stone
13879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &string_array16;
13889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curType = array16;
13899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_STRING;
13909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curIsBag = true;
13911aa8170e6a448afad86e5d62927d3b8ca4cd9707Robert Greenwalt                curIsBagReplaceOnOverwrite = true;
13929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curIsPseudolocalizable = true;
13939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp16(block.getElementName(&len), integer_array16.string()) == 0) {
13949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curTag = &integer_array16;
13959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curType = array16;
13969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_INTEGER;
13979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curIsBag = true;
13981aa8170e6a448afad86e5d62927d3b8ca4cd9707Robert Greenwalt                curIsBagReplaceOnOverwrite = true;
13999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
14009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
14019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        "Found tag %s where item is expected\n",
14029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String8(block.getElementName(&len)).string());
14039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return UNKNOWN_ERROR;
14049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
14059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String16 ident;
14079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ssize_t identIdx = block.indexOfAttribute(NULL, "name");
14089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (identIdx >= 0) {
14099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ident = String16(block.getAttributeStringValue(identIdx, &len));
14109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
14119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
14129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        "A 'name' attribute is required for <%s>\n",
14139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String8(*curTag).string());
14149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                hasErrors = localHasErrors = true;
14159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
14169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1417407f625a9b8e356e765a5ec587c443af1f3aadb5Dianne Hackborn            String16 product;
1418407f625a9b8e356e765a5ec587c443af1f3aadb5Dianne Hackborn            identIdx = block.indexOfAttribute(NULL, "product");
1419407f625a9b8e356e765a5ec587c443af1f3aadb5Dianne Hackborn            if (identIdx >= 0) {
1420407f625a9b8e356e765a5ec587c443af1f3aadb5Dianne Hackborn                product = String16(block.getAttributeStringValue(identIdx, &len));
1421407f625a9b8e356e765a5ec587c443af1f3aadb5Dianne Hackborn            }
1422407f625a9b8e356e765a5ec587c443af1f3aadb5Dianne Hackborn
14239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String16 comment(block.getComment(&len) ? block.getComment(&len) : nulStr);
14249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (curIsBag) {
14269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Figure out the parent of this bag...
14279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String16 parentIdent;
14289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ssize_t parentIdentIdx = block.indexOfAttribute(NULL, "parent");
14299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (parentIdentIdx >= 0) {
14309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    parentIdent = String16(block.getAttributeStringValue(parentIdentIdx, &len));
14319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
14329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ssize_t sep = ident.findLast('.');
14339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (sep >= 0) {
14349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        parentIdent.setTo(ident, sep);
14359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
14369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
14379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!localHasErrors) {
14391aa8170e6a448afad86e5d62927d3b8ca4cd9707Robert Greenwalt                    err = outTable->startBag(SourcePos(in->getPrintableSource(),
14401aa8170e6a448afad86e5d62927d3b8ca4cd9707Robert Greenwalt                            block.getLineNumber()), myPackage, curType, ident,
14411aa8170e6a448afad86e5d62927d3b8ca4cd9707Robert Greenwalt                            parentIdent, &curParams,
14421aa8170e6a448afad86e5d62927d3b8ca4cd9707Robert Greenwalt                            overwrite, curIsBagReplaceOnOverwrite);
14439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (err != NO_ERROR) {
14449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        hasErrors = localHasErrors = true;
14459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
14469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
14479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ssize_t elmIndex = 0;
14499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                char elmIndexStr[14];
14509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                while ((code=block.next()) != ResXMLTree::END_DOCUMENT
14519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        && code != ResXMLTree::BAD_DOCUMENT) {
14529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (code == ResXMLTree::START_TAG) {
14549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (strcmp16(block.getElementName(&len), item16.string()) != 0) {
14559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
14569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    "Tag <%s> can not appear inside <%s>, only <item>\n",
14579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    String8(block.getElementName(&len)).string(),
14589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    String8(*curTag).string());
14599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            return UNKNOWN_ERROR;
14609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
14619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String16 itemIdent;
14639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (curType == array16) {
14649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            sprintf(elmIndexStr, "^index_%d", (int)elmIndex++);
14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            itemIdent = String16(elmIndexStr);
14669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } else if (curType == plurals16) {
14679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            ssize_t itemIdentIdx = block.indexOfAttribute(NULL, "quantity");
14689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            if (itemIdentIdx >= 0) {
14699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                String16 quantity16(block.getAttributeStringValue(itemIdentIdx, &len));
14709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                if (quantity16 == other16) {
14719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    itemIdent = quantityOther16;
14729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                }
14739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                else if (quantity16 == zero16) {
14749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    itemIdent = quantityZero16;
14759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                }
14769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                else if (quantity16 == one16) {
14779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    itemIdent = quantityOne16;
14789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                }
14799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                else if (quantity16 == two16) {
14809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    itemIdent = quantityTwo16;
14819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                }
14829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                else if (quantity16 == few16) {
14839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    itemIdent = quantityFew16;
14849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                }
14859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                else if (quantity16 == many16) {
14869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    itemIdent = quantityMany16;
14879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                }
14889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                else {
14899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
14909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                            "Illegal 'quantity' attribute is <item> inside <plurals>\n");
14919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    hasErrors = localHasErrors = true;
14929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                }
14939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            } else {
14949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
14959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        "A 'quantity' attribute is required for <item> inside <plurals>\n");
14969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                hasErrors = localHasErrors = true;
14979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
14989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } else {
14999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            ssize_t itemIdentIdx = block.indexOfAttribute(NULL, "name");
15009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            if (itemIdentIdx >= 0) {
15019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                itemIdent = String16(block.getAttributeStringValue(itemIdentIdx, &len));
15029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            } else {
15039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
15049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        "A 'name' attribute is required for <item>\n");
15059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                hasErrors = localHasErrors = true;
15069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
15079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
15089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ResXMLParser::ResXMLPosition parserPosition;
15109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        block.getPosition(&parserPosition);
15119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        err = parseAndAddBag(bundle, in, &block, curParams, myPackage, curType,
151315fe2cb73b0770316db302f6502f568062d68e74Kenny Root                                ident, parentIdent, itemIdent, curFormat, curIsFormatted,
1514407f625a9b8e356e765a5ec587c443af1f3aadb5Dianne Hackborn                                product, false, overwrite, outTable);
15159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (err == NO_ERROR) {
15169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            if (curIsPseudolocalizable && localeIsDefined(curParams)
15179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    && bundle->getPseudolocalize()) {
15189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                // pseudolocalize here
15199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 1
15209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                block.setPosition(parserPosition);
15219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                err = parseAndAddBag(bundle, in, &block, pseudoParams, myPackage,
152215fe2cb73b0770316db302f6502f568062d68e74Kenny Root                                        curType, ident, parentIdent, itemIdent, curFormat,
1523407f625a9b8e356e765a5ec587c443af1f3aadb5Dianne Hackborn                                        curIsFormatted, product, true, overwrite, outTable);
15249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
15259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
15269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
15279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (err != NO_ERROR) {
15289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            hasErrors = localHasErrors = true;
15299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
15309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else if (code == ResXMLTree::END_TAG) {
15319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (strcmp16(block.getElementName(&len), curTag->string()) != 0) {
15329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
15339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    "Found tag </%s> where </%s> is expected\n",
15349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    String8(block.getElementName(&len)).string(),
15359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    String8(*curTag).string());
15369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            return UNKNOWN_ERROR;
15379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
15389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        break;
15399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
15409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
15419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
15429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ResXMLParser::ResXMLPosition parserPosition;
15439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                block.getPosition(&parserPosition);
15449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                err = parseAndAddEntry(bundle, in, &block, curParams, myPackage, curType, ident,
154615fe2cb73b0770316db302f6502f568062d68e74Kenny Root                        *curTag, curIsStyled, curFormat, curIsFormatted,
1547407f625a9b8e356e765a5ec587c443af1f3aadb5Dianne Hackborn                        product, false, overwrite, outTable);
15489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (err < NO_ERROR) { // Why err < NO_ERROR instead of err != NO_ERROR?
15509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hasErrors = localHasErrors = true;
15519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
15529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                else if (err == NO_ERROR) {
15539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (curIsPseudolocalizable && localeIsDefined(curParams)
15549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            && bundle->getPseudolocalize()) {
15559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // pseudolocalize here
15569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        block.setPosition(parserPosition);
15579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        err = parseAndAddEntry(bundle, in, &block, pseudoParams, myPackage, curType,
155815fe2cb73b0770316db302f6502f568062d68e74Kenny Root                                ident, *curTag, curIsStyled, curFormat,
1559407f625a9b8e356e765a5ec587c443af1f3aadb5Dianne Hackborn                                curIsFormatted, product,
156090964040cabfc67f92a7c3322a02401bb6f8ae82Eric Fischer                                true, overwrite, outTable);
15619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (err != NO_ERROR) {
15629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            hasErrors = localHasErrors = true;
15639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
15649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
15659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
15669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
15679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 0
15699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (comment.size() > 0) {
15709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                printf("Comment for @%s:%s/%s: %s\n", String8(myPackage).string(),
15719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                       String8(curType).string(), String8(ident).string(),
15729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                       String8(comment).string());
15739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
15749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
15759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!localHasErrors) {
15769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                outTable->appendComment(myPackage, curType, ident, comment, false);
15779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
15789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        else if (code == ResXMLTree::END_TAG) {
15809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (strcmp16(block.getElementName(&len), resources16.string()) != 0) {
15819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
15829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        "Unexpected end tag %s\n", String8(block.getElementName(&len)).string());
15839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return UNKNOWN_ERROR;
15849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
15859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        else if (code == ResXMLTree::START_NAMESPACE || code == ResXMLTree::END_NAMESPACE) {
15879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        else if (code == ResXMLTree::TEXT) {
15899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (isWhitespace(block.getText(&len))) {
15909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
15919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
15929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
15939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    "Found text \"%s\" where item tag is expected\n",
15949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(block.getText(&len)).string());
15959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return UNKNOWN_ERROR;
15969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
16009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
16019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResourceTable::ResourceTable(Bundle* bundle, const String16& assetsPackage)
16039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    : mAssetsPackage(assetsPackage), mNextPackageId(1), mHaveAppPackage(false),
16049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      mIsAppPackage(!bundle->getExtending()),
16059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      mNumLocal(0),
16069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      mBundle(bundle)
16079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
16089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
16099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::addIncludedResources(Bundle* bundle, const sp<AaptAssets>& assets)
16119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
16129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = assets->buildIncludedResources(bundle);
16139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != NO_ERROR) {
16149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return err;
16159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // For future reference to included resources.
16189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mAssets = assets;
16199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const ResTable& incl = assets->getIncludedResources();
16219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Retrieve all the packages.
16239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t N = incl.getBasePackageCount();
16249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (size_t phase=0; phase<2; phase++) {
16259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (size_t i=0; i<N; i++) {
16269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String16 name(incl.getBasePackageName(i));
16279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            uint32_t id = incl.getBasePackageId(i);
16289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // First time through: only add base packages (id
16299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // is not 0); second time through add the other
16309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // packages.
16319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (phase != 0) {
16329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (id != 0) {
16339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Skip base packages -- already one.
16349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    id = 0;
16359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
16369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Assign a dynamic id.
16379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    id = mNextPackageId;
16389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
16399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (id != 0) {
16409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (id == 127) {
16419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (mHaveAppPackage) {
1642a96cbb435d7b2197ab2b61fd98d14cbd6e0c5c3dDianne Hackborn                        fprintf(stderr, "Included resources have two application packages!\n");
16439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        return UNKNOWN_ERROR;
16449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
16459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mHaveAppPackage = true;
16469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
16479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mNextPackageId > id) {
16489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    fprintf(stderr, "Included base package ID %d already in use!\n", id);
16499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return UNKNOWN_ERROR;
16509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
16519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
16529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (id != 0) {
16539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                NOISY(printf("Including package %s with ID=%d\n",
16549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             String8(name).string(), id));
16559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sp<Package> p = new Package(name, id);
16569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mPackages.add(name, p);
16579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mOrderedPackages.add(p);
16589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (id >= mNextPackageId) {
16609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mNextPackageId = id+1;
16619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
16629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
16639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Every resource table always has one first entry, the bag attributes.
16679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const SourcePos unknown(String8("????"), 0);
16689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Type> attr = getType(mAssetsPackage, String16("attr"), unknown);
16699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
16719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
16729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::addPublic(const SourcePos& sourcePos,
16749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const String16& package,
16759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const String16& type,
16769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const String16& name,
16779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const uint32_t ident)
16789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
16799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t rid = mAssets->getIncludedResources()
16809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        .identifierForName(name.string(), name.size(),
16819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           type.string(), type.size(),
16829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           package.string(), package.size());
16839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (rid != 0) {
16849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sourcePos.error("Error declaring public resource %s/%s for included package %s\n",
16859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String8(type).string(), String8(name).string(),
16869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String8(package).string());
16879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
16889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Type> t = getType(package, type, sourcePos);
16919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (t == NULL) {
16929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
16939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return t->addPublic(sourcePos, name, ident);
16959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
16969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::addEntry(const SourcePos& sourcePos,
16989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16& package,
16999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16& type,
17009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16& name,
17019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16& value,
17029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const Vector<StringPool::entry_style_span>* style,
17039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const ResTable_config* params,
17049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const bool doSetIndex,
17059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const int32_t format,
17069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const bool overwrite)
17079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
17089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Check for adding entries in other packages...  for now we do
17099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // nothing.  We need to do the right thing here to support skinning.
17109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t rid = mAssets->getIncludedResources()
17119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        .identifierForName(name.string(), name.size(),
17129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           type.string(), type.size(),
17139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           package.string(), package.size());
17149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (rid != 0) {
17159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NO_ERROR;
17169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 0
17199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (name == String16("left")) {
17209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        printf("Adding entry left: file=%s, line=%d, type=%s, value=%s\n",
17219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project               sourcePos.file.string(), sourcePos.line, String8(type).string(),
17229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project               String8(value).string());
17239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
1725f878e2d80c3a0afefe3b018d232df6066379e1d5Robert Greenwalt
1726f878e2d80c3a0afefe3b018d232df6066379e1d5Robert Greenwalt    sp<Entry> e = getEntry(package, type, name, sourcePos, overwrite,
1727f878e2d80c3a0afefe3b018d232df6066379e1d5Robert Greenwalt                           params, doSetIndex);
17289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (e == NULL) {
17299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
17309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = e->setItem(sourcePos, value, style, format, overwrite);
17329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err == NO_ERROR) {
17339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mNumLocal++;
17349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err;
17369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
17379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::startBag(const SourcePos& sourcePos,
17399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16& package,
17409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16& type,
17419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16& name,
17429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16& bagParent,
17439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const ResTable_config* params,
17441aa8170e6a448afad86e5d62927d3b8ca4cd9707Robert Greenwalt                                 bool overlay,
17459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 bool replace, bool isId)
17469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
17474b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt    status_t result = NO_ERROR;
17484b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt
17499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Check for adding entries in other packages...  for now we do
17509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // nothing.  We need to do the right thing here to support skinning.
17519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t rid = mAssets->getIncludedResources()
17529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    .identifierForName(name.string(), name.size(),
17539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                       type.string(), type.size(),
17549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                       package.string(), package.size());
17559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (rid != 0) {
17569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NO_ERROR;
17579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 0
17609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (name == String16("left")) {
17619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        printf("Adding bag left: file=%s, line=%d, type=%s\n",
17629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project               sourcePos.file.striing(), sourcePos.line, String8(type).string());
17639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
176599080c7d9ad9e5ccfec70dd10e4c24468a960c45Xavier Ducrohet    if (overlay && !mBundle->getAutoAddOverlay() && !hasBagOrEntry(package, type, name)) {
176658c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn        bool canAdd = false;
176758c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn        sp<Package> p = mPackages.valueFor(package);
176858c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn        if (p != NULL) {
176958c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn            sp<Type> t = p->getTypes().valueFor(type);
177058c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn            if (t != NULL) {
177158c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                if (t->getCanAddEntries().indexOf(name) >= 0) {
177258c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                    canAdd = true;
177358c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                }
177458c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn            }
177558c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn        }
177658c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn        if (!canAdd) {
177758c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn            sourcePos.error("Resource does not already exist in overlay at '%s'; use <add-resource> to add.\n",
177858c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                            String8(name).string());
177958c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn            return UNKNOWN_ERROR;
178058c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn        }
17811aa8170e6a448afad86e5d62927d3b8ca4cd9707Robert Greenwalt    }
1782f878e2d80c3a0afefe3b018d232df6066379e1d5Robert Greenwalt    sp<Entry> e = getEntry(package, type, name, sourcePos, overlay, params);
17839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (e == NULL) {
17849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
17859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // If a parent is explicitly specified, set it.
17889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (bagParent.size() > 0) {
17899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        e->setParent(bagParent);
17909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17914b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt
17924b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt    if ((result = e->makeItABag(sourcePos)) != NO_ERROR) {
17934b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt        return result;
17944b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt    }
17959411a39866b749ad0a47f15083f311847eb79178Robert Greenwalt
17961aa8170e6a448afad86e5d62927d3b8ca4cd9707Robert Greenwalt    if (overlay && replace) {
17979411a39866b749ad0a47f15083f311847eb79178Robert Greenwalt        return e->emptyBag(sourcePos);
17989411a39866b749ad0a47f15083f311847eb79178Robert Greenwalt    }
17999411a39866b749ad0a47f15083f311847eb79178Robert Greenwalt    return result;
18009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
18019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::addBag(const SourcePos& sourcePos,
18039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                               const String16& package,
18049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                               const String16& type,
18059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                               const String16& name,
18069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                               const String16& bagParent,
18079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                               const String16& bagKey,
18089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                               const String16& value,
18099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                               const Vector<StringPool::entry_style_span>* style,
18109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                               const ResTable_config* params,
18119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                               bool replace, bool isId, const int32_t format)
18129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
18139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Check for adding entries in other packages...  for now we do
18149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // nothing.  We need to do the right thing here to support skinning.
18159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t rid = mAssets->getIncludedResources()
18169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        .identifierForName(name.string(), name.size(),
18179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           type.string(), type.size(),
18189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           package.string(), package.size());
18199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (rid != 0) {
18209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NO_ERROR;
18219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 0
18249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (name == String16("left")) {
18259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        printf("Adding bag left: file=%s, line=%d, type=%s\n",
18269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project               sourcePos.file.striing(), sourcePos.line, String8(type).string());
18279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
1829f878e2d80c3a0afefe3b018d232df6066379e1d5Robert Greenwalt    sp<Entry> e = getEntry(package, type, name, sourcePos, replace, params);
18309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (e == NULL) {
18319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
18329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // If a parent is explicitly specified, set it.
18359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (bagParent.size() > 0) {
18369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        e->setParent(bagParent);
18379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const bool first = e->getBag().indexOfKey(bagKey) < 0;
18409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = e->addToBag(sourcePos, bagKey, value, style, replace, isId, format);
18419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err == NO_ERROR && first) {
18429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mNumLocal++;
18439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err;
18459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
18469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::hasBagOrEntry(const String16& package,
18489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const String16& type,
18499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const String16& name) const
18509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
18519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // First look for this in the included resources...
18529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t rid = mAssets->getIncludedResources()
18539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        .identifierForName(name.string(), name.size(),
18549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           type.string(), type.size(),
18559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           package.string(), package.size());
18569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (rid != 0) {
18579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
18589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Package> p = mPackages.valueFor(package);
18619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (p != NULL) {
18629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<Type> t = p->getTypes().valueFor(type);
18639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (t != NULL) {
18649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<ConfigList> c =  t->getConfigs().valueFor(name);
18659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (c != NULL) return true;
18669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
18679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return false;
18709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
18719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1872914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischerbool ResourceTable::hasBagOrEntry(const String16& package,
1873914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer                                  const String16& type,
1874914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer                                  const String16& name,
1875914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer                                  const ResTable_config& config) const
1876914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer{
1877914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer    // First look for this in the included resources...
1878914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer    uint32_t rid = mAssets->getIncludedResources()
1879914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer        .identifierForName(name.string(), name.size(),
1880914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer                           type.string(), type.size(),
1881914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer                           package.string(), package.size());
1882914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer    if (rid != 0) {
1883914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer        return true;
1884914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer    }
1885914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer
1886914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer    sp<Package> p = mPackages.valueFor(package);
1887914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer    if (p != NULL) {
1888914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer        sp<Type> t = p->getTypes().valueFor(type);
1889914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer        if (t != NULL) {
1890914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer            sp<ConfigList> c =  t->getConfigs().valueFor(name);
1891914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer            if (c != NULL) {
1892914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer                sp<Entry> e = c->getEntries().valueFor(config);
1893914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer                if (e != NULL) {
1894914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer                    return true;
1895914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer                }
1896914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer            }
1897914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer        }
1898914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer    }
1899914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer
1900914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer    return false;
1901914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer}
1902914f7e683a01f15f8830810c49eaecc31bc554a6Eric Fischer
19039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::hasBagOrEntry(const String16& ref,
19049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const String16* defType,
19059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const String16* defPackage)
19069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
19079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String16 package, type, name;
19089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!ResTable::expandResourceRef(ref.string(), ref.size(), &package, &type, &name,
19099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                defType, defPackage ? defPackage:&mAssetsPackage, NULL)) {
19109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
19119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return hasBagOrEntry(package, type, name);
19139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
19149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::appendComment(const String16& package,
19169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const String16& type,
19179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const String16& name,
19189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const String16& comment,
19199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  bool onlyIfEmpty)
19209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
19219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (comment.size() <= 0) {
19229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
19239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Package> p = mPackages.valueFor(package);
19269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (p != NULL) {
19279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<Type> t = p->getTypes().valueFor(type);
19289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (t != NULL) {
19299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<ConfigList> c =  t->getConfigs().valueFor(name);
19309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (c != NULL) {
19319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                c->appendComment(comment, onlyIfEmpty);
19329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
19339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
19349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return false;
19379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
19389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::appendTypeComment(const String16& package,
19409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                      const String16& type,
19419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                      const String16& name,
19429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                      const String16& comment)
19439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
19449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (comment.size() <= 0) {
19459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
19469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Package> p = mPackages.valueFor(package);
19499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (p != NULL) {
19509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<Type> t = p->getTypes().valueFor(type);
19519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (t != NULL) {
19529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<ConfigList> c =  t->getConfigs().valueFor(name);
19539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (c != NULL) {
19549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                c->appendTypeComment(comment);
19559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
19569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
19579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return false;
19609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
19619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
196258c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackbornvoid ResourceTable::canAddEntry(const SourcePos& pos,
196358c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn        const String16& package, const String16& type, const String16& name)
196458c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn{
196558c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn    sp<Type> t = getType(package, type, pos);
196658c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn    if (t != NULL) {
196758c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn        t->canAddEntry(name);
196858c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn    }
196958c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn}
197058c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn
19719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsize_t ResourceTable::size() const {
19729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return mPackages.size();
19739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
19749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsize_t ResourceTable::numLocalResources() const {
19769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return mNumLocal;
19779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
19789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::hasResources() const {
19809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return mNumLocal > 0;
19819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
19829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsp<AaptFile> ResourceTable::flatten(Bundle* bundle)
19849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
19859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<AaptFile> data = new AaptFile(String8(), AaptGroupEntry(), String8());
19869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = flatten(bundle, data);
19879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err == NO_ERROR ? data : NULL;
19889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
19899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectinline uint32_t ResourceTable::getResId(const sp<Package>& p,
19919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        const sp<Type>& t,
19929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        uint32_t nameId)
19939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
19949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return makeResId(p->getAssignedId(), t->getIndex(), nameId);
19959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
19969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t ResourceTable::getResId(const String16& package,
19989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16& type,
19999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16& name,
20009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 bool onlyPublic) const
20019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
200267b38c44e8b04b97e357664804d593823b2a34edChristopher Tate    uint32_t id = ResourceIdCache::lookup(package, type, name, onlyPublic);
200367b38c44e8b04b97e357664804d593823b2a34edChristopher Tate    if (id != 0) return id;     // cache hit
200467b38c44e8b04b97e357664804d593823b2a34edChristopher Tate
20059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Package> p = mPackages.valueFor(package);
20069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (p == NULL) return 0;
20079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // First look for this in the included resources...
20099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t specFlags = 0;
20109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t rid = mAssets->getIncludedResources()
20119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        .identifierForName(name.string(), name.size(),
20129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           type.string(), type.size(),
20139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           package.string(), package.size(),
20149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           &specFlags);
20159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (rid != 0) {
20169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (onlyPublic) {
20179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if ((specFlags & ResTable_typeSpec::SPEC_PUBLIC) == 0) {
20189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return 0;
20199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
20209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
20219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (Res_INTERNALID(rid)) {
202367b38c44e8b04b97e357664804d593823b2a34edChristopher Tate            return ResourceIdCache::store(package, type, name, onlyPublic, rid);
20249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
202567b38c44e8b04b97e357664804d593823b2a34edChristopher Tate        return ResourceIdCache::store(package, type, name, onlyPublic,
202667b38c44e8b04b97e357664804d593823b2a34edChristopher Tate                Res_MAKEID(p->getAssignedId()-1, Res_GETTYPE(rid), Res_GETENTRY(rid)));
20279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Type> t = p->getTypes().valueFor(type);
20309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (t == NULL) return 0;
20319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<ConfigList> c =  t->getConfigs().valueFor(name);
20329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (c == NULL) return 0;
20339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t ei = c->getEntryIndex();
20349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (ei < 0) return 0;
203567b38c44e8b04b97e357664804d593823b2a34edChristopher Tate
203667b38c44e8b04b97e357664804d593823b2a34edChristopher Tate    return ResourceIdCache::store(package, type, name, onlyPublic,
203767b38c44e8b04b97e357664804d593823b2a34edChristopher Tate            getResId(p, t, ei));
20389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
20399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t ResourceTable::getResId(const String16& ref,
20419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16* defType,
20429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const String16* defPackage,
20439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 const char** outErrorMsg,
20449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                 bool onlyPublic) const
20459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
20469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String16 package, type, name;
2047426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn    bool refOnlyPublic = true;
20489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!ResTable::expandResourceRef(
20499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ref.string(), ref.size(), &package, &type, &name,
20509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        defType, defPackage ? defPackage:&mAssetsPackage,
2051426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn        outErrorMsg, &refOnlyPublic)) {
20529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NOISY(printf("Expanding resource: ref=%s\n",
20539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                     String8(ref).string()));
20549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NOISY(printf("Expanding resource: defType=%s\n",
20559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                     defType ? String8(*defType).string() : "NULL"));
20569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NOISY(printf("Expanding resource: defPackage=%s\n",
20579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                     defPackage ? String8(*defPackage).string() : "NULL"));
20589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NOISY(printf("Expanding resource: ref=%s\n", String8(ref).string()));
20599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NOISY(printf("Expanded resource: p=%s, t=%s, n=%s, res=0\n",
20609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                     String8(package).string(), String8(type).string(),
20619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                     String8(name).string()));
20629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 0;
20639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2064426431adcc220b6adfbe1d9530247f897e60fa36Dianne Hackborn    uint32_t res = getResId(package, type, name, onlyPublic && refOnlyPublic);
20659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    NOISY(printf("Expanded resource: p=%s, t=%s, n=%s, res=%d\n",
20669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 String8(package).string(), String8(type).string(),
20679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 String8(name).string(), res));
20689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (res == 0) {
20699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (outErrorMsg)
20709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            *outErrorMsg = "No resource found that matches the given name";
20719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return res;
20739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
20749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::isValidResourceName(const String16& s)
20769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
20779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char16_t* p = s.string();
20789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool first = true;
20799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (*p) {
20809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((*p >= 'a' && *p <= 'z')
20819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            || (*p >= 'A' && *p <= 'Z')
20829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            || *p == '_'
20839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            || (!first && *p >= '0' && *p <= '9')) {
20849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            first = false;
20859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p++;
20869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            continue;
20879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
20889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
20899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return true;
20919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
20929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::stringToValue(Res_value* outValue, StringPool* pool,
20949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const String16& str,
20959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  bool preserveSpaces, bool coerceType,
20969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  uint32_t attrID,
20979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  const Vector<StringPool::entry_style_span>* style,
20989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  String16* outStr, void* accessorCookie,
20996c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn                                  uint32_t attrType, const String8* configTypeName,
21006c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn                                  const ConfigDescription* config)
21019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
21029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String16 finalStr;
21039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool res = true;
21059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (style == NULL || style->size() == 0) {
21069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Text is not styled so it can be any type...  let's figure it out.
21079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        res = mAssets->getIncludedResources()
21089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            .stringToValue(outValue, &finalStr, str.string(), str.size(), preserveSpaces,
21099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            coerceType, attrID, NULL, &mAssetsPackage, this,
21109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           accessorCookie, attrType);
21119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
21129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Styled text can only be a string, and while collecting the style
21139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // information we have already processed that string!
21149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        outValue->size = sizeof(Res_value);
21159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        outValue->res0 = 0;
2116774562275fa76681933a0105ed61c672892b23bdKenny Root        outValue->dataType = outValue->TYPE_STRING;
21179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        outValue->data = 0;
21189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        finalStr = str;
21199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!res) {
21229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
21239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2125774562275fa76681933a0105ed61c672892b23bdKenny Root    if (outValue->dataType == outValue->TYPE_STRING) {
21269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Should do better merging styles.
21279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (pool) {
21286c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn            String8 configStr;
21296c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn            if (config != NULL) {
21306c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn                configStr = config->toString();
21316c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn            } else {
21326c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn                configStr = "(null)";
21336c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn            }
21346c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn            NOISY(printf("Adding to pool string style #%d config %s: %s\n",
21356c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn                    style != NULL ? style->size() : 0,
21366c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn                    configStr.string(), String8(finalStr).string()));
21379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (style != NULL && style->size() > 0) {
21386c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn                outValue->data = pool->add(finalStr, *style, configTypeName, config);
21399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
21406c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn                outValue->data = pool->add(finalStr, true, configTypeName, config);
21419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
21429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
21439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Caller will fill this in later.
21449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            outValue->data = 0;
21459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
21469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (outStr) {
21489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            *outStr = finalStr;
21499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
21509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return true;
21549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
21559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t ResourceTable::getCustomResource(
21579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16& package, const String16& type, const String16& name) const
21589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
21599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //printf("getCustomResource: %s %s %s\n", String8(package).string(),
21609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //       String8(type).string(), String8(name).string());
21619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Package> p = mPackages.valueFor(package);
21629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (p == NULL) return 0;
21639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Type> t = p->getTypes().valueFor(type);
21649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (t == NULL) return 0;
21659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<ConfigList> c =  t->getConfigs().valueFor(name);
21669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (c == NULL) return 0;
21679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t ei = c->getEntryIndex();
21689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (ei < 0) return 0;
21699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return getResId(p, t, ei);
21709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
21719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t ResourceTable::getCustomResourceWithCreation(
21739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const String16& package, const String16& type, const String16& name,
21749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const bool createIfNotFound)
21759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
21769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t resId = getCustomResource(package, type, name);
21779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (resId != 0 || !createIfNotFound) {
21789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return resId;
21799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String16 value("false");
21819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t status = addEntry(mCurrentXmlPos, package, type, name, value, NULL, NULL, true);
21839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (status == NO_ERROR) {
21849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        resId = getResId(package, type, name);
21859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return resId;
21869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return 0;
21889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
21899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t ResourceTable::getRemappedPackage(uint32_t origPackage) const
21919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
21929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return origPackage;
21939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
21949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::getAttributeType(uint32_t attrID, uint32_t* outType)
21969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
21979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //printf("getAttributeType #%08x\n", attrID);
21989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Res_value value;
21999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (getItemValue(attrID, ResTable_map::ATTR_TYPE, &value)) {
22009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //printf("getAttributeType #%08x (%s): #%08x\n", attrID,
22019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //       String8(getEntry(attrID)->getName()).string(), value.data);
22029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        *outType = value.data;
22039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
22049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return false;
22069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
22079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::getAttributeMin(uint32_t attrID, uint32_t* outMin)
22099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
22109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //printf("getAttributeMin #%08x\n", attrID);
22119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Res_value value;
22129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (getItemValue(attrID, ResTable_map::ATTR_MIN, &value)) {
22139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        *outMin = value.data;
22149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
22159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return false;
22179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
22189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::getAttributeMax(uint32_t attrID, uint32_t* outMax)
22209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
22219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //printf("getAttributeMax #%08x\n", attrID);
22229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Res_value value;
22239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (getItemValue(attrID, ResTable_map::ATTR_MAX, &value)) {
22249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        *outMax = value.data;
22259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
22269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return false;
22289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
22299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t ResourceTable::getAttributeL10N(uint32_t attrID)
22319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
22329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //printf("getAttributeL10N #%08x\n", attrID);
22339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Res_value value;
22349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (getItemValue(attrID, ResTable_map::ATTR_L10N, &value)) {
22359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return value.data;
22369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return ResTable_map::L10N_NOT_REQUIRED;
22389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
22399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::getLocalizationSetting()
22419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
22429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return mBundle->getRequireLocalization();
22439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
22449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResourceTable::reportError(void* accessorCookie, const char* fmt, ...)
22469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
22479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (accessorCookie != NULL && fmt != NULL) {
22489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        AccessorCookie* ac = (AccessorCookie*)accessorCookie;
22499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int retval=0;
22509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        char buf[1024];
22519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        va_list ap;
22529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        va_start(ap, fmt);
22539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        retval = vsnprintf(buf, sizeof(buf), fmt, ap);
22549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        va_end(ap);
22559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ac->sourcePos.error("Error: %s (at '%s' with value '%s').\n",
22569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            buf, ac->attr.string(), ac->value.string());
22579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
22599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::getAttributeKeys(
22619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t attrID, Vector<String16>* outKeys)
22629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
22639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<const Entry> e = getEntry(attrID);
22649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (e != NULL) {
22659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t N = e->getBag().size();
22669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (size_t i=0; i<N; i++) {
22679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const String16& key = e->getBag().keyAt(i);
22689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (key.size() > 0 && key.string()[0] != '^') {
22699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                outKeys->add(key);
22709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
22719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
22729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
22739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return false;
22759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
22769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::getAttributeEnum(
22789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t attrID, const char16_t* name, size_t nameLen,
22799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Res_value* outValue)
22809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
22819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //printf("getAttributeEnum #%08x %s\n", attrID, String8(name, nameLen).string());
22829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String16 nameStr(name, nameLen);
22839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<const Entry> e = getEntry(attrID);
22849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (e != NULL) {
22859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t N = e->getBag().size();
22869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (size_t i=0; i<N; i++) {
22879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //printf("Comparing %s to %s\n", String8(name, nameLen).string(),
22889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //       String8(e->getBag().keyAt(i)).string());
22899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (e->getBag().keyAt(i) == nameStr) {
22909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return getItemValue(attrID, e->getBag().valueAt(i).bagKeyId, outValue);
22919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
22929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
22939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return false;
22959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
22969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::getAttributeFlags(
22989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t attrID, const char16_t* name, size_t nameLen,
22999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Res_value* outValue)
23009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
23019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    outValue->dataType = Res_value::TYPE_INT_HEX;
23029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    outValue->data = 0;
23039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //printf("getAttributeFlags #%08x %s\n", attrID, String8(name, nameLen).string());
23059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String16 nameStr(name, nameLen);
23069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<const Entry> e = getEntry(attrID);
23079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (e != NULL) {
23089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t N = e->getBag().size();
23099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const char16_t* end = name + nameLen;
23119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const char16_t* pos = name;
231259eb5fd509c98a371b8824f6b13cf29981a4f063Ben Gruver        while (pos < end) {
23139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const char16_t* start = pos;
23149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            while (pos < end && *pos != '|') {
23159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pos++;
23169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
23179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String16 nameStr(start, pos-start);
23199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            size_t i;
23209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (i=0; i<N; i++) {
23219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                //printf("Comparing \"%s\" to \"%s\"\n", String8(nameStr).string(),
23229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                //       String8(e->getBag().keyAt(i)).string());
23239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (e->getBag().keyAt(i) == nameStr) {
23249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Res_value val;
23259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    bool got = getItemValue(attrID, e->getBag().valueAt(i).bagKeyId, &val);
23269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (!got) {
23279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        return false;
23289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
23299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    //printf("Got value: 0x%08x\n", val.data);
23309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    outValue->data |= val.data;
23319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
23329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
23339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
23349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (i >= N) {
23369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Didn't find this flag identifier.
23379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return false;
23389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
233959eb5fd509c98a371b8824f6b13cf29981a4f063Ben Gruver            pos++;
23409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
23419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
23439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
23449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return false;
23459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
23469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::assignResourceIds()
23489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
23499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t N = mOrderedPackages.size();
23509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t pi;
23519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t firstError = NO_ERROR;
23529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // First generate all bag attributes and assign indices.
23549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (pi=0; pi<N; pi++) {
23559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<Package> p = mOrderedPackages.itemAt(pi);
23569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (p == NULL || p->getTypes().size() == 0) {
23579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Empty, skip!
23589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            continue;
23599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
23609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        status_t err = p->applyPublicTypeOrder();
23629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != NO_ERROR && firstError == NO_ERROR) {
23639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            firstError = err;
23649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
23659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Generate attributes...
23679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t N = p->getOrderedTypes().size();
23689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        size_t ti;
23699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (ti=0; ti<N; ti++) {
23709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<Type> t = p->getOrderedTypes().itemAt(ti);
23719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (t == NULL) {
23729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
23739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
23749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const size_t N = t->getOrderedConfigs().size();
23759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (size_t ci=0; ci<N; ci++) {
23769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);
23779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (c == NULL) {
23789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
23799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
23809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                const size_t N = c->getEntries().size();
23819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (size_t ei=0; ei<N; ei++) {
23829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sp<Entry> e = c->getEntries().valueAt(ei);
23839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (e == NULL) {
23849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        continue;
23859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
23869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    status_t err = e->generateAttributes(this, p->getName());
23879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (err != NO_ERROR && firstError == NO_ERROR) {
23889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        firstError = err;
23899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
23909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
23919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
23929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
23939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const SourcePos unknown(String8("????"), 0);
23959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<Type> attr = p->getType(String16("attr"), unknown);
23969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Assign indices...
23989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (ti=0; ti<N; ti++) {
23999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<Type> t = p->getOrderedTypes().itemAt(ti);
24009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (t == NULL) {
24019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
24029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
24039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            err = t->applyPublicEntryOrder();
24049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (err != NO_ERROR && firstError == NO_ERROR) {
24059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                firstError = err;
24069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
24079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const size_t N = t->getOrderedConfigs().size();
24099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            t->setIndex(ti+1);
24109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOG_ALWAYS_FATAL_IF(ti == 0 && attr != t,
24129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                "First type is not attr!");
24139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (size_t ei=0; ei<N; ei++) {
24159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ei);
24169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (c == NULL) {
24179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
24189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
24199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                c->setEntryIndex(ei);
24209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
24219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
24229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Assign resource IDs to keys in bags...
24249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (ti=0; ti<N; ti++) {
24259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<Type> t = p->getOrderedTypes().itemAt(ti);
24269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (t == NULL) {
24279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
24289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
24299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const size_t N = t->getOrderedConfigs().size();
24309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (size_t ci=0; ci<N; ci++) {
24319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);
24329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                //printf("Ordered config #%d: %p\n", ci, c.get());
24339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                const size_t N = c->getEntries().size();
24349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (size_t ei=0; ei<N; ei++) {
24359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sp<Entry> e = c->getEntries().valueAt(ei);
24369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (e == NULL) {
24379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        continue;
24389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
24399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    status_t err = e->assignResourceIds(this, p->getName());
24409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (err != NO_ERROR && firstError == NO_ERROR) {
24419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        firstError = err;
24429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
24439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
24449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
24459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
24469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
24479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return firstError;
24489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
24499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::addSymbols(const sp<AaptSymbols>& outSymbols) {
24519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t N = mOrderedPackages.size();
24529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t pi;
24539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (pi=0; pi<N; pi++) {
24559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<Package> p = mOrderedPackages.itemAt(pi);
24569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (p->getTypes().size() == 0) {
24579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Empty, skip!
24589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            continue;
24599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
24609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t N = p->getOrderedTypes().size();
24629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        size_t ti;
24639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (ti=0; ti<N; ti++) {
24659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<Type> t = p->getOrderedTypes().itemAt(ti);
24669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (t == NULL) {
24679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
24689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
24699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const size_t N = t->getOrderedConfigs().size();
24709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<AaptSymbols> typeSymbols;
24719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            typeSymbols = outSymbols->addNestedSymbol(String8(t->getName()), t->getPos());
24729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (size_t ci=0; ci<N; ci++) {
24739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);
24749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (c == NULL) {
24759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
24769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
24779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                uint32_t rid = getResId(p, t, ci);
24789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (rid == 0) {
24799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return UNKNOWN_ERROR;
24809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
24819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (Res_GETPACKAGE(rid) == (size_t)(p->getAssignedId()-1)) {
24829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    typeSymbols->addSymbol(String8(c->getName()), rid, c->getPos());
24839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String16 comment(c->getComment());
24859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    typeSymbols->appendComment(String8(c->getName()), comment, c->getPos());
24869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    //printf("Type symbol %s comment: %s\n", String8(e->getName()).string(),
24879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    //     String8(comment).string());
24889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    comment = c->getTypeComment();
24899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    typeSymbols->appendTypeComment(String8(c->getName()), comment);
24909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
24919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 0
24929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    printf("**** NO MATCH: 0x%08x vs 0x%08x\n",
24939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           Res_GETPACKAGE(rid), p->getAssignedId());
24949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
24959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
24969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
24979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
24989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
24999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
25009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
25019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid
25049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResourceTable::addLocalization(const String16& name, const String8& locale)
25059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
25069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mLocalizations[name].insert(locale);
25079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
25089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*!
25119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Flag various sorts of localization problems.  '+' indicates checks already implemented;
25129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * '-' indicates checks that will be implemented in the future.
25139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
25149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * + A localized string for which no default-locale version exists => warning
25159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * + A string for which no version in an explicitly-requested locale exists => warning
25169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * + A localized translation of an translateable="false" string => warning
25179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * - A localized string not provided in every locale used by the table
25189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
25199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t
25209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResourceTable::validateLocalizations(void)
25219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
25229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = NO_ERROR;
25239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String8 defaultLocale;
25249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // For all strings...
25269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (map<String16, set<String8> >::iterator nameIter = mLocalizations.begin();
25279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         nameIter != mLocalizations.end();
25289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         nameIter++) {
25299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const set<String8>& configSet = nameIter->second;   // naming convenience
25309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Look for strings with no default localization
25329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (configSet.count(defaultLocale) == 0) {
25339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stdout, "aapt: warning: string '%s' has no default translation in %s; found:",
25349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(nameIter->first).string(), mBundle->getResourceSourceDirs()[0]);
2535f1ff21ac62a51f5ba8ca0821ea8a90f70957e25dSteve Block            for (set<String8>::const_iterator locales = configSet.begin();
25369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 locales != configSet.end();
25379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 locales++) {
25389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                fprintf(stdout, " %s", (*locales).string());
25399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
25409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stdout, "\n");
25419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // !!! TODO: throw an error here in some circumstances
25429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
25439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Check that all requested localizations are present for this string
25459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mBundle->getConfigurations() != NULL && mBundle->getRequireLocalization()) {
25469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const char* allConfigs = mBundle->getConfigurations();
25479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const char* start = allConfigs;
25489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const char* comma;
25499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            do {
25519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String8 config;
25529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                comma = strchr(start, ',');
25539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (comma != NULL) {
25549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    config.setTo(start, comma - start);
25559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    start = comma + 1;
25569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
25579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    config.setTo(start);
25589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
25599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // don't bother with the pseudolocale "zz_ZZ"
25619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (config != "zz_ZZ") {
25629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (configSet.find(config) == configSet.end()) {
25639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // okay, no specific localization found.  it's possible that we are
25649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // requiring a specific regional localization [e.g. de_DE] but there is an
25659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // available string in the generic language localization [e.g. de];
25669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // consider that string to have fulfilled the localization requirement.
25679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String8 region(config.string(), 2);
25689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (configSet.find(region) == configSet.end()) {
25699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            if (configSet.count(defaultLocale) == 0) {
2570c87d25215c842cea370c6a86ce67585fa8da4900Eric Fischer                                fprintf(stdout, "aapt: warning: "
257165e185b51ec655518f1917418cd6192400ac439dEd Heyl                                        "**** string '%s' has no default or required localization "
25729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        "for '%s' in %s\n",
25739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        String8(nameIter->first).string(),
25749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        config.string(),
25759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        mBundle->getResourceSourceDirs()[0]);
25769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
25779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
25789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
25799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
25809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project           } while (comma != NULL);
25819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
25829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
25839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err;
25859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
25869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest)
25889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
25899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ResourceFilter filter;
25909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = filter.parse(bundle->getConfigurations());
25919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != NO_ERROR) {
25929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return err;
25939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
25949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25956c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn    const ConfigDescription nullConfig;
25966c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn
25979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t N = mOrderedPackages.size();
25989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t pi;
25999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26007c71023b7f5aafac09bd2f0425fccb5fe2d22b27Kenny Root    const static String16 mipmap16("mipmap");
26017c71023b7f5aafac09bd2f0425fccb5fe2d22b27Kenny Root
26026c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn    bool useUTF8 = !bundle->getUTF16StringsOption();
26031741cd4904414b5b4e768953a8f1abb3f0ef0a0aKenny Root
26049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Iterate through all data, collecting all values (strings,
26059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // references, etc).
2606345b7eb8749d6954942fd4e961fff9f2f854934cJeff Brown    StringPool valueStrings(useUTF8);
26076c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn    Vector<sp<Entry> > allEntries;
26089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (pi=0; pi<N; pi++) {
26099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<Package> p = mOrderedPackages.itemAt(pi);
26109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (p->getTypes().size() == 0) {
26119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Empty, skip!
26129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            continue;
26139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
26149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2615345b7eb8749d6954942fd4e961fff9f2f854934cJeff Brown        StringPool typeStrings(useUTF8);
2616345b7eb8749d6954942fd4e961fff9f2f854934cJeff Brown        StringPool keyStrings(useUTF8);
26179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t N = p->getOrderedTypes().size();
26199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (size_t ti=0; ti<N; ti++) {
26209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<Type> t = p->getOrderedTypes().itemAt(ti);
26219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (t == NULL) {
26229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                typeStrings.add(String16("<empty>"), false);
26239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
26249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
26257c71023b7f5aafac09bd2f0425fccb5fe2d22b27Kenny Root            const String16 typeName(t->getName());
26267c71023b7f5aafac09bd2f0425fccb5fe2d22b27Kenny Root            typeStrings.add(typeName, false);
26277c71023b7f5aafac09bd2f0425fccb5fe2d22b27Kenny Root
26286c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn            // This is a hack to tweak the sorting order of the final strings,
26296c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn            // to put stuff that is generally not language-specific first.
26306c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn            String8 configTypeName(typeName);
26316c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn            if (configTypeName == "drawable" || configTypeName == "layout"
26326c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn                    || configTypeName == "color" || configTypeName == "anim"
26336c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn                    || configTypeName == "interpolator" || configTypeName == "animator"
26346c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn                    || configTypeName == "xml" || configTypeName == "menu"
26356c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn                    || configTypeName == "mipmap" || configTypeName == "raw") {
26366c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn                configTypeName = "1complex";
26376c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn            } else {
26386c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn                configTypeName = "2value";
26396c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn            }
26406c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn
26417c71023b7f5aafac09bd2f0425fccb5fe2d22b27Kenny Root            const bool filterable = (typeName != mipmap16);
26429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const size_t N = t->getOrderedConfigs().size();
26449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (size_t ci=0; ci<N; ci++) {
26459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);
26469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (c == NULL) {
26479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
26489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
26499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                const size_t N = c->getEntries().size();
26509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (size_t ei=0; ei<N; ei++) {
26519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ConfigDescription config = c->getEntries().keyAt(ei);
26527c71023b7f5aafac09bd2f0425fccb5fe2d22b27Kenny Root                    if (filterable && !filter.match(config)) {
26539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        continue;
26549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
26559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sp<Entry> e = c->getEntries().valueAt(ei);
26569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (e == NULL) {
26579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        continue;
26589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
26599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    e->setNameIndex(keyStrings.add(e->getName(), true));
26606c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn
26616c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn                    // If this entry has no values for other configs,
26626c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn                    // and is the default config, then it is special.  Otherwise
26636c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn                    // we want to add it with the config info.
26646c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn                    ConfigDescription* valueConfig = NULL;
26656c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn                    if (N != 1 || config == nullConfig) {
26666c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn                        valueConfig = &config;
26676c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn                    }
26686c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn
26696c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn                    status_t err = e->prepareFlatten(&valueStrings, this,
26706c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn                            &configTypeName, &config);
26719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (err != NO_ERROR) {
26729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        return err;
26739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
26746c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn                    allEntries.add(e);
26759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
26769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
26779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
26789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p->setTypeStrings(typeStrings.createStringBlock());
26809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p->setKeyStrings(keyStrings.createStringBlock());
26819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
26829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26836c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn    if (bundle->getOutputAPKFile() != NULL) {
26846c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn        // Now we want to sort the value strings for better locality.  This will
26856c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn        // cause the positions of the strings to change, so we need to go back
26866c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn        // through out resource entries and update them accordingly.  Only need
26876c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn        // to do this if actually writing the output file.
26886c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn        valueStrings.sortByConfig();
26896c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn        for (pi=0; pi<allEntries.size(); pi++) {
26906c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn            allEntries[pi]->remapStringValue(&valueStrings);
26916c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn        }
26926c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn    }
26936c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn
26949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ssize_t strAmt = 0;
26959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Now build the array of package chunks.
26979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Vector<sp<AaptFile> > flatPackages;
26989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (pi=0; pi<N; pi++) {
26999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<Package> p = mOrderedPackages.itemAt(pi);
27009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (p->getTypes().size() == 0) {
27019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Empty, skip!
27029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            continue;
27039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
27049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t N = p->getTypeStrings().size();
27069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t baseSize = sizeof(ResTable_package);
27089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Start the package data.
27109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<AaptFile> data = new AaptFile(String8(), AaptGroupEntry(), String8());
27119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ResTable_package* header = (ResTable_package*)data->editData(baseSize);
27129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (header == NULL) {
27139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "ERROR: out of memory creating ResTable_package\n");
27149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return NO_MEMORY;
27159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
27169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        memset(header, 0, sizeof(*header));
27179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header->header.type = htods(RES_TABLE_PACKAGE_TYPE);
27189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header->header.headerSize = htods(sizeof(*header));
27199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header->id = htodl(p->getAssignedId());
27209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        strcpy16_htod(header->name, p->getName().string());
27219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Write the string blocks.
27239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t typeStringsStart = data->getSize();
27249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<AaptFile> strFile = p->getTypeStringsData();
27259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ssize_t amt = data->writeData(strFile->getData(), strFile->getSize());
27269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        #if PRINT_STRING_METRICS
27279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fprintf(stderr, "**** type strings: %d\n", amt);
27289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        #endif
27299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        strAmt += amt;
27309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (amt < 0) {
27319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return amt;
27329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
27339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t keyStringsStart = data->getSize();
27349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        strFile = p->getKeyStringsData();
27359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        amt = data->writeData(strFile->getData(), strFile->getSize());
27369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        #if PRINT_STRING_METRICS
27379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fprintf(stderr, "**** key strings: %d\n", amt);
27389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        #endif
27399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        strAmt += amt;
27409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (amt < 0) {
27419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return amt;
27429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
27439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Build the type chunks inside of this package.
27459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (size_t ti=0; ti<N; ti++) {
27469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Retrieve them in the same order as the type string block.
27479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            size_t len;
27489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String16 typeName(p->getTypeStrings().stringAt(ti, &len));
27499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<Type> t = p->getTypes().valueFor(typeName);
27509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOG_ALWAYS_FATAL_IF(t == NULL && typeName != String16("<empty>"),
27519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                "Type name %s not found",
27529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                String8(typeName).string());
27539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27547c71023b7f5aafac09bd2f0425fccb5fe2d22b27Kenny Root            const bool filterable = (typeName != mipmap16);
27557c71023b7f5aafac09bd2f0425fccb5fe2d22b27Kenny Root
27569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const size_t N = t != NULL ? t->getOrderedConfigs().size() : 0;
2757249e3ed5400e5c7ab2e9aa8017f612d79d2e8089MÃ¥rten Kongstad
2758249e3ed5400e5c7ab2e9aa8017f612d79d2e8089MÃ¥rten Kongstad            // Until a non-NO_ENTRY value has been written for a resource,
2759249e3ed5400e5c7ab2e9aa8017f612d79d2e8089MÃ¥rten Kongstad            // that resource is invalid; validResources[i] represents
2760249e3ed5400e5c7ab2e9aa8017f612d79d2e8089MÃ¥rten Kongstad            // the item at t->getOrderedConfigs().itemAt(i).
2761249e3ed5400e5c7ab2e9aa8017f612d79d2e8089MÃ¥rten Kongstad            Vector<bool> validResources;
2762249e3ed5400e5c7ab2e9aa8017f612d79d2e8089MÃ¥rten Kongstad            validResources.insertAt(false, 0, N);
27639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // First write the typeSpec chunk, containing information about
27659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // each resource entry in this type.
27669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            {
27679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                const size_t typeSpecSize = sizeof(ResTable_typeSpec) + sizeof(uint32_t)*N;
27689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                const size_t typeSpecStart = data->getSize();
27699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ResTable_typeSpec* tsHeader = (ResTable_typeSpec*)
27709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    (((uint8_t*)data->editData(typeSpecStart+typeSpecSize)) + typeSpecStart);
27719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (tsHeader == NULL) {
27729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    fprintf(stderr, "ERROR: out of memory creating ResTable_typeSpec\n");
27739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return NO_MEMORY;
27749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
27759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                memset(tsHeader, 0, sizeof(*tsHeader));
27769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tsHeader->header.type = htods(RES_TABLE_TYPE_SPEC_TYPE);
27779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tsHeader->header.headerSize = htods(sizeof(*tsHeader));
27789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tsHeader->header.size = htodl(typeSpecSize);
27799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tsHeader->id = ti+1;
27809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tsHeader->entryCount = htodl(N);
27819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                uint32_t* typeSpecFlags = (uint32_t*)
27839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    (((uint8_t*)data->editData())
27849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + typeSpecStart + sizeof(ResTable_typeSpec));
27859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                memset(typeSpecFlags, 0, sizeof(uint32_t)*N);
27867c71023b7f5aafac09bd2f0425fccb5fe2d22b27Kenny Root
27879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (size_t ei=0; ei<N; ei++) {
27889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sp<ConfigList> cl = t->getOrderedConfigs().itemAt(ei);
27899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (cl->getPublic()) {
27909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        typeSpecFlags[ei] |= htodl(ResTable_typeSpec::SPEC_PUBLIC);
27919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
27929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    const size_t CN = cl->getEntries().size();
27939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    for (size_t ci=0; ci<CN; ci++) {
27947c71023b7f5aafac09bd2f0425fccb5fe2d22b27Kenny Root                        if (filterable && !filter.match(cl->getEntries().keyAt(ci))) {
27959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            continue;
27969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
27979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        for (size_t cj=ci+1; cj<CN; cj++) {
27987c71023b7f5aafac09bd2f0425fccb5fe2d22b27Kenny Root                            if (filterable && !filter.match(cl->getEntries().keyAt(cj))) {
27999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                continue;
28009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
28019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            typeSpecFlags[ei] |= htodl(
28029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                cl->getEntries().keyAt(ci).diff(cl->getEntries().keyAt(cj)));
28039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
28049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
28059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
28069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
28079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // We need to write one type chunk for each configuration for
28099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // which we have entries in this type.
28109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const size_t NC = t->getUniqueConfigs().size();
28119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const size_t typeSize = sizeof(ResTable_type) + sizeof(uint32_t)*N;
28139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (size_t ci=0; ci<NC; ci++) {
28159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ConfigDescription config = t->getUniqueConfigs().itemAt(ci);
28169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                NOISY(printf("Writing config %d config: imsi:%d/%d lang:%c%c cnt:%c%c "
281869cb87576ba163b61bb0e6477a3b7c57a9b11d40Dianne Hackborn                     "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d "
28195f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio                     "sw%ddp w%ddp h%ddp dir:%d\n",
28209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      ti+1,
28219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.mcc, config.mnc,
28229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.language[0] ? config.language[0] : '-',
28239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.language[1] ? config.language[1] : '-',
28249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.country[0] ? config.country[0] : '-',
28259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.country[1] ? config.country[1] : '-',
28269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.orientation,
282727b28b3f62bd3b54fa13acd5d035940b9be464f3Tobias Haamel                      config.uiMode,
28289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.touchscreen,
28299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.density,
28309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.keyboard,
28319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.inputFlags,
28329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.navigation,
28339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config.screenWidth,
2834ebff8f92f13513ce37bd74759eb1db63f2220590Dianne Hackborn                      config.screenHeight,
283569cb87576ba163b61bb0e6477a3b7c57a9b11d40Dianne Hackborn                      config.smallestScreenWidthDp,
2836ebff8f92f13513ce37bd74759eb1db63f2220590Dianne Hackborn                      config.screenWidthDp,
28375f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio                      config.screenHeightDp,
28385f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio                      config.layoutDirection));
28399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28407c71023b7f5aafac09bd2f0425fccb5fe2d22b27Kenny Root                if (filterable && !filter.match(config)) {
28419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
28429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
28439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                const size_t typeStart = data->getSize();
28459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ResTable_type* tHeader = (ResTable_type*)
28479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    (((uint8_t*)data->editData(typeStart+typeSize)) + typeStart);
28489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (tHeader == NULL) {
28499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    fprintf(stderr, "ERROR: out of memory creating ResTable_type\n");
28509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return NO_MEMORY;
28519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
28529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                memset(tHeader, 0, sizeof(*tHeader));
28549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tHeader->header.type = htods(RES_TABLE_TYPE_TYPE);
28559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tHeader->header.headerSize = htods(sizeof(*tHeader));
28569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tHeader->id = ti+1;
28579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tHeader->entryCount = htodl(N);
28589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tHeader->entriesStart = htodl(typeSize);
28599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tHeader->config = config;
28609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                NOISY(printf("Writing type %d config: imsi:%d/%d lang:%c%c cnt:%c%c "
286169cb87576ba163b61bb0e6477a3b7c57a9b11d40Dianne Hackborn                     "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d "
28625f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio                     "sw%ddp w%ddp h%ddp dir:%d\n",
28639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      ti+1,
28649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.mcc, tHeader->config.mnc,
28659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.language[0] ? tHeader->config.language[0] : '-',
28669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.language[1] ? tHeader->config.language[1] : '-',
28679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.country[0] ? tHeader->config.country[0] : '-',
28689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.country[1] ? tHeader->config.country[1] : '-',
28699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.orientation,
287027b28b3f62bd3b54fa13acd5d035940b9be464f3Tobias Haamel                      tHeader->config.uiMode,
28719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.touchscreen,
28729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.density,
28739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.keyboard,
28749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.inputFlags,
28759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.navigation,
28769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      tHeader->config.screenWidth,
2877ebff8f92f13513ce37bd74759eb1db63f2220590Dianne Hackborn                      tHeader->config.screenHeight,
287869cb87576ba163b61bb0e6477a3b7c57a9b11d40Dianne Hackborn                      tHeader->config.smallestScreenWidthDp,
2879ebff8f92f13513ce37bd74759eb1db63f2220590Dianne Hackborn                      tHeader->config.screenWidthDp,
28805f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio                      tHeader->config.screenHeightDp,
28815f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio                      tHeader->config.layoutDirection));
28829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tHeader->config.swapHtoD();
28839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Build the entries inside of this type.
28859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (size_t ei=0; ei<N; ei++) {
28869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sp<ConfigList> cl = t->getOrderedConfigs().itemAt(ei);
28879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sp<Entry> e = cl->getEntries().valueFor(config);
28889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Set the offset for this entry in its type.
28909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    uint32_t* index = (uint32_t*)
28919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        (((uint8_t*)data->editData())
28929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            + typeStart + sizeof(ResTable_type));
28939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (e != NULL) {
28949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        index[ei] = htodl(data->getSize()-typeStart-typeSize);
28959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // Create the entry.
28979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ssize_t amt = e->flatten(bundle, data, cl->getPublic());
28989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (amt < 0) {
28999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            return amt;
29009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
2901249e3ed5400e5c7ab2e9aa8017f612d79d2e8089MÃ¥rten Kongstad                        validResources.editItemAt(ei) = true;
29029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else {
29039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        index[ei] = htodl(ResTable_type::NO_ENTRY);
29049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
29059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
29069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Fill in the rest of the type information.
29089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tHeader = (ResTable_type*)
29099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    (((uint8_t*)data->editData()) + typeStart);
29109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tHeader->header.size = htodl(data->getSize()-typeStart);
29119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2912249e3ed5400e5c7ab2e9aa8017f612d79d2e8089MÃ¥rten Kongstad
2913249e3ed5400e5c7ab2e9aa8017f612d79d2e8089MÃ¥rten Kongstad            for (size_t i = 0; i < N; ++i) {
2914249e3ed5400e5c7ab2e9aa8017f612d79d2e8089MÃ¥rten Kongstad                if (!validResources[i]) {
2915249e3ed5400e5c7ab2e9aa8017f612d79d2e8089MÃ¥rten Kongstad                    sp<ConfigList> c = t->getOrderedConfigs().itemAt(i);
2916249e3ed5400e5c7ab2e9aa8017f612d79d2e8089MÃ¥rten Kongstad                    fprintf(stderr, "warning: no entries written for %s/%s\n",
2917249e3ed5400e5c7ab2e9aa8017f612d79d2e8089MÃ¥rten Kongstad                            String8(typeName).string(), String8(c->getName()).string());
2918249e3ed5400e5c7ab2e9aa8017f612d79d2e8089MÃ¥rten Kongstad                }
2919249e3ed5400e5c7ab2e9aa8017f612d79d2e8089MÃ¥rten Kongstad            }
29209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
29219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Fill in the rest of the package information.
29239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header = (ResTable_package*)data->editData();
29249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header->header.size = htodl(data->getSize());
29259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header->typeStrings = htodl(typeStringsStart);
29269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header->lastPublicType = htodl(p->getTypeStrings().size());
29279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header->keyStrings = htodl(keyStringsStart);
29289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header->lastPublicKey = htodl(p->getKeyStrings().size());
29299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        flatPackages.add(data);
29319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
29329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // And now write out the final chunks.
29349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t dataStart = dest->getSize();
29359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
29379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // blah
29389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ResTable_header header;
29399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        memset(&header, 0, sizeof(header));
29409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header.header.type = htods(RES_TABLE_TYPE);
29419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header.header.headerSize = htods(sizeof(header));
29429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header.packageCount = htodl(flatPackages.size());
29439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        status_t err = dest->writeData(&header, sizeof(header));
29449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != NO_ERROR) {
29459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "ERROR: out of memory creating ResTable_header\n");
29469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return err;
29479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
29489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
29499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ssize_t strStart = dest->getSize();
29519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    err = valueStrings.writeStringBlock(dest);
29529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != NO_ERROR) {
29539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return err;
29549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
29559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ssize_t amt = (dest->getSize()-strStart);
29579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    strAmt += amt;
29589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    #if PRINT_STRING_METRICS
29599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    fprintf(stderr, "**** value strings: %d\n", amt);
29609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    fprintf(stderr, "**** total strings: %d\n", strAmt);
29619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    #endif
29629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (pi=0; pi<flatPackages.size(); pi++) {
29649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        err = dest->writeData(flatPackages[pi]->getData(),
29659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                              flatPackages[pi]->getSize());
29669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != NO_ERROR) {
29679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "ERROR: out of memory creating package chunk for ResTable_header\n");
29689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return err;
29699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
29709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
29719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ResTable_header* header = (ResTable_header*)
29739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (((uint8_t*)dest->getData()) + dataStart);
29749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    header->header.size = htodl(dest->getSize() - dataStart);
29759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    NOISY(aout << "Resource table:"
29779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project          << HexDump(dest->getData(), dest->getSize()) << endl);
29789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    #if PRINT_STRING_METRICS
29809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    fprintf(stderr, "**** total resource table size: %d / %d%% strings\n",
29819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dest->getSize(), (strAmt*100)/dest->getSize());
29829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    #endif
29839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
29859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
29869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResourceTable::writePublicDefinitions(const String16& package, FILE* fp)
29889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
29899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    fprintf(fp,
29909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    "<!-- This file contains <public> resource definitions for all\n"
29919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    "     resources that were generated from the source data. -->\n"
29929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    "\n"
29939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    "<resources>\n");
29949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    writePublicDefinitions(package, fp, true);
29969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    writePublicDefinitions(package, fp, false);
29979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    fprintf(fp,
29999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    "\n"
30009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    "</resources>\n");
30019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
30029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
30039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResourceTable::writePublicDefinitions(const String16& package, FILE* fp, bool pub)
30049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
30059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool didHeader = false;
30069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
30079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Package> pkg = mPackages.valueFor(package);
30089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (pkg != NULL) {
30099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t NT = pkg->getOrderedTypes().size();
30109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (size_t i=0; i<NT; i++) {
30119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<Type> t = pkg->getOrderedTypes().itemAt(i);
30129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (t == NULL) {
30139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
30149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
30159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
30169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bool didType = false;
30179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
30189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const size_t NC = t->getOrderedConfigs().size();
30199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (size_t j=0; j<NC; j++) {
30209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sp<ConfigList> c = t->getOrderedConfigs().itemAt(j);
30219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (c == NULL) {
30229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
30239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
30249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
30259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (c->getPublic() != pub) {
30269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
30279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
30289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
30299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!didType) {
30309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    fprintf(fp, "\n");
30319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    didType = true;
30329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
30339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!didHeader) {
30349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (pub) {
30359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        fprintf(fp,"  <!-- PUBLIC SECTION.  These resources have been declared public.\n");
30369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        fprintf(fp,"       Changes to these definitions will break binary compatibility. -->\n\n");
30379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else {
30389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        fprintf(fp,"  <!-- PRIVATE SECTION.  These resources have not been declared public.\n");
30399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        fprintf(fp,"       You can make them public my moving these lines into a file in res/values. -->\n\n");
30409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
30419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    didHeader = true;
30429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
30439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!pub) {
30449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    const size_t NE = c->getEntries().size();
30459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    for (size_t k=0; k<NE; k++) {
30469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const SourcePos& pos = c->getEntries().valueAt(k)->getPos();
30479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (pos.file != "") {
30489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            fprintf(fp,"  <!-- Declared at %s:%d -->\n",
30499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    pos.file.string(), pos.line);
30509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
30519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
30529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
30539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                fprintf(fp, "  <public type=\"%s\" name=\"%s\" id=\"0x%08x\" />\n",
30549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String8(t->getName()).string(),
30559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String8(c->getName()).string(),
30569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        getResId(pkg, t, c->getEntryIndex()));
30579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
30589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
30599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
30609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
30619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
30629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResourceTable::Item::Item(const SourcePos& _sourcePos,
30639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                          bool _isId,
30649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                          const String16& _value,
30659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                          const Vector<StringPool::entry_style_span>* _style,
30669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                          int32_t _format)
30679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    : sourcePos(_sourcePos)
30689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    , isId(_isId)
30699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    , value(_value)
30709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    , format(_format)
30719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    , bagKeyId(0)
30729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    , evaluating(false)
30739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
30749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (_style) {
30759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        style = *_style;
30769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
30779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
30789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
30799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::Entry::makeItABag(const SourcePos& sourcePos)
30809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
30819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mType == TYPE_BAG) {
30829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NO_ERROR;
30839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
30849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mType == TYPE_UNKNOWN) {
30859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mType = TYPE_BAG;
30869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NO_ERROR;
30879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
30889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sourcePos.error("Resource entry %s is already defined as a single item.\n"
30899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    "%s:%d: Originally defined here.\n",
30909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(mName).string(),
30919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mItem.sourcePos.file.string(), mItem.sourcePos.line);
30929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return UNKNOWN_ERROR;
30939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
30949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
30959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::Entry::setItem(const SourcePos& sourcePos,
30969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       const String16& value,
30979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       const Vector<StringPool::entry_style_span>* style,
30989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       int32_t format,
30999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       const bool overwrite)
31009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
31019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Item item(sourcePos, false, value, style);
31029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
31039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mType == TYPE_BAG) {
31049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const Item& item(mBag.valueAt(0));
31059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sourcePos.error("Resource entry %s is already defined as a bag.\n"
31069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        "%s:%d: Originally defined here.\n",
31079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String8(mName).string(),
31089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        item.sourcePos.file.string(), item.sourcePos.line);
31099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
31109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
31119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if ( (mType != TYPE_UNKNOWN) && (overwrite == false) ) {
31129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sourcePos.error("Resource entry %s is already defined.\n"
31139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        "%s:%d: Originally defined here.\n",
31149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String8(mName).string(),
31159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        mItem.sourcePos.file.string(), mItem.sourcePos.line);
31169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
31179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3118f878e2d80c3a0afefe3b018d232df6066379e1d5Robert Greenwalt
31199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mType = TYPE_ITEM;
31209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mItem = item;
31219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mItemFormat = format;
31229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
31239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
31249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
31259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::Entry::addToBag(const SourcePos& sourcePos,
31269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        const String16& key, const String16& value,
31279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        const Vector<StringPool::entry_style_span>* style,
31289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        bool replace, bool isId, int32_t format)
31299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
31309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = makeItABag(sourcePos);
31319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != NO_ERROR) {
31329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return err;
31339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
31349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
31359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Item item(sourcePos, isId, value, style, format);
31369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
31379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // XXX NOTE: there is an error if you try to have a bag with two keys,
31389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // one an attr and one an id, with the same name.  Not something we
31399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // currently ever have to worry about.
31409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ssize_t origKey = mBag.indexOfKey(key);
31419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (origKey >= 0) {
31429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!replace) {
31439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const Item& item(mBag.valueAt(origKey));
31449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sourcePos.error("Resource entry %s already has bag item %s.\n"
31459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    "%s:%d: Originally defined here.\n",
31469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(mName).string(), String8(key).string(),
31479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    item.sourcePos.file.string(), item.sourcePos.line);
31489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return UNKNOWN_ERROR;
31499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
31509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //printf("Replacing %s with %s\n",
31519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //       String8(mBag.valueFor(key).value).string(), String8(value).string());
31529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mBag.replaceValueFor(key, item);
31539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
31549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
31559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mBag.add(key, item);
31569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
31579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
31589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
31594b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwaltstatus_t ResourceTable::Entry::emptyBag(const SourcePos& sourcePos)
31604b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt{
31614b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt    status_t err = makeItABag(sourcePos);
31624b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt    if (err != NO_ERROR) {
31634b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt        return err;
31644b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt    }
31654b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt
31664b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt    mBag.clear();
31674b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt    return NO_ERROR;
31684b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt}
31694b4f4a908895bc0ba63f929bfdc02eec22c0f6e5Robert Greenwalt
31709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::Entry::generateAttributes(ResourceTable* table,
31719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                  const String16& package)
31729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
31739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 attr16("attr");
31749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16 id16("id");
31759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t N = mBag.size();
31769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (size_t i=0; i<N; i++) {
31779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const String16& key = mBag.keyAt(i);
31789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const Item& it = mBag.valueAt(i);
31799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (it.isId) {
31809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!table->hasBagOrEntry(key, &id16, &package)) {
31819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String16 value("false");
31829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                status_t err = table->addEntry(SourcePos(String8("<generated>"), 0), package,
31839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                               id16, key, value);
31849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (err != NO_ERROR) {
31859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return err;
31869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
31879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
31889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (!table->hasBagOrEntry(key, &attr16, &package)) {
31899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
31909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 1
31919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//             fprintf(stderr, "ERROR: Bag attribute '%s' has not been defined.\n",
31929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//                     String8(key).string());
31939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//             const Item& item(mBag.valueAt(i));
31949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//             fprintf(stderr, "Referenced from file %s line %d\n",
31959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//                     item.sourcePos.file.string(), item.sourcePos.line);
31969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//             return UNKNOWN_ERROR;
31979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else
31989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            char numberStr[16];
31999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sprintf(numberStr, "%d", ResTable_map::TYPE_ANY);
32009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            status_t err = table->addBag(SourcePos("<generated>", 0), package,
32019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                         attr16, key, String16(""),
32029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                         String16("^type"),
32039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                         String16(numberStr), NULL, NULL);
32049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (err != NO_ERROR) {
32059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return err;
32069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
32079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
32089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
32099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
32109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
32119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
32129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
32139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::Entry::assignResourceIds(ResourceTable* table,
32149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                 const String16& package)
32159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
32169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool hasErrors = false;
32179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
32189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mType == TYPE_BAG) {
32199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const char* errorMsg;
32209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const String16 style16("style");
32219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const String16 attr16("attr");
32229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const String16 id16("id");
32239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mParentId = 0;
32249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mParent.size() > 0) {
3225f795e9a86d4f62e5314ef95978c3ea17d90975dbDianne Hackborn            mParentId = table->getResId(mParent, &style16, NULL, &errorMsg);
32269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mParentId == 0) {
32279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mPos.error("Error retrieving parent for item: %s '%s'.\n",
32289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        errorMsg, String8(mParent).string());
32299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                hasErrors = true;
32309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
32319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
32329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t N = mBag.size();
32339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (size_t i=0; i<N; i++) {
32349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const String16& key = mBag.keyAt(i);
32359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Item& it = mBag.editValueAt(i);
32369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            it.bagKeyId = table->getResId(key,
3237f795e9a86d4f62e5314ef95978c3ea17d90975dbDianne Hackborn                    it.isId ? &id16 : &attr16, NULL, &errorMsg);
32389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //printf("Bag key of %s: #%08x\n", String8(key).string(), it.bagKeyId);
32399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (it.bagKeyId == 0) {
32409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                it.sourcePos.error("Error: %s: %s '%s'.\n", errorMsg,
32419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String8(it.isId ? id16 : attr16).string(),
32429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String8(key).string());
32439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                hasErrors = true;
32449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
32459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
32469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
32479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
32489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
32499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
32506c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackbornstatus_t ResourceTable::Entry::prepareFlatten(StringPool* strings, ResourceTable* table,
32516c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn        const String8* configTypeName, const ConfigDescription* config)
32529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
32539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mType == TYPE_ITEM) {
32549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Item& it = mItem;
32559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        AccessorCookie ac(it.sourcePos, String8(mName), String8(it.value));
32569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!table->stringToValue(&it.parsedValue, strings,
32579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  it.value, false, true, 0,
32586c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn                                  &it.style, NULL, &ac, mItemFormat,
32596c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn                                  configTypeName, config)) {
32609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return UNKNOWN_ERROR;
32619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
32629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (mType == TYPE_BAG) {
32639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t N = mBag.size();
32649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (size_t i=0; i<N; i++) {
32659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const String16& key = mBag.keyAt(i);
32669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Item& it = mBag.editValueAt(i);
32679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            AccessorCookie ac(it.sourcePos, String8(key), String8(it.value));
32689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!table->stringToValue(&it.parsedValue, strings,
32699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                      it.value, false, true, it.bagKeyId,
32706c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn                                      &it.style, NULL, &ac, it.format,
32716c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn                                      configTypeName, config)) {
32729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return UNKNOWN_ERROR;
32739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
32749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
32759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
32769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPos.error("Error: entry %s is not a single item or a bag.\n",
32779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                   String8(mName).string());
32789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
32799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
32809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
32819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
32829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
32836c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackbornstatus_t ResourceTable::Entry::remapStringValue(StringPool* strings)
32846c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn{
32856c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn    if (mType == TYPE_ITEM) {
32866c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn        Item& it = mItem;
32876c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn        if (it.parsedValue.dataType == Res_value::TYPE_STRING) {
32886c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn            it.parsedValue.data = strings->mapOriginalPosToNewPos(it.parsedValue.data);
32896c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn        }
32906c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn    } else if (mType == TYPE_BAG) {
32916c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn        const size_t N = mBag.size();
32926c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn        for (size_t i=0; i<N; i++) {
32936c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn            Item& it = mBag.editValueAt(i);
32946c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn            if (it.parsedValue.dataType == Res_value::TYPE_STRING) {
32956c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn                it.parsedValue.data = strings->mapOriginalPosToNewPos(it.parsedValue.data);
32966c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn            }
32976c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn        }
32986c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn    } else {
32996c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn        mPos.error("Error: entry %s is not a single item or a bag.\n",
33006c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn                   String8(mName).string());
33016c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn        return UNKNOWN_ERROR;
33026c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn    }
33036c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn    return NO_ERROR;
33046c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn}
33056c997a9e880e08c354ffd809bd62df9e25e9c4d4Dianne Hackborn
33069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t ResourceTable::Entry::flatten(Bundle* bundle, const sp<AaptFile>& data, bool isPublic)
33079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
33089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t amt = 0;
33099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ResTable_entry header;
33109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    memset(&header, 0, sizeof(header));
33119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    header.size = htods(sizeof(header));
33129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const type ty = this != NULL ? mType : TYPE_ITEM;
33139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (this != NULL) {
33149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ty == TYPE_BAG) {
33159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            header.flags |= htods(header.FLAG_COMPLEX);
33169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
33179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (isPublic) {
33189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            header.flags |= htods(header.FLAG_PUBLIC);
33199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
33209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        header.key.index = htodl(mNameIndex);
33219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
33229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (ty != TYPE_BAG) {
33239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        status_t err = data->writeData(&header, sizeof(header));
33249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != NO_ERROR) {
33259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "ERROR: out of memory creating ResTable_entry\n");
33269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return err;
33279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
33289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
33299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const Item& it = mItem;
33309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Res_value par;
33319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        memset(&par, 0, sizeof(par));
33329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        par.size = htods(it.parsedValue.size);
33339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        par.dataType = it.parsedValue.dataType;
33349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        par.res0 = it.parsedValue.res0;
33359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        par.data = htodl(it.parsedValue.data);
33369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        #if 0
33379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        printf("Writing item (%s): type=%d, data=0x%x, res0=0x%x\n",
33389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project               String8(mName).string(), it.parsedValue.dataType,
33399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project               it.parsedValue.data, par.res0);
33409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        #endif
33419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        err = data->writeData(&par, it.parsedValue.size);
33429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != NO_ERROR) {
33439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "ERROR: out of memory creating Res_value\n");
33449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return err;
33459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
33469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        amt += it.parsedValue.size;
33479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
33489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        size_t N = mBag.size();
33499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        size_t i;
33509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Create correct ordering of items.
33519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        KeyedVector<uint32_t, const Item*> items;
33529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (i=0; i<N; i++) {
33539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const Item& it = mBag.valueAt(i);
33549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            items.add(it.bagKeyId, &it);
33559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
33569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        N = items.size();
33579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
33589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ResTable_map_entry mapHeader;
33599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        memcpy(&mapHeader, &header, sizeof(header));
33609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mapHeader.size = htods(sizeof(mapHeader));
33619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mapHeader.parent.ident = htodl(mParentId);
33629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mapHeader.count = htodl(N);
33639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        status_t err = data->writeData(&mapHeader, sizeof(mapHeader));
33649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != NO_ERROR) {
33659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fprintf(stderr, "ERROR: out of memory creating ResTable_entry\n");
33669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return err;
33679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
33689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
33699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (i=0; i<N; i++) {
33709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const Item& it = *items.valueAt(i);
33719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ResTable_map map;
33729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            map.name.ident = htodl(it.bagKeyId);
33739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            map.value.size = htods(it.parsedValue.size);
33749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            map.value.dataType = it.parsedValue.dataType;
33759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            map.value.res0 = it.parsedValue.res0;
33769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            map.value.data = htodl(it.parsedValue.data);
33779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            err = data->writeData(&map, sizeof(map));
33789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (err != NO_ERROR) {
33799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                fprintf(stderr, "ERROR: out of memory creating Res_value\n");
33809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return err;
33819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
33829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            amt += sizeof(map);
33839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
33849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
33859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return amt;
33869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
33879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
33889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResourceTable::ConfigList::appendComment(const String16& comment,
33899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                              bool onlyIfEmpty)
33909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
33919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (comment.size() <= 0) {
33929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
33939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
33949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (onlyIfEmpty && mComment.size() > 0) {
33959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
33969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
33979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mComment.size() > 0) {
33989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mComment.append(String16("\n"));
33999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
34009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mComment.append(comment);
34019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
34029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ResourceTable::ConfigList::appendTypeComment(const String16& comment)
34049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
34059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (comment.size() <= 0) {
34069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
34079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
34089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mTypeComment.size() > 0) {
34099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mTypeComment.append(String16("\n"));
34109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
34119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mTypeComment.append(comment);
34129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
34139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::Type::addPublic(const SourcePos& sourcePos,
34159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        const String16& name,
34169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        const uint32_t ident)
34179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
34189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    #if 0
34199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t entryIdx = Res_GETENTRY(ident);
34209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (entryIdx < 0) {
34219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sourcePos.error("Public resource %s/%s has an invalid 0 identifier (0x%08x).\n",
34229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String8(mName).string(), String8(name).string(), ident);
34239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
34249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
34259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    #endif
34269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t typeIdx = Res_GETTYPE(ident);
34289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (typeIdx >= 0) {
34299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        typeIdx++;
34309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mPublicIndex > 0 && mPublicIndex != typeIdx) {
34319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sourcePos.error("Public resource %s/%s has conflicting type codes for its"
34329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    " public identifiers (0x%x vs 0x%x).\n",
34339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(mName).string(), String8(name).string(),
34349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mPublicIndex, typeIdx);
34359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return UNKNOWN_ERROR;
34369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
34379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPublicIndex = typeIdx;
34389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
34399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mFirstPublicSourcePos == NULL) {
34419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mFirstPublicSourcePos = new SourcePos(sourcePos);
34429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
34439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mPublic.indexOfKey(name) < 0) {
34459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPublic.add(name, Public(sourcePos, String16(), ident));
34469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
34479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Public& p = mPublic.editValueFor(name);
34489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (p.ident != ident) {
34499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sourcePos.error("Public resource %s/%s has conflicting public identifiers"
34509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    " (0x%08x vs 0x%08x).\n"
34519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    "%s:%d: Originally defined here.\n",
34529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(mName).string(), String8(name).string(), p.ident, ident,
34539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    p.sourcePos.file.string(), p.sourcePos.line);
34549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return UNKNOWN_ERROR;
34559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
34569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
34579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
34599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
34609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
346158c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackbornvoid ResourceTable::Type::canAddEntry(const String16& name)
346258c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn{
346358c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn    mCanAddEntries.add(name);
346458c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn}
346558c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn
34669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsp<ResourceTable::Entry> ResourceTable::Type::getEntry(const String16& entry,
34679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                       const SourcePos& sourcePos,
34689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                       const ResTable_config* config,
3469f878e2d80c3a0afefe3b018d232df6066379e1d5Robert Greenwalt                                                       bool doSetIndex,
347099080c7d9ad9e5ccfec70dd10e4c24468a960c45Xavier Ducrohet                                                       bool overlay,
347199080c7d9ad9e5ccfec70dd10e4c24468a960c45Xavier Ducrohet                                                       bool autoAddOverlay)
34729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
34739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int pos = -1;
34749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<ConfigList> c = mConfigs.valueFor(entry);
34759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (c == NULL) {
347699080c7d9ad9e5ccfec70dd10e4c24468a960c45Xavier Ducrohet        if (overlay && !autoAddOverlay && mCanAddEntries.indexOf(entry) < 0) {
347758c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn            sourcePos.error("Resource at %s appears in overlay but not"
347858c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                            " in the base package; use <add-resource> to add.\n",
347958c27a0a03f573791935116fa35f6a7c8bf93896Dianne Hackborn                            String8(entry).string());
3480f878e2d80c3a0afefe3b018d232df6066379e1d5Robert Greenwalt            return NULL;
3481f878e2d80c3a0afefe3b018d232df6066379e1d5Robert Greenwalt        }
34829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        c = new ConfigList(entry, sourcePos);
34839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mConfigs.add(entry, c);
34849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pos = (int)mOrderedConfigs.size();
34859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOrderedConfigs.add(c);
34869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (doSetIndex) {
34879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            c->setEntryIndex(pos);
34889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
34899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
34909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ConfigDescription cdesc;
34929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (config) cdesc = *config;
34939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Entry> e = c->getEntries().valueFor(cdesc);
34959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (e == NULL) {
34969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (config != NULL) {
34979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            NOISY(printf("New entry at %s:%d: imsi:%d/%d lang:%c%c cnt:%c%c "
349869cb87576ba163b61bb0e6477a3b7c57a9b11d40Dianne Hackborn                    "orien:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d "
34995f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio                    "sw%ddp w%ddp h%ddp dir:%d\n",
35009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      sourcePos.file.string(), sourcePos.line,
35019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->mcc, config->mnc,
35029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->language[0] ? config->language[0] : '-',
35039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->language[1] ? config->language[1] : '-',
35049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->country[0] ? config->country[0] : '-',
35059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->country[1] ? config->country[1] : '-',
35069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->orientation,
35079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->touchscreen,
35089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->density,
35099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->keyboard,
35109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->inputFlags,
35119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->navigation,
35129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      config->screenWidth,
3513ebff8f92f13513ce37bd74759eb1db63f2220590Dianne Hackborn                      config->screenHeight,
351469cb87576ba163b61bb0e6477a3b7c57a9b11d40Dianne Hackborn                      config->smallestScreenWidthDp,
3515ebff8f92f13513ce37bd74759eb1db63f2220590Dianne Hackborn                      config->screenWidthDp,
35165f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio                      config->screenHeightDp,
35175f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio                      config->layoutDirection));
35189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
35199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            NOISY(printf("New entry at %s:%d: NULL config\n",
35209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      sourcePos.file.string(), sourcePos.line));
35219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
35229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        e = new Entry(entry, sourcePos);
35239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        c->addEntry(cdesc, e);
35249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*
35259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (doSetIndex) {
35269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (pos < 0) {
35279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (pos=0; pos<(int)mOrderedConfigs.size(); pos++) {
35289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (mOrderedConfigs[pos] == c) {
35299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        break;
35309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
35319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
35329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (pos >= (int)mOrderedConfigs.size()) {
35339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sourcePos.error("Internal error: config not found in mOrderedConfigs when adding entry");
35349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return NULL;
35359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
35369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
35379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            e->setEntryIndex(pos);
35389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
35399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        */
35409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
35419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
35429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mUniqueConfigs.add(cdesc);
35439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
35449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return e;
35459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
35469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
35479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::Type::applyPublicEntryOrder()
35489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
35499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t N = mOrderedConfigs.size();
35509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Vector<sp<ConfigList> > origOrder(mOrderedConfigs);
35519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool hasError = false;
35529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
35539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t i;
35549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (i=0; i<N; i++) {
35559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOrderedConfigs.replaceAt(NULL, i);
35569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
35579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
35589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t NP = mPublic.size();
35599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //printf("Ordering %d configs from %d public defs\n", N, NP);
35609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t j;
35619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (j=0; j<NP; j++) {
35629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const String16& name = mPublic.keyAt(j);
35639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const Public& p = mPublic.valueAt(j);
35649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int32_t idx = Res_GETENTRY(p.ident);
35659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //printf("Looking for entry \"%s\"/\"%s\" (0x%08x) in %d...\n",
35669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //       String8(mName).string(), String8(name).string(), p.ident, N);
35679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bool found = false;
35689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (i=0; i<N; i++) {
35699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<ConfigList> e = origOrder.itemAt(i);
35709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //printf("#%d: \"%s\"\n", i, String8(e->getName()).string());
35719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (e->getName() == name) {
35729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (idx >= (int32_t)mOrderedConfigs.size()) {
35739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    p.sourcePos.error("Public entry identifier 0x%x entry index "
35749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            "is larger than available symbols (index %d, total symbols %d).\n",
35759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            p.ident, idx, mOrderedConfigs.size());
35769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hasError = true;
35779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (mOrderedConfigs.itemAt(idx) == NULL) {
35789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    e->setPublic(true);
35799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    e->setPublicSourcePos(p.sourcePos);
35809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mOrderedConfigs.replaceAt(e, idx);
35819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    origOrder.removeAt(i);
35829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    N--;
35839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    found = true;
35849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
35859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
35869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sp<ConfigList> oe = mOrderedConfigs.itemAt(idx);
35879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
35889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    p.sourcePos.error("Multiple entry names declared for public entry"
35899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            " identifier 0x%x in type %s (%s vs %s).\n"
35909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            "%s:%d: Originally defined here.",
35919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            idx+1, String8(mName).string(),
35929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            String8(oe->getName()).string(),
35939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            String8(name).string(),
35949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            oe->getPublicSourcePos().file.string(),
35959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            oe->getPublicSourcePos().line);
35969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hasError = true;
35979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
35989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
35999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
36009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!found) {
36029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.sourcePos.error("Public symbol %s/%s declared here is not defined.",
36039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(mName).string(), String8(name).string());
36049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            hasError = true;
36059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
36069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
36079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //printf("Copying back in %d non-public configs, have %d\n", N, origOrder.size());
36099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (N != origOrder.size()) {
36119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        printf("Internal error: remaining private symbol count mismatch\n");
36129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        N = origOrder.size();
36139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
36149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    j = 0;
36169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (i=0; i<N; i++) {
36179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<ConfigList> e = origOrder.itemAt(i);
36189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // There will always be enough room for the remaining entries.
36199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (mOrderedConfigs.itemAt(j) != NULL) {
36209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            j++;
36219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
36229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOrderedConfigs.replaceAt(e, j);
36239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        j++;
36249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
36259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return hasError ? UNKNOWN_ERROR : NO_ERROR;
36279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
36289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectResourceTable::Package::Package(const String16& name, ssize_t includedId)
36309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    : mName(name), mIncludedId(includedId),
36319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      mTypeStringsMapping(0xffffffff),
36329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      mKeyStringsMapping(0xffffffff)
36339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
36349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
36359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsp<ResourceTable::Type> ResourceTable::Package::getType(const String16& type,
36379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                        const SourcePos& sourcePos,
36389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                        bool doSetIndex)
36399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
36409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Type> t = mTypes.valueFor(type);
36419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (t == NULL) {
36429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        t = new Type(type, sourcePos);
36439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mTypes.add(type, t);
36449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOrderedTypes.add(t);
36459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (doSetIndex) {
36469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // For some reason the type's index is set to one plus the index
36479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // in the mOrderedTypes list, rather than just the index.
36489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            t->setIndex(mOrderedTypes.size());
36499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
36509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
36519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return t;
36529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
36539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::Package::setTypeStrings(const sp<AaptFile>& data)
36559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
36569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mTypeStringsData = data;
36579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = setStrings(data, &mTypeStrings, &mTypeStringsMapping);
36589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != NO_ERROR) {
36599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fprintf(stderr, "ERROR: Type string data is corrupt!\n");
36609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
36619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err;
36629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
36639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::Package::setKeyStrings(const sp<AaptFile>& data)
36659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
36669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mKeyStringsData = data;
36679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = setStrings(data, &mKeyStrings, &mKeyStringsMapping);
36689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != NO_ERROR) {
36699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fprintf(stderr, "ERROR: Key string data is corrupt!\n");
36709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
36719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err;
36729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
36739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::Package::setStrings(const sp<AaptFile>& data,
36759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                            ResStringPool* strings,
36769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                            DefaultKeyedVector<String16, uint32_t>* mappings)
36779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
36789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (data->getData() == NULL) {
36799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return UNKNOWN_ERROR;
36809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
36819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    NOISY(aout << "Setting restable string pool: "
36839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project          << HexDump(data->getData(), data->getSize()) << endl);
36849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = strings->setTo(data->getData(), data->getSize());
36869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err == NO_ERROR) {
36879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const size_t N = strings->size();
36889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (size_t i=0; i<N; i++) {
36899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            size_t len;
36909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mappings->add(String16(strings->stringAt(i, &len)), i);
36919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
36929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
36939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err;
36949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
36959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ResourceTable::Package::applyPublicTypeOrder()
36979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
36989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t N = mOrderedTypes.size();
36999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Vector<sp<Type> > origOrder(mOrderedTypes);
37009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
37019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t i;
37029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (i=0; i<N; i++) {
37039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOrderedTypes.replaceAt(NULL, i);
37049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
37059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
37069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (i=0; i<N; i++) {
37079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<Type> t = origOrder.itemAt(i);
37089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int32_t idx = t->getPublicIndex();
37099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (idx > 0) {
37109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            idx--;
37119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            while (idx >= (int32_t)mOrderedTypes.size()) {
37129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mOrderedTypes.add();
37139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
37149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mOrderedTypes.itemAt(idx) != NULL) {
37159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sp<Type> ot = mOrderedTypes.itemAt(idx);
37169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                t->getFirstPublicSourcePos().error("Multiple type names declared for public type"
37179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        " identifier 0x%x (%s vs %s).\n"
37189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        "%s:%d: Originally defined here.",
37199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        idx, String8(ot->getName()).string(),
37209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String8(t->getName()).string(),
37219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ot->getFirstPublicSourcePos().file.string(),
37229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ot->getFirstPublicSourcePos().line);
37239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return UNKNOWN_ERROR;
37249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
37259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mOrderedTypes.replaceAt(t, idx);
37269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            origOrder.removeAt(i);
37279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            i--;
37289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            N--;
37299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
37309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
37319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
37329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t j=0;
37339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (i=0; i<N; i++) {
37349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<Type> t = origOrder.itemAt(i);
37359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // There will always be enough room for the remaining types.
37369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (mOrderedTypes.itemAt(j) != NULL) {
37379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            j++;
37389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
37399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOrderedTypes.replaceAt(t, j);
37409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
37419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
37429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
37439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
37449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
37459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsp<ResourceTable::Package> ResourceTable::getPackage(const String16& package)
37469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
37479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Package> p = mPackages.valueFor(package);
37489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (p == NULL) {
3749c761d8b0086f9e92eb1e4b3a5683ae6afb84036aMÃ¥rten Kongstad        if (mIsAppPackage) {
37509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mHaveAppPackage) {
37519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                fprintf(stderr, "Adding multiple application package resources; only one is allowed.\n"
37529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                "Use -x to create extended resources.\n");
37539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return NULL;
37549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
37559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mHaveAppPackage = true;
37569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p = new Package(package, 127);
37579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
37589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p = new Package(package, mNextPackageId);
37599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
37609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //printf("*** NEW PACKAGE: \"%s\" id=%d\n",
37619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //       String8(package).string(), p->getAssignedId());
37629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPackages.add(package, p);
37639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOrderedPackages.add(p);
37649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mNextPackageId++;
37659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
37669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return p;
37679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
37689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
37699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsp<ResourceTable::Type> ResourceTable::getType(const String16& package,
37709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                               const String16& type,
37719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                               const SourcePos& sourcePos,
37729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                               bool doSetIndex)
37739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
37749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Package> p = getPackage(package);
37759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (p == NULL) {
37769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
37779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
37789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return p->getType(type, sourcePos, doSetIndex);
37799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
37809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
37819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsp<ResourceTable::Entry> ResourceTable::getEntry(const String16& package,
37829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                 const String16& type,
37839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                 const String16& name,
37849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                 const SourcePos& sourcePos,
3785f878e2d80c3a0afefe3b018d232df6066379e1d5Robert Greenwalt                                                 bool overlay,
37869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                 const ResTable_config* config,
37879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                 bool doSetIndex)
37889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
37899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Type> t = getType(package, type, sourcePos, doSetIndex);
37909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (t == NULL) {
37919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
37929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
379399080c7d9ad9e5ccfec70dd10e4c24468a960c45Xavier Ducrohet    return t->getEntry(name, sourcePos, config, doSetIndex, overlay, mBundle->getAutoAddOverlay());
37949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
37959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
37969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsp<const ResourceTable::Entry> ResourceTable::getEntry(uint32_t resID,
37979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                       const ResTable_config* config) const
37989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
37999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int pid = Res_GETPACKAGE(resID)+1;
38009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t N = mOrderedPackages.size();
38019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t i;
38029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Package> p;
38039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (i=0; i<N; i++) {
38049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<Package> check = mOrderedPackages[i];
38059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (check->getAssignedId() == pid) {
38069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p = check;
38079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
38089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
38099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
38109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
38119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (p == NULL) {
3812dd931864209eac0b4182d7a0d1ca965fcc3b8c03Marco Nelissen        fprintf(stderr, "warning: Package not found for resource #%08x\n", resID);
38139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
38149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
38159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
38169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int tid = Res_GETTYPE(resID);
38179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (tid < 0 || tid >= (int)p->getOrderedTypes().size()) {
3818dd931864209eac0b4182d7a0d1ca965fcc3b8c03Marco Nelissen        fprintf(stderr, "warning: Type not found for resource #%08x\n", resID);
38199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
38209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
38219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Type> t = p->getOrderedTypes()[tid];
38229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
38239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int eid = Res_GETENTRY(resID);
38249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (eid < 0 || eid >= (int)t->getOrderedConfigs().size()) {
3825dd931864209eac0b4182d7a0d1ca965fcc3b8c03Marco Nelissen        fprintf(stderr, "warning: Entry not found for resource #%08x\n", resID);
38269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
38279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
38289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
38299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<ConfigList> c = t->getOrderedConfigs()[eid];
38309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (c == NULL) {
3831dd931864209eac0b4182d7a0d1ca965fcc3b8c03Marco Nelissen        fprintf(stderr, "warning: Entry not found for resource #%08x\n", resID);
38329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
38339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
38349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
38359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ConfigDescription cdesc;
38369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (config) cdesc = *config;
38379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Entry> e = c->getEntries().valueFor(cdesc);
38389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (c == NULL) {
3839dd931864209eac0b4182d7a0d1ca965fcc3b8c03Marco Nelissen        fprintf(stderr, "warning: Entry configuration not found for resource #%08x\n", resID);
38409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
38419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
38429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
38439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return e;
38449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
38459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
38469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst ResourceTable::Item* ResourceTable::getItem(uint32_t resID, uint32_t attrID) const
38479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
38489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<const Entry> e = getEntry(resID);
38499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (e == NULL) {
38509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
38519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
38529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
38539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t N = e->getBag().size();
38549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (size_t i=0; i<N; i++) {
38559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const Item& it = e->getBag().valueAt(i);
38569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (it.bagKeyId == 0) {
3857dd931864209eac0b4182d7a0d1ca965fcc3b8c03Marco Nelissen            fprintf(stderr, "warning: ID not yet assigned to '%s' in bag '%s'\n",
38589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(e->getName()).string(),
38599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(e->getBag().keyAt(i)).string());
38609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
38619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (it.bagKeyId == attrID) {
38629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return &it;
38639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
38649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
38659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
38669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NULL;
38679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
38689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
38699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ResourceTable::getItemValue(
38709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t resID, uint32_t attrID, Res_value* outValue)
38719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
38729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const Item* item = getItem(resID, attrID);
38739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
38749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool res = false;
38759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (item != NULL) {
38769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (item->evaluating) {
38779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<const Entry> e = getEntry(resID);
38789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const size_t N = e->getBag().size();
38799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            size_t i;
38809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (i=0; i<N; i++) {
38819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (&e->getBag().valueAt(i) == item) {
38829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
38839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
38849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3885dd931864209eac0b4182d7a0d1ca965fcc3b8c03Marco Nelissen            fprintf(stderr, "warning: Circular reference detected in key '%s' of bag '%s'\n",
38869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(e->getName()).string(),
38879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String8(e->getBag().keyAt(i)).string());
38889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
38899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
38909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        item->evaluating = true;
38919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        res = stringToValue(outValue, NULL, item->value, false, false, item->bagKeyId);
38929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NOISY(
38939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (res) {
38949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                printf("getItemValue of #%08x[#%08x] (%s): type=#%08x, data=#%08x\n",
38959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                       resID, attrID, String8(getEntry(resID)->getName()).string(),
38969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                       outValue->dataType, outValue->data);
38979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
38989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                printf("getItemValue of #%08x[#%08x]: failed\n",
38999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                       resID, attrID);
39009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
39019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        );
39029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        item->evaluating = false;
39039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
39049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return res;
39059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3906