//
// Copyright 2006 The Android Open Source Project
//
// Build resource files from raw assets.
//

#include "ResourceTable.h"

#include "XMLNode.h"

#include <utils/ByteOrder.h>
#include <utils/ResourceTypes.h>
#include <stdarg.h>

#define NOISY(x) //x

status_t compileXmlFile(const sp<AaptAssets>& assets,
                        const sp<AaptFile>& target,
                        ResourceTable* table,
                        int options)
{
    sp<XMLNode> root = XMLNode::parse(target);
    if (root == NULL) {
        return UNKNOWN_ERROR;
    }
    
    return compileXmlFile(assets, root, target, table, options);
}

status_t compileXmlFile(const sp<AaptAssets>& assets,
                        const sp<AaptFile>& target,
                        const sp<AaptFile>& outTarget,
                        ResourceTable* table,
                        int options)
{
    sp<XMLNode> root = XMLNode::parse(target);
    if (root == NULL) {
        return UNKNOWN_ERROR;
    }
    
    return compileXmlFile(assets, root, outTarget, table, options);
}

status_t compileXmlFile(const sp<AaptAssets>& assets,
                        const sp<XMLNode>& root,
                        const sp<AaptFile>& target,
                        ResourceTable* table,
                        int options)
{
    if ((options&XML_COMPILE_STRIP_WHITESPACE) != 0) {
        root->removeWhitespace(true, NULL);
    } else  if ((options&XML_COMPILE_COMPACT_WHITESPACE) != 0) {
        root->removeWhitespace(false, NULL);
    }

    if ((options&XML_COMPILE_UTF8) != 0) {
        root->setUTF8(true);
    }

    bool hasErrors = false;
    
    if ((options&XML_COMPILE_ASSIGN_ATTRIBUTE_IDS) != 0) {
        status_t err = root->assignResourceIds(assets, table);
        if (err != NO_ERROR) {
            hasErrors = true;
        }
    }

    status_t err = root->parseValues(assets, table);
    if (err != NO_ERROR) {
        hasErrors = true;
    }

    if (hasErrors) {
        return UNKNOWN_ERROR;
    }
    
    NOISY(printf("Input XML Resource:\n"));
    NOISY(root->print());
    err = root->flatten(target,
            (options&XML_COMPILE_STRIP_COMMENTS) != 0,
            (options&XML_COMPILE_STRIP_RAW_VALUES) != 0);
    if (err != NO_ERROR) {
        return err;
    }

    NOISY(printf("Output XML Resource:\n"));
    NOISY(ResXMLTree tree;
        tree.setTo(target->getData(), target->getSize());
        printXMLBlock(&tree));

    target->setCompressionMethod(ZipEntry::kCompressDeflated);
    
    return err;
}

#undef NOISY
#define NOISY(x) //x

struct flag_entry
{
    const char16_t* name;
    size_t nameLen;
    uint32_t value;
    const char* description;
};

static const char16_t referenceArray[] =
    { 'r', 'e', 'f', 'e', 'r', 'e', 'n', 'c', 'e' };
static const char16_t stringArray[] =
    { 's', 't', 'r', 'i', 'n', 'g' };
static const char16_t integerArray[] =
    { 'i', 'n', 't', 'e', 'g', 'e', 'r' };
static const char16_t booleanArray[] =
    { 'b', 'o', 'o', 'l', 'e', 'a', 'n' };
static const char16_t colorArray[] =
    { 'c', 'o', 'l', 'o', 'r' };
static const char16_t floatArray[] =
    { 'f', 'l', 'o', 'a', 't' };
static const char16_t dimensionArray[] =
    { 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n' };
static const char16_t fractionArray[] =
    { 'f', 'r', 'a', 'c', 't', 'i', 'o', 'n' };
static const char16_t enumArray[] =
    { 'e', 'n', 'u', 'm' };
static const char16_t flagsArray[] =
    { 'f', 'l', 'a', 'g', 's' };

static const flag_entry gFormatFlags[] = {
    { referenceArray, sizeof(referenceArray)/2, ResTable_map::TYPE_REFERENCE,
      "a reference to another resource, in the form \"<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>\"\n"
      "or to a theme attribute in the form \"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>\"."},
    { stringArray, sizeof(stringArray)/2, ResTable_map::TYPE_STRING,
      "a string value, using '\\\\;' to escape characters such as '\\\\n' or '\\\\uxxxx' for a unicode character." },
    { integerArray, sizeof(integerArray)/2, ResTable_map::TYPE_INTEGER,
      "an integer value, such as \"<code>100</code>\"." },
    { booleanArray, sizeof(booleanArray)/2, ResTable_map::TYPE_BOOLEAN,
      "a boolean value, either \"<code>true</code>\" or \"<code>false</code>\"." },
    { colorArray, sizeof(colorArray)/2, ResTable_map::TYPE_COLOR,
      "a color value, in the form of \"<code>#<i>rgb</i></code>\", \"<code>#<i>argb</i></code>\",\n"
      "\"<code>#<i>rrggbb</i></code>\", or \"<code>#<i>aarrggbb</i></code>\"." },
    { floatArray, sizeof(floatArray)/2, ResTable_map::TYPE_FLOAT,
      "a floating point value, such as \"<code>1.2</code>\"."},
    { dimensionArray, sizeof(dimensionArray)/2, ResTable_map::TYPE_DIMENSION,
      "a dimension value, which is a floating point number appended with a unit such as \"<code>14.5sp</code>\".\n"
      "Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size),\n"
      "in (inches), mm (millimeters)." },
    { fractionArray, sizeof(fractionArray)/2, ResTable_map::TYPE_FRACTION,
      "a fractional value, which is a floating point number appended with either % or %p, such as \"<code>14.5%</code>\".\n"
      "The % suffix always means a percentage of the base size; the optional %p suffix provides a size relative to\n"
      "some parent container." },
    { enumArray, sizeof(enumArray)/2, ResTable_map::TYPE_ENUM, NULL },
    { flagsArray, sizeof(flagsArray)/2, ResTable_map::TYPE_FLAGS, NULL },
    { NULL, 0, 0, NULL }
};

static const char16_t suggestedArray[] = { 's', 'u', 'g', 'g', 'e', 's', 't', 'e', 'd' };

static const flag_entry l10nRequiredFlags[] = {
    { suggestedArray, sizeof(suggestedArray)/2, ResTable_map::L10N_SUGGESTED, NULL },
    { NULL, 0, 0, NULL }
};

static const char16_t nulStr[] = { 0 };

static uint32_t parse_flags(const char16_t* str, size_t len,
                             const flag_entry* flags, bool* outError = NULL)
{
    while (len > 0 && isspace(*str)) {
        str++;
        len--;
    }
    while (len > 0 && isspace(str[len-1])) {
        len--;
    }

    const char16_t* const end = str + len;
    uint32_t value = 0;

    while (str < end) {
        const char16_t* div = str;
        while (div < end && *div != '|') {
            div++;
        }

        const flag_entry* cur = flags;
        while (cur->name) {
            if (strzcmp16(cur->name, cur->nameLen, str, div-str) == 0) {
                value |= cur->value;
                break;
            }
            cur++;
        }

        if (!cur->name) {
            if (outError) *outError = true;
            return 0;
        }

        str = div < end ? div+1 : div;
    }

    if (outError) *outError = false;
    return value;
}

static String16 mayOrMust(int type, int flags)
{
    if ((type&(~flags)) == 0) {
        return String16("<p>Must");
    }
    
    return String16("<p>May");
}

static void appendTypeInfo(ResourceTable* outTable, const String16& pkg,
        const String16& typeName, const String16& ident, int type,
        const flag_entry* flags)
{
    bool hadType = false;
    while (flags->name) {
        if ((type&flags->value) != 0 && flags->description != NULL) {
            String16 fullMsg(mayOrMust(type, flags->value));
            fullMsg.append(String16(" be "));
            fullMsg.append(String16(flags->description));
            outTable->appendTypeComment(pkg, typeName, ident, fullMsg);
            hadType = true;
        }
        flags++;
    }
    if (hadType && (type&ResTable_map::TYPE_REFERENCE) == 0) {
        outTable->appendTypeComment(pkg, typeName, ident,
                String16("<p>This may also be a reference to a resource (in the form\n"
                         "\"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>\") or\n"
                         "theme attribute (in the form\n"
                         "\"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>\")\n"
                         "containing a value of this type."));
    }
}

struct PendingAttribute
{
    const String16 myPackage;
    const SourcePos sourcePos;
    const bool appendComment;
    int32_t type;
    String16 ident;
    String16 comment;
    bool hasErrors;
    bool added;
    
    PendingAttribute(String16 _package, const sp<AaptFile>& in,
            ResXMLTree& block, bool _appendComment)
        : myPackage(_package)
        , sourcePos(in->getPrintableSource(), block.getLineNumber())
        , appendComment(_appendComment)
        , type(ResTable_map::TYPE_ANY)
        , hasErrors(false)
        , added(false)
    {
    }
    
    status_t createIfNeeded(ResourceTable* outTable)
    {
        if (added || hasErrors) {
            return NO_ERROR;
        }
        added = true;

        String16 attr16("attr");
        
        if (outTable->hasBagOrEntry(myPackage, attr16, ident)) {
            sourcePos.error("Attribute \"%s\" has already been defined\n",
                    String8(ident).string());
            hasErrors = true;
            return UNKNOWN_ERROR;
        }
        
        char numberStr[16];
        sprintf(numberStr, "%d", type);
        status_t err = outTable->addBag(sourcePos, myPackage,
                attr16, ident, String16(""),
                String16("^type"),
                String16(numberStr), NULL, NULL);
        if (err != NO_ERROR) {
            hasErrors = true;
            return err;
        }
        outTable->appendComment(myPackage, attr16, ident, comment, appendComment);
        //printf("Attribute %s comment: %s\n", String8(ident).string(),
        //     String8(comment).string());
        return err;
    }
};

static status_t compileAttribute(const sp<AaptFile>& in,
                                 ResXMLTree& block,
                                 const String16& myPackage,
                                 ResourceTable* outTable,
                                 String16* outIdent = NULL,
                                 bool inStyleable = false)
{
    PendingAttribute attr(myPackage, in, block, inStyleable);
    
    const String16 attr16("attr");
    const String16 id16("id");

    // Attribute type constants.
    const String16 enum16("enum");
    const String16 flag16("flag");

    ResXMLTree::event_code_t code;
    size_t len;
    status_t err;
    
    ssize_t identIdx = block.indexOfAttribute(NULL, "name");
    if (identIdx >= 0) {
        attr.ident = String16(block.getAttributeStringValue(identIdx, &len));
        if (outIdent) {
            *outIdent = attr.ident;
        }
    } else {
        attr.sourcePos.error("A 'name' attribute is required for <attr>\n");
        attr.hasErrors = true;
    }

    attr.comment = String16(
            block.getComment(&len) ? block.getComment(&len) : nulStr);

    ssize_t typeIdx = block.indexOfAttribute(NULL, "format");
    if (typeIdx >= 0) {
        String16 typeStr = String16(block.getAttributeStringValue(typeIdx, &len));
        attr.type = parse_flags(typeStr.string(), typeStr.size(), gFormatFlags);
        if (attr.type == 0) {
            attr.sourcePos.error("Tag <attr> 'format' attribute value \"%s\" not valid\n",
                    String8(typeStr).string());
            attr.hasErrors = true;
        }
        attr.createIfNeeded(outTable);
    } else if (!inStyleable) {
        // Attribute definitions outside of styleables always define the
        // attribute as a generic value.
        attr.createIfNeeded(outTable);
    }

    //printf("Attribute %s: type=0x%08x\n", String8(attr.ident).string(), attr.type);

    ssize_t minIdx = block.indexOfAttribute(NULL, "min");
    if (minIdx >= 0) {
        String16 val = String16(block.getAttributeStringValue(minIdx, &len));
        if (!ResTable::stringToInt(val.string(), val.size(), NULL)) {
            attr.sourcePos.error("Tag <attr> 'min' attribute must be a number, not \"%s\"\n",
                    String8(val).string());
            attr.hasErrors = true;
        }
        attr.createIfNeeded(outTable);
        if (!attr.hasErrors) {
            err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident,
                    String16(""), String16("^min"), String16(val), NULL, NULL);
            if (err != NO_ERROR) {
                attr.hasErrors = true;
            }
        }
    }

    ssize_t maxIdx = block.indexOfAttribute(NULL, "max");
    if (maxIdx >= 0) {
        String16 val = String16(block.getAttributeStringValue(maxIdx, &len));
        if (!ResTable::stringToInt(val.string(), val.size(), NULL)) {
            attr.sourcePos.error("Tag <attr> 'max' attribute must be a number, not \"%s\"\n",
                    String8(val).string());
            attr.hasErrors = true;
        }
        attr.createIfNeeded(outTable);
        if (!attr.hasErrors) {
            err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident,
                    String16(""), String16("^max"), String16(val), NULL, NULL);
            attr.hasErrors = true;
        }
    }

    if ((minIdx >= 0 || maxIdx >= 0) && (attr.type&ResTable_map::TYPE_INTEGER) == 0) {
        attr.sourcePos.error("Tag <attr> must have format=integer attribute if using max or min\n");
        attr.hasErrors = true;
    }

    ssize_t l10nIdx = block.indexOfAttribute(NULL, "localization");
    if (l10nIdx >= 0) {
        const uint16_t* str = block.getAttributeStringValue(l10nIdx, &len);
        bool error;
        uint32_t l10n_required = parse_flags(str, len, l10nRequiredFlags, &error);
        if (error) {
            attr.sourcePos.error("Tag <attr> 'localization' attribute value \"%s\" not valid\n",
                    String8(str).string());
            attr.hasErrors = true;
        }
        attr.createIfNeeded(outTable);
        if (!attr.hasErrors) {
            char buf[11];
            sprintf(buf, "%d", l10n_required);
            err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident,
                    String16(""), String16("^l10n"), String16(buf), NULL, NULL);
            if (err != NO_ERROR) {
                attr.hasErrors = true;
            }
        }
    }

    String16 enumOrFlagsComment;
    
    while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
        if (code == ResXMLTree::START_TAG) {
            uint32_t localType = 0;
            if (strcmp16(block.getElementName(&len), enum16.string()) == 0) {
                localType = ResTable_map::TYPE_ENUM;
            } else if (strcmp16(block.getElementName(&len), flag16.string()) == 0) {
                localType = ResTable_map::TYPE_FLAGS;
            } else {
                SourcePos(in->getPrintableSource(), block.getLineNumber())
                        .error("Tag <%s> can not appear inside <attr>, only <enum> or <flag>\n",
                        String8(block.getElementName(&len)).string());
                return UNKNOWN_ERROR;
            }

            attr.createIfNeeded(outTable);
            
            if (attr.type == ResTable_map::TYPE_ANY) {
                // No type was explicitly stated, so supplying enum tags
                // implicitly creates an enum or flag.
                attr.type = 0;
            }

            if ((attr.type&(ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS)) == 0) {
                // Wasn't originally specified as an enum, so update its type.
                attr.type |= localType;
                if (!attr.hasErrors) {
                    char numberStr[16];
                    sprintf(numberStr, "%d", attr.type);
                    err = outTable->addBag(SourcePos(in->getPrintableSource(), block.getLineNumber()),
                            myPackage, attr16, attr.ident, String16(""),
                            String16("^type"), String16(numberStr), NULL, NULL, true);
                    if (err != NO_ERROR) {
                        attr.hasErrors = true;
                    }
                }
            } else if ((uint32_t)(attr.type&(ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS)) != localType) {
                if (localType == ResTable_map::TYPE_ENUM) {
                    SourcePos(in->getPrintableSource(), block.getLineNumber())
                            .error("<enum> attribute can not be used inside a flags format\n");
                    attr.hasErrors = true;
                } else {
                    SourcePos(in->getPrintableSource(), block.getLineNumber())
                            .error("<flag> attribute can not be used inside a enum format\n");
                    attr.hasErrors = true;
                }
            }

            String16 itemIdent;
            ssize_t itemIdentIdx = block.indexOfAttribute(NULL, "name");
            if (itemIdentIdx >= 0) {
                itemIdent = String16(block.getAttributeStringValue(itemIdentIdx, &len));
            } else {
                SourcePos(in->getPrintableSource(), block.getLineNumber())
                        .error("A 'name' attribute is required for <enum> or <flag>\n");
                attr.hasErrors = true;
            }

            String16 value;
            ssize_t valueIdx = block.indexOfAttribute(NULL, "value");
            if (valueIdx >= 0) {
                value = String16(block.getAttributeStringValue(valueIdx, &len));
            } else {
                SourcePos(in->getPrintableSource(), block.getLineNumber())
                        .error("A 'value' attribute is required for <enum> or <flag>\n");
                attr.hasErrors = true;
            }
            if (!attr.hasErrors && !ResTable::stringToInt(value.string(), value.size(), NULL)) {
                SourcePos(in->getPrintableSource(), block.getLineNumber())
                        .error("Tag <enum> or <flag> 'value' attribute must be a number,"
                        " not \"%s\"\n",
                        String8(value).string());
                attr.hasErrors = true;
            }

            // Make sure an id is defined for this enum/flag identifier...
            if (!attr.hasErrors && !outTable->hasBagOrEntry(itemIdent, &id16, &myPackage)) {
                err = outTable->startBag(SourcePos(in->getPrintableSource(), block.getLineNumber()),
                                         myPackage, id16, itemIdent, String16(), NULL);
                if (err != NO_ERROR) {
                    attr.hasErrors = true;
                }
            }

            if (!attr.hasErrors) {
                if (enumOrFlagsComment.size() == 0) {
                    enumOrFlagsComment.append(mayOrMust(attr.type,
                            ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS));
                    enumOrFlagsComment.append((attr.type&ResTable_map::TYPE_ENUM)
                                       ? String16(" be one of the following constant values.")
                                       : String16(" be one or more (separated by '|') of the following constant values."));
                    enumOrFlagsComment.append(String16("</p>\n<table>\n"
                                                "<colgroup align=\"left\" />\n"
                                                "<colgroup align=\"left\" />\n"
                                                "<colgroup align=\"left\" />\n"
                                                "<tr><th>Constant</th><th>Value</th><th>Description</th></tr>"));
                }
                
                enumOrFlagsComment.append(String16("\n<tr><td><code>"));
                enumOrFlagsComment.append(itemIdent);
                enumOrFlagsComment.append(String16("</code></td><td>"));
                enumOrFlagsComment.append(value);
                enumOrFlagsComment.append(String16("</td><td>"));
                if (block.getComment(&len)) {
                    enumOrFlagsComment.append(String16(block.getComment(&len)));
                }
                enumOrFlagsComment.append(String16("</td></tr>"));
                
                err = outTable->addBag(SourcePos(in->getPrintableSource(), block.getLineNumber()),
                                       myPackage,
                                       attr16, attr.ident, String16(""),
                                       itemIdent, value, NULL, NULL, false, true);
                if (err != NO_ERROR) {
                    attr.hasErrors = true;
                }
            }
        } else if (code == ResXMLTree::END_TAG) {
            if (strcmp16(block.getElementName(&len), attr16.string()) == 0) {
                break;
            }
            if ((attr.type&ResTable_map::TYPE_ENUM) != 0) {
                if (strcmp16(block.getElementName(&len), enum16.string()) != 0) {
                    SourcePos(in->getPrintableSource(), block.getLineNumber())
                            .error("Found tag </%s> where </enum> is expected\n",
                            String8(block.getElementName(&len)).string());
                    return UNKNOWN_ERROR;
                }
            } else {
                if (strcmp16(block.getElementName(&len), flag16.string()) != 0) {
                    SourcePos(in->getPrintableSource(), block.getLineNumber())
                            .error("Found tag </%s> where </flag> is expected\n",
                            String8(block.getElementName(&len)).string());
                    return UNKNOWN_ERROR;
                }
            }
        }
    }
    
    if (!attr.hasErrors && attr.added) {
        appendTypeInfo(outTable, myPackage, attr16, attr.ident, attr.type, gFormatFlags);
    }
    
    if (!attr.hasErrors && enumOrFlagsComment.size() > 0) {
        enumOrFlagsComment.append(String16("\n</table>"));
        outTable->appendTypeComment(myPackage, attr16, attr.ident, enumOrFlagsComment);
    }


    return NO_ERROR;
}

bool localeIsDefined(const ResTable_config& config)
{
    return config.locale == 0;
}

status_t parseAndAddBag(Bundle* bundle,
                        const sp<AaptFile>& in,
                        ResXMLTree* block,
                        const ResTable_config& config,
                        const String16& myPackage,
                        const String16& curType,
                        const String16& ident,
                        const String16& parentIdent,
                        const String16& itemIdent,
                        int32_t curFormat,
                        bool isFormatted,
                        const String16& product,
                        bool pseudolocalize,
                        const bool overwrite,
                        ResourceTable* outTable)
{
    status_t err;
    const String16 item16("item");
    
    String16 str;
    Vector<StringPool::entry_style_span> spans;
    err = parseStyledString(bundle, in->getPrintableSource().string(),
                            block, item16, &str, &spans, isFormatted,
                            pseudolocalize);
    if (err != NO_ERROR) {
        return err;
    }
    
    NOISY(printf("Adding resource bag entry l=%c%c c=%c%c orien=%d d=%d "
                 " pid=%s, bag=%s, id=%s: %s\n",
                 config.language[0], config.language[1],
                 config.country[0], config.country[1],
                 config.orientation, config.density,
                 String8(parentIdent).string(),
                 String8(ident).string(),
                 String8(itemIdent).string(),
                 String8(str).string()));

    err = outTable->addBag(SourcePos(in->getPrintableSource(), block->getLineNumber()),
                           myPackage, curType, ident, parentIdent, itemIdent, str,
                           &spans, &config, overwrite, false, curFormat);
    return err;
}

/*
 * Returns true if needle is one of the elements in the comma-separated list
 * haystack, false otherwise.
 */
bool isInProductList(const String16& needle, const String16& haystack) {
    const char16_t *needle2 = needle.string();
    const char16_t *haystack2 = haystack.string();
    size_t needlesize = needle.size();

    while (*haystack2 != '\0') {
        if (strncmp16(haystack2, needle2, needlesize) == 0) {
            if (haystack2[needlesize] == '\0' || haystack2[needlesize] == ',') {
                return true;
            }
        }

        while (*haystack2 != '\0' && *haystack2 != ',') {
            haystack2++;
        }
        if (*haystack2 == ',') {
            haystack2++;
        }
    }

    return false;
}

status_t parseAndAddEntry(Bundle* bundle,
                        const sp<AaptFile>& in,
                        ResXMLTree* block,
                        const ResTable_config& config,
                        const String16& myPackage,
                        const String16& curType,
                        const String16& ident,
                        const String16& curTag,
                        bool curIsStyled,
                        int32_t curFormat,
                        bool isFormatted,
                        const String16& product,
                        bool pseudolocalize,
                        const bool overwrite,
                        ResourceTable* outTable)
{
    status_t err;

    String16 str;
    Vector<StringPool::entry_style_span> spans;
    err = parseStyledString(bundle, in->getPrintableSource().string(), block,
                            curTag, &str, curIsStyled ? &spans : NULL,
                            isFormatted, pseudolocalize);

    if (err < NO_ERROR) { 
        return err;
    }

    /*
     * If a product type was specified on the command line
     * and also in the string, and the two are not the same,
     * return without adding the string.
     */

    const char *bundleProduct = bundle->getProduct();
    if (bundleProduct == NULL) {
        bundleProduct = "";
    }

    if (product.size() != 0) {
        /*
         * If the command-line-specified product is empty, only "default"
         * matches.  Other variants are skipped.  This is so generation
         * of the R.java file when the product is not known is predictable.
         */

        if (bundleProduct[0] == '\0') {
            if (strcmp16(String16("default").string(), product.string()) != 0) {
                return NO_ERROR;
            }
        } else {
            /*
             * The command-line product is not empty.
             * If the product for this string is on the command-line list,
             * it matches.  "default" also matches, but only if nothing
             * else has matched already.
             */

            if (isInProductList(product, String16(bundleProduct))) {
                ;
            } else if (strcmp16(String16("default").string(), product.string()) == 0 &&
                       !outTable->hasBagOrEntry(myPackage, curType, ident)) {
                ;
            } else {
                return NO_ERROR;
            }
        }
    }

    NOISY(printf("Adding resource entry l=%c%c c=%c%c orien=%d d=%d id=%s: %s\n",
                 config.language[0], config.language[1],
                 config.country[0], config.country[1],
                 config.orientation, config.density,
                 String8(ident).string(), String8(str).string()));

    err = outTable->addEntry(SourcePos(in->getPrintableSource(), block->getLineNumber()),
                             myPackage, curType, ident, str, &spans, &config,
                             false, curFormat, overwrite);

    return err;
}

status_t compileResourceFile(Bundle* bundle,
                             const sp<AaptAssets>& assets,
                             const sp<AaptFile>& in,
                             const ResTable_config& defParams,
                             const bool overwrite,
                             ResourceTable* outTable)
{
    ResXMLTree block;
    status_t err = parseXMLResource(in, &block, false, true);
    if (err != NO_ERROR) {
        return err;
    }

    // Top-level tag.
    const String16 resources16("resources");

    // Identifier declaration tags.
    const String16 declare_styleable16("declare-styleable");
    const String16 attr16("attr");

    // Data creation organizational tags.
    const String16 string16("string");
    const String16 drawable16("drawable");
    const String16 color16("color");
    const String16 bool16("bool");
    const String16 integer16("integer");
    const String16 dimen16("dimen");
    const String16 fraction16("fraction");
    const String16 style16("style");
    const String16 plurals16("plurals");
    const String16 array16("array");
    const String16 string_array16("string-array");
    const String16 integer_array16("integer-array");
    const String16 public16("public");
    const String16 public_padding16("public-padding");
    const String16 private_symbols16("private-symbols");
    const String16 add_resource16("add-resource");
    const String16 skip16("skip");
    const String16 eat_comment16("eat-comment");

    // Data creation tags.
    const String16 bag16("bag");
    const String16 item16("item");

    // Attribute type constants.
    const String16 enum16("enum");

    // plural values
    const String16 other16("other");
    const String16 quantityOther16("^other");
    const String16 zero16("zero");
    const String16 quantityZero16("^zero");
    const String16 one16("one");
    const String16 quantityOne16("^one");
    const String16 two16("two");
    const String16 quantityTwo16("^two");
    const String16 few16("few");
    const String16 quantityFew16("^few");
    const String16 many16("many");
    const String16 quantityMany16("^many");

    // useful attribute names and special values
    const String16 name16("name");
    const String16 translatable16("translatable");
    const String16 formatted16("formatted");
    const String16 false16("false");

    const String16 myPackage(assets->getPackage());

    bool hasErrors = false;

    bool fileIsTranslatable = true;
    if (strstr(in->getPrintableSource().string(), "donottranslate") != NULL) {
        fileIsTranslatable = false;
    }

    DefaultKeyedVector<String16, uint32_t> nextPublicId(0);

    ResXMLTree::event_code_t code;
    do {
        code = block.next();
    } while (code == ResXMLTree::START_NAMESPACE);

    size_t len;
    if (code != ResXMLTree::START_TAG) {
        SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
                "No start tag found\n");
        return UNKNOWN_ERROR;
    }
    if (strcmp16(block.getElementName(&len), resources16.string()) != 0) {
        SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
                "Invalid start tag %s\n", String8(block.getElementName(&len)).string());
        return UNKNOWN_ERROR;
    }

    ResTable_config curParams(defParams);

    ResTable_config pseudoParams(curParams);
        pseudoParams.language[0] = 'z';
        pseudoParams.language[1] = 'z';
        pseudoParams.country[0] = 'Z';
        pseudoParams.country[1] = 'Z';

    while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
        if (code == ResXMLTree::START_TAG) {
            const String16* curTag = NULL;
            String16 curType;
            int32_t curFormat = ResTable_map::TYPE_ANY;
            bool curIsBag = false;
            bool curIsBagReplaceOnOverwrite = false;
            bool curIsStyled = false;
            bool curIsPseudolocalizable = false;
            bool curIsFormatted = fileIsTranslatable;
            bool localHasErrors = false;

            if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {
                while ((code=block.next()) != ResXMLTree::END_DOCUMENT
                        && code != ResXMLTree::BAD_DOCUMENT) {
                    if (code == ResXMLTree::END_TAG) {
                        if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {
                            break;
                        }
                    }
                }
                continue;

            } else if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) {
                while ((code=block.next()) != ResXMLTree::END_DOCUMENT
                        && code != ResXMLTree::BAD_DOCUMENT) {
                    if (code == ResXMLTree::END_TAG) {
                        if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) {
                            break;
                        }
                    }
                }
                continue;

            } else if (strcmp16(block.getElementName(&len), public16.string()) == 0) {
                SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());
            
                String16 type;
                ssize_t typeIdx = block.indexOfAttribute(NULL, "type");
                if (typeIdx < 0) {
                    srcPos.error("A 'type' attribute is required for <public>\n");
                    hasErrors = localHasErrors = true;
                }
                type = String16(block.getAttributeStringValue(typeIdx, &len));

                String16 name;
                ssize_t nameIdx = block.indexOfAttribute(NULL, "name");
                if (nameIdx < 0) {
                    srcPos.error("A 'name' attribute is required for <public>\n");
                    hasErrors = localHasErrors = true;
                }
                name = String16(block.getAttributeStringValue(nameIdx, &len));

                uint32_t ident = 0;
                ssize_t identIdx = block.indexOfAttribute(NULL, "id");
                if (identIdx >= 0) {
                    const char16_t* identStr = block.getAttributeStringValue(identIdx, &len);
                    Res_value identValue;
                    if (!ResTable::stringToInt(identStr, len, &identValue)) {
                        srcPos.error("Given 'id' attribute is not an integer: %s\n",
                                String8(block.getAttributeStringValue(identIdx, &len)).string());
                        hasErrors = localHasErrors = true;
                    } else {
                        ident = identValue.data;
                        nextPublicId.replaceValueFor(type, ident+1);
                    }
                } else if (nextPublicId.indexOfKey(type) < 0) {
                    srcPos.error("No 'id' attribute supplied <public>,"
                            " and no previous id defined in this file.\n");
                    hasErrors = localHasErrors = true;
                } else if (!localHasErrors) {
                    ident = nextPublicId.valueFor(type);
                    nextPublicId.replaceValueFor(type, ident+1);
                }

                if (!localHasErrors) {
                    err = outTable->addPublic(srcPos, myPackage, type, name, ident);
                    if (err < NO_ERROR) {
                        hasErrors = localHasErrors = true;
                    }
                }
                if (!localHasErrors) {
                    sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R"));
                    if (symbols != NULL) {
                        symbols = symbols->addNestedSymbol(String8(type), srcPos);
                    }
                    if (symbols != NULL) {
                        symbols->makeSymbolPublic(String8(name), srcPos);
                        String16 comment(
                            block.getComment(&len) ? block.getComment(&len) : nulStr);
                        symbols->appendComment(String8(name), comment, srcPos);
                    } else {
                        srcPos.error("Unable to create symbols!\n");
                        hasErrors = localHasErrors = true;
                    }
                }

                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
                    if (code == ResXMLTree::END_TAG) {
                        if (strcmp16(block.getElementName(&len), public16.string()) == 0) {
                            break;
                        }
                    }
                }
                continue;

            } else if (strcmp16(block.getElementName(&len), public_padding16.string()) == 0) {
                SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());
            
                String16 type;
                ssize_t typeIdx = block.indexOfAttribute(NULL, "type");
                if (typeIdx < 0) {
                    srcPos.error("A 'type' attribute is required for <public-padding>\n");
                    hasErrors = localHasErrors = true;
                }
                type = String16(block.getAttributeStringValue(typeIdx, &len));

                String16 name;
                ssize_t nameIdx = block.indexOfAttribute(NULL, "name");
                if (nameIdx < 0) {
                    srcPos.error("A 'name' attribute is required for <public-padding>\n");
                    hasErrors = localHasErrors = true;
                }
                name = String16(block.getAttributeStringValue(nameIdx, &len));

                uint32_t start = 0;
                ssize_t startIdx = block.indexOfAttribute(NULL, "start");
                if (startIdx >= 0) {
                    const char16_t* startStr = block.getAttributeStringValue(startIdx, &len);
                    Res_value startValue;
                    if (!ResTable::stringToInt(startStr, len, &startValue)) {
                        srcPos.error("Given 'start' attribute is not an integer: %s\n",
                                String8(block.getAttributeStringValue(startIdx, &len)).string());
                        hasErrors = localHasErrors = true;
                    } else {
                        start = startValue.data;
                    }
                } else if (nextPublicId.indexOfKey(type) < 0) {
                    srcPos.error("No 'start' attribute supplied <public-padding>,"
                            " and no previous id defined in this file.\n");
                    hasErrors = localHasErrors = true;
                } else if (!localHasErrors) {
                    start = nextPublicId.valueFor(type);
                }

                uint32_t end = 0;
                ssize_t endIdx = block.indexOfAttribute(NULL, "end");
                if (endIdx >= 0) {
                    const char16_t* endStr = block.getAttributeStringValue(endIdx, &len);
                    Res_value endValue;
                    if (!ResTable::stringToInt(endStr, len, &endValue)) {
                        srcPos.error("Given 'end' attribute is not an integer: %s\n",
                                String8(block.getAttributeStringValue(endIdx, &len)).string());
                        hasErrors = localHasErrors = true;
                    } else {
                        end = endValue.data;
                    }
                } else {
                    srcPos.error("No 'end' attribute supplied <public-padding>\n");
                    hasErrors = localHasErrors = true;
                }

                if (end >= start) {
                    nextPublicId.replaceValueFor(type, end+1);
                } else {
                    srcPos.error("Padding start '%ul' is after end '%ul'\n",
                            start, end);
                    hasErrors = localHasErrors = true;
                }
                
                String16 comment(
                    block.getComment(&len) ? block.getComment(&len) : nulStr);
                for (uint32_t curIdent=start; curIdent<=end; curIdent++) {
                    if (localHasErrors) {
                        break;
                    }
                    String16 curName(name);
                    char buf[64];
                    sprintf(buf, "%d", (int)(end-curIdent+1));
                    curName.append(String16(buf));
                    
                    err = outTable->addEntry(srcPos, myPackage, type, curName,
                                             String16("padding"), NULL, &curParams, false,
                                             ResTable_map::TYPE_STRING, overwrite);
                    if (err < NO_ERROR) {
                        hasErrors = localHasErrors = true;
                        break;
                    }
                    err = outTable->addPublic(srcPos, myPackage, type,
                            curName, curIdent);
                    if (err < NO_ERROR) {
                        hasErrors = localHasErrors = true;
                        break;
                    }
                    sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R"));
                    if (symbols != NULL) {
                        symbols = symbols->addNestedSymbol(String8(type), srcPos);
                    }
                    if (symbols != NULL) {
                        symbols->makeSymbolPublic(String8(curName), srcPos);
                        symbols->appendComment(String8(curName), comment, srcPos);
                    } else {
                        srcPos.error("Unable to create symbols!\n");
                        hasErrors = localHasErrors = true;
                    }
                }

                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
                    if (code == ResXMLTree::END_TAG) {
                        if (strcmp16(block.getElementName(&len), public_padding16.string()) == 0) {
                            break;
                        }
                    }
                }
                continue;

            } else if (strcmp16(block.getElementName(&len), private_symbols16.string()) == 0) {
                String16 pkg;
                ssize_t pkgIdx = block.indexOfAttribute(NULL, "package");
                if (pkgIdx < 0) {
                    SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
                            "A 'package' attribute is required for <private-symbols>\n");
                    hasErrors = localHasErrors = true;
                }
                pkg = String16(block.getAttributeStringValue(pkgIdx, &len));
                if (!localHasErrors) {
                    assets->setSymbolsPrivatePackage(String8(pkg));
                }

                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
                    if (code == ResXMLTree::END_TAG) {
                        if (strcmp16(block.getElementName(&len), private_symbols16.string()) == 0) {
                            break;
                        }
                    }
                }
                continue;

            } else if (strcmp16(block.getElementName(&len), add_resource16.string()) == 0) {
                SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());
            
                String16 typeName;
                ssize_t typeIdx = block.indexOfAttribute(NULL, "type");
                if (typeIdx < 0) {
                    srcPos.error("A 'type' attribute is required for <add-resource>\n");
                    hasErrors = localHasErrors = true;
                }
                typeName = String16(block.getAttributeStringValue(typeIdx, &len));

                String16 name;
                ssize_t nameIdx = block.indexOfAttribute(NULL, "name");
                if (nameIdx < 0) {
                    srcPos.error("A 'name' attribute is required for <add-resource>\n");
                    hasErrors = localHasErrors = true;
                }
                name = String16(block.getAttributeStringValue(nameIdx, &len));

                outTable->canAddEntry(srcPos, myPackage, typeName, name);

                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
                    if (code == ResXMLTree::END_TAG) {
                        if (strcmp16(block.getElementName(&len), add_resource16.string()) == 0) {
                            break;
                        }
                    }
                }
                continue;
                
            } else if (strcmp16(block.getElementName(&len), declare_styleable16.string()) == 0) {
                SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());
                                
                String16 ident;
                ssize_t identIdx = block.indexOfAttribute(NULL, "name");
                if (identIdx < 0) {
                    srcPos.error("A 'name' attribute is required for <declare-styleable>\n");
                    hasErrors = localHasErrors = true;
                }
                ident = String16(block.getAttributeStringValue(identIdx, &len));

                sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R"));
                if (!localHasErrors) {
                    if (symbols != NULL) {
                        symbols = symbols->addNestedSymbol(String8("styleable"), srcPos);
                    }
                    sp<AaptSymbols> styleSymbols = symbols;
                    if (symbols != NULL) {
                        symbols = symbols->addNestedSymbol(String8(ident), srcPos);
                    }
                    if (symbols == NULL) {
                        srcPos.error("Unable to create symbols!\n");
                        return UNKNOWN_ERROR;
                    }
                    
                    String16 comment(
                        block.getComment(&len) ? block.getComment(&len) : nulStr);
                    styleSymbols->appendComment(String8(ident), comment, srcPos);
                } else {
                    symbols = NULL;
                }

                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
                    if (code == ResXMLTree::START_TAG) {
                        if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {
                            while ((code=block.next()) != ResXMLTree::END_DOCUMENT
                                   && code != ResXMLTree::BAD_DOCUMENT) {
                                if (code == ResXMLTree::END_TAG) {
                                    if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {
                                        break;
                                    }
                                }
                            }
                            continue;
                        } else if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) {
                            while ((code=block.next()) != ResXMLTree::END_DOCUMENT
                                   && code != ResXMLTree::BAD_DOCUMENT) {
                                if (code == ResXMLTree::END_TAG) {
                                    if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) {
                                        break;
                                    }
                                }
                            }
                            continue;
                        } else if (strcmp16(block.getElementName(&len), attr16.string()) != 0) {
                            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
                                    "Tag <%s> can not appear inside <declare-styleable>, only <attr>\n",
                                    String8(block.getElementName(&len)).string());
                            return UNKNOWN_ERROR;
                        }

                        String16 comment(
                            block.getComment(&len) ? block.getComment(&len) : nulStr);
                        String16 itemIdent;
                        err = compileAttribute(in, block, myPackage, outTable, &itemIdent, true);
                        if (err != NO_ERROR) {
                            hasErrors = localHasErrors = true;
                        }

                        if (symbols != NULL) {
                            SourcePos srcPos(String8(in->getPrintableSource()), block.getLineNumber());
                            symbols->addSymbol(String8(itemIdent), 0, srcPos);
                            symbols->appendComment(String8(itemIdent), comment, srcPos);
                            //printf("Attribute %s comment: %s\n", String8(itemIdent).string(),
                            //     String8(comment).string());
                        }
                    } else if (code == ResXMLTree::END_TAG) {
                        if (strcmp16(block.getElementName(&len), declare_styleable16.string()) == 0) {
                            break;
                        }

                        SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
                                "Found tag </%s> where </attr> is expected\n",
                                String8(block.getElementName(&len)).string());
                        return UNKNOWN_ERROR;
                    }
                }
                continue;

            } else if (strcmp16(block.getElementName(&len), attr16.string()) == 0) {
                err = compileAttribute(in, block, myPackage, outTable, NULL);
                if (err != NO_ERROR) {
                    hasErrors = true;
                }
                continue;

            } else if (strcmp16(block.getElementName(&len), item16.string()) == 0) {
                curTag = &item16;
                ssize_t attri = block.indexOfAttribute(NULL, "type");
                if (attri >= 0) {
                    curType = String16(block.getAttributeStringValue(attri, &len));
                    ssize_t formatIdx = block.indexOfAttribute(NULL, "format");
                    if (formatIdx >= 0) {
                        String16 formatStr = String16(block.getAttributeStringValue(
                                formatIdx, &len));
                        curFormat = parse_flags(formatStr.string(), formatStr.size(),
                                                gFormatFlags);
                        if (curFormat == 0) {
                            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
                                    "Tag <item> 'format' attribute value \"%s\" not valid\n",
                                    String8(formatStr).string());
                            hasErrors = localHasErrors = true;
                        }
                    }
                } else {
                    SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
                            "A 'type' attribute is required for <item>\n");
                    hasErrors = localHasErrors = true;
                }
                curIsStyled = true;
            } else if (strcmp16(block.getElementName(&len), string16.string()) == 0) {
                // Note the existence and locale of every string we process
                char rawLocale[16];
                curParams.getLocale(rawLocale);
                String8 locale(rawLocale);
                String16 name;
                String16 translatable;
                String16 formatted;

                size_t n = block.getAttributeCount();
                for (size_t i = 0; i < n; i++) {
                    size_t length;
                    const uint16_t* attr = block.getAttributeName(i, &length);
                    if (strcmp16(attr, name16.string()) == 0) {
                        name.setTo(block.getAttributeStringValue(i, &length));
                    } else if (strcmp16(attr, translatable16.string()) == 0) {
                        translatable.setTo(block.getAttributeStringValue(i, &length));
                    } else if (strcmp16(attr, formatted16.string()) == 0) {
                        formatted.setTo(block.getAttributeStringValue(i, &length));
                    }
                }
                
                if (name.size() > 0) {
                    if (translatable == false16) {
                        curIsFormatted = false;
                        // Untranslatable strings must only exist in the default [empty] locale
                        if (locale.size() > 0) {
                            fprintf(stderr, "aapt: warning: string '%s' in %s marked untranslatable but exists"
                                    " in locale '%s'\n", String8(name).string(),
                                    bundle->getResourceSourceDirs()[0],
                                    locale.string());
                            // hasErrors = localHasErrors = true;
                        } else {
                            // Intentionally empty block:
                            //
                            // Don't add untranslatable strings to the localization table; that
                            // way if we later see localizations of them, they'll be flagged as
                            // having no default translation.
                        }
                    } else {
                        outTable->addLocalization(name, locale);
                    }

                    if (formatted == false16) {
                        curIsFormatted = false;
                    }
                }

                curTag = &string16;
                curType = string16;
                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_STRING;
                curIsStyled = true;
                curIsPseudolocalizable = true;
            } else if (strcmp16(block.getElementName(&len), drawable16.string()) == 0) {
                curTag = &drawable16;
                curType = drawable16;
                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_COLOR;
            } else if (strcmp16(block.getElementName(&len), color16.string()) == 0) {
                curTag = &color16;
                curType = color16;
                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_COLOR;
            } else if (strcmp16(block.getElementName(&len), bool16.string()) == 0) {
                curTag = &bool16;
                curType = bool16;
                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_BOOLEAN;
            } else if (strcmp16(block.getElementName(&len), integer16.string()) == 0) {
                curTag = &integer16;
                curType = integer16;
                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_INTEGER;
            } else if (strcmp16(block.getElementName(&len), dimen16.string()) == 0) {
                curTag = &dimen16;
                curType = dimen16;
                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_DIMENSION;
            } else if (strcmp16(block.getElementName(&len), fraction16.string()) == 0) {
                curTag = &fraction16;
                curType = fraction16;
                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_FRACTION;
            } else if (strcmp16(block.getElementName(&len), bag16.string()) == 0) {
                curTag = &bag16;
                curIsBag = true;
                ssize_t attri = block.indexOfAttribute(NULL, "type");
                if (attri >= 0) {
                    curType = String16(block.getAttributeStringValue(attri, &len));
                } else {
                    SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
                            "A 'type' attribute is required for <bag>\n");
                    hasErrors = localHasErrors = true;
                }
            } else if (strcmp16(block.getElementName(&len), style16.string()) == 0) {
                curTag = &style16;
                curType = style16;
                curIsBag = true;
            } else if (strcmp16(block.getElementName(&len), plurals16.string()) == 0) {
                curTag = &plurals16;
                curType = plurals16;
                curIsBag = true;
            } else if (strcmp16(block.getElementName(&len), array16.string()) == 0) {
                curTag = &array16;
                curType = array16;
                curIsBag = true;
                curIsBagReplaceOnOverwrite = true;
                ssize_t formatIdx = block.indexOfAttribute(NULL, "format");
                if (formatIdx >= 0) {
                    String16 formatStr = String16(block.getAttributeStringValue(
                            formatIdx, &len));
                    curFormat = parse_flags(formatStr.string(), formatStr.size(),
                                            gFormatFlags);
                    if (curFormat == 0) {
                        SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
                                "Tag <array> 'format' attribute value \"%s\" not valid\n",
                                String8(formatStr).string());
                        hasErrors = localHasErrors = true;
                    }
                }
            } else if (strcmp16(block.getElementName(&len), string_array16.string()) == 0) {
                // Check whether these strings need valid formats.
                // (simplified form of what string16 does above)
                size_t n = block.getAttributeCount();
                for (size_t i = 0; i < n; i++) {
                    size_t length;
                    const uint16_t* attr = block.getAttributeName(i, &length);
                    if (strcmp16(attr, translatable16.string()) == 0
                            || strcmp16(attr, formatted16.string()) == 0) {
                        const uint16_t* value = block.getAttributeStringValue(i, &length);
                        if (strcmp16(value, false16.string()) == 0) {
                            curIsFormatted = false;
                            break;
                        }
                    }
                }

                curTag = &string_array16;
                curType = array16;
                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_STRING;
                curIsBag = true;
                curIsBagReplaceOnOverwrite = true;
                curIsPseudolocalizable = true;
            } else if (strcmp16(block.getElementName(&len), integer_array16.string()) == 0) {
                curTag = &integer_array16;
                curType = array16;
                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_INTEGER;
                curIsBag = true;
                curIsBagReplaceOnOverwrite = true;
            } else {
                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
                        "Found tag %s where item is expected\n",
                        String8(block.getElementName(&len)).string());
                return UNKNOWN_ERROR;
            }

            String16 ident;
            ssize_t identIdx = block.indexOfAttribute(NULL, "name");
            if (identIdx >= 0) {
                ident = String16(block.getAttributeStringValue(identIdx, &len));
            } else {
                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
                        "A 'name' attribute is required for <%s>\n",
                        String8(*curTag).string());
                hasErrors = localHasErrors = true;
            }

            String16 product;
            identIdx = block.indexOfAttribute(NULL, "product");
            if (identIdx >= 0) {
                product = String16(block.getAttributeStringValue(identIdx, &len));
            }

            String16 comment(block.getComment(&len) ? block.getComment(&len) : nulStr);
            
            if (curIsBag) {
                // Figure out the parent of this bag...
                String16 parentIdent;
                ssize_t parentIdentIdx = block.indexOfAttribute(NULL, "parent");
                if (parentIdentIdx >= 0) {
                    parentIdent = String16(block.getAttributeStringValue(parentIdentIdx, &len));
                } else {
                    ssize_t sep = ident.findLast('.');
                    if (sep >= 0) {
                        parentIdent.setTo(ident, sep);
                    }
                }

                if (!localHasErrors) {
                    err = outTable->startBag(SourcePos(in->getPrintableSource(),
                            block.getLineNumber()), myPackage, curType, ident,
                            parentIdent, &curParams,
                            overwrite, curIsBagReplaceOnOverwrite);
                    if (err != NO_ERROR) {
                        hasErrors = localHasErrors = true;
                    }
                }
                
                ssize_t elmIndex = 0;
                char elmIndexStr[14];
                while ((code=block.next()) != ResXMLTree::END_DOCUMENT
                        && code != ResXMLTree::BAD_DOCUMENT) {

                    if (code == ResXMLTree::START_TAG) {
                        if (strcmp16(block.getElementName(&len), item16.string()) != 0) {
                            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
                                    "Tag <%s> can not appear inside <%s>, only <item>\n",
                                    String8(block.getElementName(&len)).string(),
                                    String8(*curTag).string());
                            return UNKNOWN_ERROR;
                        }

                        String16 itemIdent;
                        if (curType == array16) {
                            sprintf(elmIndexStr, "^index_%d", (int)elmIndex++);
                            itemIdent = String16(elmIndexStr);
                        } else if (curType == plurals16) {
                            ssize_t itemIdentIdx = block.indexOfAttribute(NULL, "quantity");
                            if (itemIdentIdx >= 0) {
                                String16 quantity16(block.getAttributeStringValue(itemIdentIdx, &len));
                                if (quantity16 == other16) {
                                    itemIdent = quantityOther16;
                                }
                                else if (quantity16 == zero16) {
                                    itemIdent = quantityZero16;
                                }
                                else if (quantity16 == one16) {
                                    itemIdent = quantityOne16;
                                }
                                else if (quantity16 == two16) {
                                    itemIdent = quantityTwo16;
                                }
                                else if (quantity16 == few16) {
                                    itemIdent = quantityFew16;
                                }
                                else if (quantity16 == many16) {
                                    itemIdent = quantityMany16;
                                }
                                else {
                                    SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
                                            "Illegal 'quantity' attribute is <item> inside <plurals>\n");
                                    hasErrors = localHasErrors = true;
                                }
                            } else {
                                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
                                        "A 'quantity' attribute is required for <item> inside <plurals>\n");
                                hasErrors = localHasErrors = true;
                            }
                        } else {
                            ssize_t itemIdentIdx = block.indexOfAttribute(NULL, "name");
                            if (itemIdentIdx >= 0) {
                                itemIdent = String16(block.getAttributeStringValue(itemIdentIdx, &len));
                            } else {
                                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
                                        "A 'name' attribute is required for <item>\n");
                                hasErrors = localHasErrors = true;
                            }
                        }

                        ResXMLParser::ResXMLPosition parserPosition;
                        block.getPosition(&parserPosition);

                        err = parseAndAddBag(bundle, in, &block, curParams, myPackage, curType,
                                ident, parentIdent, itemIdent, curFormat, curIsFormatted,
                                product, false, overwrite, outTable);
                        if (err == NO_ERROR) {
                            if (curIsPseudolocalizable && localeIsDefined(curParams)
                                    && bundle->getPseudolocalize()) {
                                // pseudolocalize here
#if 1
                                block.setPosition(parserPosition);
                                err = parseAndAddBag(bundle, in, &block, pseudoParams, myPackage,
                                        curType, ident, parentIdent, itemIdent, curFormat,
                                        curIsFormatted, product, true, overwrite, outTable);
#endif
                            }
                        } 
                        if (err != NO_ERROR) {
                            hasErrors = localHasErrors = true;
                        }
                    } else if (code == ResXMLTree::END_TAG) {
                        if (strcmp16(block.getElementName(&len), curTag->string()) != 0) {
                            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
                                    "Found tag </%s> where </%s> is expected\n",
                                    String8(block.getElementName(&len)).string(),
                                    String8(*curTag).string());
                            return UNKNOWN_ERROR;
                        }
                        break;
                    }
                }
            } else {
                ResXMLParser::ResXMLPosition parserPosition;
                block.getPosition(&parserPosition);

                err = parseAndAddEntry(bundle, in, &block, curParams, myPackage, curType, ident,
                        *curTag, curIsStyled, curFormat, curIsFormatted,
                        product, false, overwrite, outTable);

                if (err < NO_ERROR) { // Why err < NO_ERROR instead of err != NO_ERROR?
                    hasErrors = localHasErrors = true;
                }
                else if (err == NO_ERROR) {
                    if (curIsPseudolocalizable && localeIsDefined(curParams)
                            && bundle->getPseudolocalize()) {
                        // pseudolocalize here
                        block.setPosition(parserPosition);
                        err = parseAndAddEntry(bundle, in, &block, pseudoParams, myPackage, curType,
                                ident, *curTag, curIsStyled, curFormat,
                                curIsFormatted, product,
                                true, overwrite, outTable);
                        if (err != NO_ERROR) {
                            hasErrors = localHasErrors = true;
                        }
                    }
                }
            }

#if 0
            if (comment.size() > 0) {
                printf("Comment for @%s:%s/%s: %s\n", String8(myPackage).string(),
                       String8(curType).string(), String8(ident).string(),
                       String8(comment).string());
            }
#endif
            if (!localHasErrors) {
                outTable->appendComment(myPackage, curType, ident, comment, false);
            }
        }
        else if (code == ResXMLTree::END_TAG) {
            if (strcmp16(block.getElementName(&len), resources16.string()) != 0) {
                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
                        "Unexpected end tag %s\n", String8(block.getElementName(&len)).string());
                return UNKNOWN_ERROR;
            }
        }
        else if (code == ResXMLTree::START_NAMESPACE || code == ResXMLTree::END_NAMESPACE) {
        }
        else if (code == ResXMLTree::TEXT) {
            if (isWhitespace(block.getText(&len))) {
                continue;
            }
            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
                    "Found text \"%s\" where item tag is expected\n",
                    String8(block.getText(&len)).string());
            return UNKNOWN_ERROR;
        }
    }

    return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
}

ResourceTable::ResourceTable(Bundle* bundle, const String16& assetsPackage)
    : mAssetsPackage(assetsPackage), mNextPackageId(1), mHaveAppPackage(false),
      mIsAppPackage(!bundle->getExtending()),
      mNumLocal(0),
      mBundle(bundle)
{
}

status_t ResourceTable::addIncludedResources(Bundle* bundle, const sp<AaptAssets>& assets)
{
    status_t err = assets->buildIncludedResources(bundle);
    if (err != NO_ERROR) {
        return err;
    }

    // For future reference to included resources.
    mAssets = assets;

    const ResTable& incl = assets->getIncludedResources();

    // Retrieve all the packages.
    const size_t N = incl.getBasePackageCount();
    for (size_t phase=0; phase<2; phase++) {
        for (size_t i=0; i<N; i++) {
            String16 name(incl.getBasePackageName(i));
            uint32_t id = incl.getBasePackageId(i);
            // First time through: only add base packages (id
            // is not 0); second time through add the other
            // packages.
            if (phase != 0) {
                if (id != 0) {
                    // Skip base packages -- already one.
                    id = 0;
                } else {
                    // Assign a dynamic id.
                    id = mNextPackageId;
                }
            } else if (id != 0) {
                if (id == 127) {
                    if (mHaveAppPackage) {
                        fprintf(stderr, "Included resources have two application packages!\n");
                        return UNKNOWN_ERROR;
                    }
                    mHaveAppPackage = true;
                }
                if (mNextPackageId > id) {
                    fprintf(stderr, "Included base package ID %d already in use!\n", id);
                    return UNKNOWN_ERROR;
                }
            }
            if (id != 0) {
                NOISY(printf("Including package %s with ID=%d\n",
                             String8(name).string(), id));
                sp<Package> p = new Package(name, id);
                mPackages.add(name, p);
                mOrderedPackages.add(p);

                if (id >= mNextPackageId) {
                    mNextPackageId = id+1;
                }
            }
        }
    }

    // Every resource table always has one first entry, the bag attributes.
    const SourcePos unknown(String8("????"), 0);
    sp<Type> attr = getType(mAssetsPackage, String16("attr"), unknown);

    return NO_ERROR;
}

status_t ResourceTable::addPublic(const SourcePos& sourcePos,
                                  const String16& package,
                                  const String16& type,
                                  const String16& name,
                                  const uint32_t ident)
{
    uint32_t rid = mAssets->getIncludedResources()
        .identifierForName(name.string(), name.size(),
                           type.string(), type.size(),
                           package.string(), package.size());
    if (rid != 0) {
        sourcePos.error("Error declaring public resource %s/%s for included package %s\n",
                String8(type).string(), String8(name).string(),
                String8(package).string());
        return UNKNOWN_ERROR;
    }

    sp<Type> t = getType(package, type, sourcePos);
    if (t == NULL) {
        return UNKNOWN_ERROR;
    }
    return t->addPublic(sourcePos, name, ident);
}

status_t ResourceTable::addEntry(const SourcePos& sourcePos,
                                 const String16& package,
                                 const String16& type,
                                 const String16& name,
                                 const String16& value,
                                 const Vector<StringPool::entry_style_span>* style,
                                 const ResTable_config* params,
                                 const bool doSetIndex,
                                 const int32_t format,
                                 const bool overwrite)
{
    // Check for adding entries in other packages...  for now we do
    // nothing.  We need to do the right thing here to support skinning.
    uint32_t rid = mAssets->getIncludedResources()
        .identifierForName(name.string(), name.size(),
                           type.string(), type.size(),
                           package.string(), package.size());
    if (rid != 0) {
        return NO_ERROR;
    }
    
#if 0
    if (name == String16("left")) {
        printf("Adding entry left: file=%s, line=%d, type=%s, value=%s\n",
               sourcePos.file.string(), sourcePos.line, String8(type).string(),
               String8(value).string());
    }
#endif

    sp<Entry> e = getEntry(package, type, name, sourcePos, overwrite,
                           params, doSetIndex);
    if (e == NULL) {
        return UNKNOWN_ERROR;
    }
    status_t err = e->setItem(sourcePos, value, style, format, overwrite);
    if (err == NO_ERROR) {
        mNumLocal++;
    }
    return err;
}

status_t ResourceTable::startBag(const SourcePos& sourcePos,
                                 const String16& package,
                                 const String16& type,
                                 const String16& name,
                                 const String16& bagParent,
                                 const ResTable_config* params,
                                 bool overlay,
                                 bool replace, bool isId)
{
    status_t result = NO_ERROR;

    // Check for adding entries in other packages...  for now we do
    // nothing.  We need to do the right thing here to support skinning.
    uint32_t rid = mAssets->getIncludedResources()
    .identifierForName(name.string(), name.size(),
                       type.string(), type.size(),
                       package.string(), package.size());
    if (rid != 0) {
        return NO_ERROR;
    }
    
#if 0
    if (name == String16("left")) {
        printf("Adding bag left: file=%s, line=%d, type=%s\n",
               sourcePos.file.striing(), sourcePos.line, String8(type).string());
    }
#endif
    if (overlay && !mBundle->getAutoAddOverlay() && !hasBagOrEntry(package, type, name)) {
        bool canAdd = false;
        sp<Package> p = mPackages.valueFor(package);
        if (p != NULL) {
            sp<Type> t = p->getTypes().valueFor(type);
            if (t != NULL) {
                if (t->getCanAddEntries().indexOf(name) >= 0) {
                    canAdd = true;
                }
            }
        }
        if (!canAdd) {
            sourcePos.error("Resource does not already exist in overlay at '%s'; use <add-resource> to add.\n",
                            String8(name).string());
            return UNKNOWN_ERROR;
        }
    }
    sp<Entry> e = getEntry(package, type, name, sourcePos, overlay, params);
    if (e == NULL) {
        return UNKNOWN_ERROR;
    }
    
    // If a parent is explicitly specified, set it.
    if (bagParent.size() > 0) {
        e->setParent(bagParent);
    }

    if ((result = e->makeItABag(sourcePos)) != NO_ERROR) {
        return result;
    }

    if (overlay && replace) { 
        return e->emptyBag(sourcePos);
    }
    return result;
}

status_t ResourceTable::addBag(const SourcePos& sourcePos,
                               const String16& package,
                               const String16& type,
                               const String16& name,
                               const String16& bagParent,
                               const String16& bagKey,
                               const String16& value,
                               const Vector<StringPool::entry_style_span>* style,
                               const ResTable_config* params,
                               bool replace, bool isId, const int32_t format)
{
    // Check for adding entries in other packages...  for now we do
    // nothing.  We need to do the right thing here to support skinning.
    uint32_t rid = mAssets->getIncludedResources()
        .identifierForName(name.string(), name.size(),
                           type.string(), type.size(),
                           package.string(), package.size());
    if (rid != 0) {
        return NO_ERROR;
    }

#if 0
    if (name == String16("left")) {
        printf("Adding bag left: file=%s, line=%d, type=%s\n",
               sourcePos.file.striing(), sourcePos.line, String8(type).string());
    }
#endif
    sp<Entry> e = getEntry(package, type, name, sourcePos, replace, params);
    if (e == NULL) {
        return UNKNOWN_ERROR;
    }

    // If a parent is explicitly specified, set it.
    if (bagParent.size() > 0) {
        e->setParent(bagParent);
    }

    const bool first = e->getBag().indexOfKey(bagKey) < 0;
    status_t err = e->addToBag(sourcePos, bagKey, value, style, replace, isId, format);
    if (err == NO_ERROR && first) {
        mNumLocal++;
    }
    return err;
}

bool ResourceTable::hasBagOrEntry(const String16& package,
                                  const String16& type,
                                  const String16& name) const
{
    // First look for this in the included resources...
    uint32_t rid = mAssets->getIncludedResources()
        .identifierForName(name.string(), name.size(),
                           type.string(), type.size(),
                           package.string(), package.size());
    if (rid != 0) {
        return true;
    }

    sp<Package> p = mPackages.valueFor(package);
    if (p != NULL) {
        sp<Type> t = p->getTypes().valueFor(type);
        if (t != NULL) {
            sp<ConfigList> c =  t->getConfigs().valueFor(name);
            if (c != NULL) return true;
        }
    }

    return false;
}

bool ResourceTable::hasBagOrEntry(const String16& ref,
                                  const String16* defType,
                                  const String16* defPackage)
{
    String16 package, type, name;
    if (!ResTable::expandResourceRef(ref.string(), ref.size(), &package, &type, &name,
                defType, defPackage ? defPackage:&mAssetsPackage, NULL)) {
        return false;
    }
    return hasBagOrEntry(package, type, name);
}

bool ResourceTable::appendComment(const String16& package,
                                  const String16& type,
                                  const String16& name,
                                  const String16& comment,
                                  bool onlyIfEmpty)
{
    if (comment.size() <= 0) {
        return true;
    }

    sp<Package> p = mPackages.valueFor(package);
    if (p != NULL) {
        sp<Type> t = p->getTypes().valueFor(type);
        if (t != NULL) {
            sp<ConfigList> c =  t->getConfigs().valueFor(name);
            if (c != NULL) {
                c->appendComment(comment, onlyIfEmpty);
                return true;
            }
        }
    }
    return false;
}

bool ResourceTable::appendTypeComment(const String16& package,
                                      const String16& type,
                                      const String16& name,
                                      const String16& comment)
{
    if (comment.size() <= 0) {
        return true;
    }
    
    sp<Package> p = mPackages.valueFor(package);
    if (p != NULL) {
        sp<Type> t = p->getTypes().valueFor(type);
        if (t != NULL) {
            sp<ConfigList> c =  t->getConfigs().valueFor(name);
            if (c != NULL) {
                c->appendTypeComment(comment);
                return true;
            }
        }
    }
    return false;
}

void ResourceTable::canAddEntry(const SourcePos& pos,
        const String16& package, const String16& type, const String16& name)
{
    sp<Type> t = getType(package, type, pos);
    if (t != NULL) {
        t->canAddEntry(name);
    }
}

size_t ResourceTable::size() const {
    return mPackages.size();
}

size_t ResourceTable::numLocalResources() const {
    return mNumLocal;
}

bool ResourceTable::hasResources() const {
    return mNumLocal > 0;
}

sp<AaptFile> ResourceTable::flatten(Bundle* bundle)
{
    sp<AaptFile> data = new AaptFile(String8(), AaptGroupEntry(), String8());
    status_t err = flatten(bundle, data);
    return err == NO_ERROR ? data : NULL;
}

inline uint32_t ResourceTable::getResId(const sp<Package>& p,
                                        const sp<Type>& t,
                                        uint32_t nameId)
{
    return makeResId(p->getAssignedId(), t->getIndex(), nameId);
}

uint32_t ResourceTable::getResId(const String16& package,
                                 const String16& type,
                                 const String16& name,
                                 bool onlyPublic) const
{
    sp<Package> p = mPackages.valueFor(package);
    if (p == NULL) return 0;

    // First look for this in the included resources...
    uint32_t specFlags = 0;
    uint32_t rid = mAssets->getIncludedResources()
        .identifierForName(name.string(), name.size(),
                           type.string(), type.size(),
                           package.string(), package.size(),
                           &specFlags);
    if (rid != 0) {
        if (onlyPublic) {
            if ((specFlags & ResTable_typeSpec::SPEC_PUBLIC) == 0) {
                return 0;
            }
        }
        
        if (Res_INTERNALID(rid)) {
            return rid;
        }
        return Res_MAKEID(p->getAssignedId()-1,
                          Res_GETTYPE(rid),
                          Res_GETENTRY(rid));
    }

    sp<Type> t = p->getTypes().valueFor(type);
    if (t == NULL) return 0;
    sp<ConfigList> c =  t->getConfigs().valueFor(name);
    if (c == NULL) return 0;
    int32_t ei = c->getEntryIndex();
    if (ei < 0) return 0;
    return getResId(p, t, ei);
}

uint32_t ResourceTable::getResId(const String16& ref,
                                 const String16* defType,
                                 const String16* defPackage,
                                 const char** outErrorMsg,
                                 bool onlyPublic) const
{
    String16 package, type, name;
    if (!ResTable::expandResourceRef(
        ref.string(), ref.size(), &package, &type, &name,
        defType, defPackage ? defPackage:&mAssetsPackage,
        outErrorMsg)) {
        NOISY(printf("Expanding resource: ref=%s\n",
                     String8(ref).string()));
        NOISY(printf("Expanding resource: defType=%s\n",
                     defType ? String8(*defType).string() : "NULL"));
        NOISY(printf("Expanding resource: defPackage=%s\n",
                     defPackage ? String8(*defPackage).string() : "NULL"));
        NOISY(printf("Expanding resource: ref=%s\n", String8(ref).string()));
        NOISY(printf("Expanded resource: p=%s, t=%s, n=%s, res=0\n",
                     String8(package).string(), String8(type).string(),
                     String8(name).string()));
        return 0;
    }
    uint32_t res = getResId(package, type, name, onlyPublic);
    NOISY(printf("Expanded resource: p=%s, t=%s, n=%s, res=%d\n",
                 String8(package).string(), String8(type).string(),
                 String8(name).string(), res));
    if (res == 0) {
        if (outErrorMsg)
            *outErrorMsg = "No resource found that matches the given name";
    }
    return res;
}

bool ResourceTable::isValidResourceName(const String16& s)
{
    const char16_t* p = s.string();
    bool first = true;
    while (*p) {
        if ((*p >= 'a' && *p <= 'z')
            || (*p >= 'A' && *p <= 'Z')
            || *p == '_'
            || (!first && *p >= '0' && *p <= '9')) {
            first = false;
            p++;
            continue;
        }
        return false;
    }
    return true;
}

bool ResourceTable::stringToValue(Res_value* outValue, StringPool* pool,
                                  const String16& str,
                                  bool preserveSpaces, bool coerceType,
                                  uint32_t attrID,
                                  const Vector<StringPool::entry_style_span>* style,
                                  String16* outStr, void* accessorCookie,
                                  uint32_t attrType)
{
    String16 finalStr;

    bool res = true;
    if (style == NULL || style->size() == 0) {
        // Text is not styled so it can be any type...  let's figure it out.
        res = mAssets->getIncludedResources()
            .stringToValue(outValue, &finalStr, str.string(), str.size(), preserveSpaces,
                            coerceType, attrID, NULL, &mAssetsPackage, this,
                           accessorCookie, attrType);
    } else {
        // Styled text can only be a string, and while collecting the style
        // information we have already processed that string!
        outValue->size = sizeof(Res_value);
        outValue->res0 = 0;
        outValue->dataType = outValue->TYPE_STRING;
        outValue->data = 0;
        finalStr = str;
    }

    if (!res) {
        return false;
    }

    if (outValue->dataType == outValue->TYPE_STRING) {
        // Should do better merging styles.
        if (pool) {
            if (style != NULL && style->size() > 0) {
                outValue->data = pool->add(finalStr, *style);
            } else {
                outValue->data = pool->add(finalStr, true);
            }
        } else {
            // Caller will fill this in later.
            outValue->data = 0;
        }
    
        if (outStr) {
            *outStr = finalStr;
        }

    }

    return true;
}

uint32_t ResourceTable::getCustomResource(
    const String16& package, const String16& type, const String16& name) const
{
    //printf("getCustomResource: %s %s %s\n", String8(package).string(),
    //       String8(type).string(), String8(name).string());
    sp<Package> p = mPackages.valueFor(package);
    if (p == NULL) return 0;
    sp<Type> t = p->getTypes().valueFor(type);
    if (t == NULL) return 0;
    sp<ConfigList> c =  t->getConfigs().valueFor(name);
    if (c == NULL) return 0;
    int32_t ei = c->getEntryIndex();
    if (ei < 0) return 0;
    return getResId(p, t, ei);
}

uint32_t ResourceTable::getCustomResourceWithCreation(
        const String16& package, const String16& type, const String16& name,
        const bool createIfNotFound)
{
    uint32_t resId = getCustomResource(package, type, name);
    if (resId != 0 || !createIfNotFound) {
        return resId;
    }
    String16 value("false");

    status_t status = addEntry(mCurrentXmlPos, package, type, name, value, NULL, NULL, true);
    if (status == NO_ERROR) {
        resId = getResId(package, type, name);
        return resId;
    }
    return 0;
}

uint32_t ResourceTable::getRemappedPackage(uint32_t origPackage) const
{
    return origPackage;
}

bool ResourceTable::getAttributeType(uint32_t attrID, uint32_t* outType)
{
    //printf("getAttributeType #%08x\n", attrID);
    Res_value value;
    if (getItemValue(attrID, ResTable_map::ATTR_TYPE, &value)) {
        //printf("getAttributeType #%08x (%s): #%08x\n", attrID,
        //       String8(getEntry(attrID)->getName()).string(), value.data);
        *outType = value.data;
        return true;
    }
    return false;
}

bool ResourceTable::getAttributeMin(uint32_t attrID, uint32_t* outMin)
{
    //printf("getAttributeMin #%08x\n", attrID);
    Res_value value;
    if (getItemValue(attrID, ResTable_map::ATTR_MIN, &value)) {
        *outMin = value.data;
        return true;
    }
    return false;
}

bool ResourceTable::getAttributeMax(uint32_t attrID, uint32_t* outMax)
{
    //printf("getAttributeMax #%08x\n", attrID);
    Res_value value;
    if (getItemValue(attrID, ResTable_map::ATTR_MAX, &value)) {
        *outMax = value.data;
        return true;
    }
    return false;
}

uint32_t ResourceTable::getAttributeL10N(uint32_t attrID)
{
    //printf("getAttributeL10N #%08x\n", attrID);
    Res_value value;
    if (getItemValue(attrID, ResTable_map::ATTR_L10N, &value)) {
        return value.data;
    }
    return ResTable_map::L10N_NOT_REQUIRED;
}

bool ResourceTable::getLocalizationSetting()
{
    return mBundle->getRequireLocalization();
}

void ResourceTable::reportError(void* accessorCookie, const char* fmt, ...)
{
    if (accessorCookie != NULL && fmt != NULL) {
        AccessorCookie* ac = (AccessorCookie*)accessorCookie;
        int retval=0;
        char buf[1024];
        va_list ap;
        va_start(ap, fmt);
        retval = vsnprintf(buf, sizeof(buf), fmt, ap);
        va_end(ap);
        ac->sourcePos.error("Error: %s (at '%s' with value '%s').\n",
                            buf, ac->attr.string(), ac->value.string());
    }
}

bool ResourceTable::getAttributeKeys(
    uint32_t attrID, Vector<String16>* outKeys)
{
    sp<const Entry> e = getEntry(attrID);
    if (e != NULL) {
        const size_t N = e->getBag().size();
        for (size_t i=0; i<N; i++) {
            const String16& key = e->getBag().keyAt(i);
            if (key.size() > 0 && key.string()[0] != '^') {
                outKeys->add(key);
            }
        }
        return true;
    }
    return false;
}

bool ResourceTable::getAttributeEnum(
    uint32_t attrID, const char16_t* name, size_t nameLen,
    Res_value* outValue)
{
    //printf("getAttributeEnum #%08x %s\n", attrID, String8(name, nameLen).string());
    String16 nameStr(name, nameLen);
    sp<const Entry> e = getEntry(attrID);
    if (e != NULL) {
        const size_t N = e->getBag().size();
        for (size_t i=0; i<N; i++) {
            //printf("Comparing %s to %s\n", String8(name, nameLen).string(),
            //       String8(e->getBag().keyAt(i)).string());
            if (e->getBag().keyAt(i) == nameStr) {
                return getItemValue(attrID, e->getBag().valueAt(i).bagKeyId, outValue);
            }
        }
    }
    return false;
}

bool ResourceTable::getAttributeFlags(
    uint32_t attrID, const char16_t* name, size_t nameLen,
    Res_value* outValue)
{
    outValue->dataType = Res_value::TYPE_INT_HEX;
    outValue->data = 0;

    //printf("getAttributeFlags #%08x %s\n", attrID, String8(name, nameLen).string());
    String16 nameStr(name, nameLen);
    sp<const Entry> e = getEntry(attrID);
    if (e != NULL) {
        const size_t N = e->getBag().size();

        const char16_t* end = name + nameLen;
        const char16_t* pos = name;
        bool failed = false;
        while (pos < end && !failed) {
            const char16_t* start = pos;
            end++;
            while (pos < end && *pos != '|') {
                pos++;
            }

            String16 nameStr(start, pos-start);
            size_t i;
            for (i=0; i<N; i++) {
                //printf("Comparing \"%s\" to \"%s\"\n", String8(nameStr).string(),
                //       String8(e->getBag().keyAt(i)).string());
                if (e->getBag().keyAt(i) == nameStr) {
                    Res_value val;
                    bool got = getItemValue(attrID, e->getBag().valueAt(i).bagKeyId, &val);
                    if (!got) {
                        return false;
                    }
                    //printf("Got value: 0x%08x\n", val.data);
                    outValue->data |= val.data;
                    break;
                }
            }

            if (i >= N) {
                // Didn't find this flag identifier.
                return false;
            }
            if (pos < end) {
                pos++;
            }
        }

        return true;
    }
    return false;
}

status_t ResourceTable::assignResourceIds()
{
    const size_t N = mOrderedPackages.size();
    size_t pi;
    status_t firstError = NO_ERROR;

    // First generate all bag attributes and assign indices.
    for (pi=0; pi<N; pi++) {
        sp<Package> p = mOrderedPackages.itemAt(pi);
        if (p == NULL || p->getTypes().size() == 0) {
            // Empty, skip!
            continue;
        }

        status_t err = p->applyPublicTypeOrder();
        if (err != NO_ERROR && firstError == NO_ERROR) {
            firstError = err;
        }

        // Generate attributes...
        const size_t N = p->getOrderedTypes().size();
        size_t ti;
        for (ti=0; ti<N; ti++) {
            sp<Type> t = p->getOrderedTypes().itemAt(ti);
            if (t == NULL) {
                continue;
            }
            const size_t N = t->getOrderedConfigs().size();
            for (size_t ci=0; ci<N; ci++) {
                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);
                if (c == NULL) {
                    continue;
                }
                const size_t N = c->getEntries().size();
                for (size_t ei=0; ei<N; ei++) {
                    sp<Entry> e = c->getEntries().valueAt(ei);
                    if (e == NULL) {
                        continue;
                    }
                    status_t err = e->generateAttributes(this, p->getName());
                    if (err != NO_ERROR && firstError == NO_ERROR) {
                        firstError = err;
                    }
                }
            }
        }

        const SourcePos unknown(String8("????"), 0);
        sp<Type> attr = p->getType(String16("attr"), unknown);

        // Assign indices...
        for (ti=0; ti<N; ti++) {
            sp<Type> t = p->getOrderedTypes().itemAt(ti);
            if (t == NULL) {
                continue;
            }
            err = t->applyPublicEntryOrder();
            if (err != NO_ERROR && firstError == NO_ERROR) {
                firstError = err;
            }

            const size_t N = t->getOrderedConfigs().size();
            t->setIndex(ti+1);

            LOG_ALWAYS_FATAL_IF(ti == 0 && attr != t,
                                "First type is not attr!");

            for (size_t ei=0; ei<N; ei++) {
                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ei);
                if (c == NULL) {
                    continue;
                }
                c->setEntryIndex(ei);
            }
        }

        // Assign resource IDs to keys in bags...
        for (ti=0; ti<N; ti++) {
            sp<Type> t = p->getOrderedTypes().itemAt(ti);
            if (t == NULL) {
                continue;
            }
            const size_t N = t->getOrderedConfigs().size();
            for (size_t ci=0; ci<N; ci++) {
                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);
                //printf("Ordered config #%d: %p\n", ci, c.get());
                const size_t N = c->getEntries().size();
                for (size_t ei=0; ei<N; ei++) {
                    sp<Entry> e = c->getEntries().valueAt(ei);
                    if (e == NULL) {
                        continue;
                    }
                    status_t err = e->assignResourceIds(this, p->getName());
                    if (err != NO_ERROR && firstError == NO_ERROR) {
                        firstError = err;
                    }
                }
            }
        }
    }
    return firstError;
}

status_t ResourceTable::addSymbols(const sp<AaptSymbols>& outSymbols) {
    const size_t N = mOrderedPackages.size();
    size_t pi;

    for (pi=0; pi<N; pi++) {
        sp<Package> p = mOrderedPackages.itemAt(pi);
        if (p->getTypes().size() == 0) {
            // Empty, skip!
            continue;
        }

        const size_t N = p->getOrderedTypes().size();
        size_t ti;

        for (ti=0; ti<N; ti++) {
            sp<Type> t = p->getOrderedTypes().itemAt(ti);
            if (t == NULL) {
                continue;
            }
            const size_t N = t->getOrderedConfigs().size();
            sp<AaptSymbols> typeSymbols;
            typeSymbols = outSymbols->addNestedSymbol(String8(t->getName()), t->getPos());
            for (size_t ci=0; ci<N; ci++) {
                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);
                if (c == NULL) {
                    continue;
                }
                uint32_t rid = getResId(p, t, ci);
                if (rid == 0) {
                    return UNKNOWN_ERROR;
                }
                if (Res_GETPACKAGE(rid) == (size_t)(p->getAssignedId()-1)) {
                    typeSymbols->addSymbol(String8(c->getName()), rid, c->getPos());
                    
                    String16 comment(c->getComment());
                    typeSymbols->appendComment(String8(c->getName()), comment, c->getPos());
                    //printf("Type symbol %s comment: %s\n", String8(e->getName()).string(),
                    //     String8(comment).string());
                    comment = c->getTypeComment();
                    typeSymbols->appendTypeComment(String8(c->getName()), comment);
                } else {
#if 0
                    printf("**** NO MATCH: 0x%08x vs 0x%08x\n",
                           Res_GETPACKAGE(rid), p->getAssignedId());
#endif
                }
            }
        }
    }
    return NO_ERROR;
}


void
ResourceTable::addLocalization(const String16& name, const String8& locale)
{
    mLocalizations[name].insert(locale);
}


/*!
 * Flag various sorts of localization problems.  '+' indicates checks already implemented;
 * '-' indicates checks that will be implemented in the future.
 *
 * + A localized string for which no default-locale version exists => warning
 * + A string for which no version in an explicitly-requested locale exists => warning
 * + A localized translation of an translateable="false" string => warning
 * - A localized string not provided in every locale used by the table
 */
status_t
ResourceTable::validateLocalizations(void)
{
    status_t err = NO_ERROR;
    const String8 defaultLocale;

    // For all strings...
    for (map<String16, set<String8> >::iterator nameIter = mLocalizations.begin();
         nameIter != mLocalizations.end();
         nameIter++) {
        const set<String8>& configSet = nameIter->second;   // naming convenience

        // Look for strings with no default localization
        if (configSet.count(defaultLocale) == 0) {
            fprintf(stdout, "aapt: warning: string '%s' has no default translation in %s; found:",
                    String8(nameIter->first).string(), mBundle->getResourceSourceDirs()[0]);
            for (set<String8>::iterator locales = configSet.begin();
                 locales != configSet.end();
                 locales++) {
                fprintf(stdout, " %s", (*locales).string());
            }
            fprintf(stdout, "\n");
            // !!! TODO: throw an error here in some circumstances
        }

        // Check that all requested localizations are present for this string
        if (mBundle->getConfigurations() != NULL && mBundle->getRequireLocalization()) {
            const char* allConfigs = mBundle->getConfigurations();
            const char* start = allConfigs;
            const char* comma;
            
            do {
                String8 config;
                comma = strchr(start, ',');
                if (comma != NULL) {
                    config.setTo(start, comma - start);
                    start = comma + 1;
                } else {
                    config.setTo(start);
                }

                // don't bother with the pseudolocale "zz_ZZ"
                if (config != "zz_ZZ") {
                    if (configSet.find(config) == configSet.end()) {
                        // okay, no specific localization found.  it's possible that we are
                        // requiring a specific regional localization [e.g. de_DE] but there is an
                        // available string in the generic language localization [e.g. de];
                        // consider that string to have fulfilled the localization requirement.
                        String8 region(config.string(), 2);
                        if (configSet.find(region) == configSet.end()) {
                            if (configSet.count(defaultLocale) == 0) {
                                fprintf(stdout, "aapt: warning: "
                                        "**** string '%s' has no default or required localization "
                                        "for '%s' in %s\n",
                                        String8(nameIter->first).string(),
                                        config.string(),
                                        mBundle->getResourceSourceDirs()[0]);
                            }
                        }
                    }
                }
           } while (comma != NULL);
        }
    }

    return err;
}


status_t
ResourceFilter::parse(const char* arg)
{
    if (arg == NULL) {
        return 0;
    }

    const char* p = arg;
    const char* q;

    while (true) {
        q = strchr(p, ',');
        if (q == NULL) {
            q = p + strlen(p);
        }

        String8 part(p, q-p);

        if (part == "zz_ZZ") {
            mContainsPseudo = true;
        }
        int axis;
        uint32_t value;
        if (AaptGroupEntry::parseNamePart(part, &axis, &value)) {
            fprintf(stderr, "Invalid configuration: %s\n", arg);
            fprintf(stderr, "                       ");
            for (int i=0; i<p-arg; i++) {
                fprintf(stderr, " ");
            }
            for (int i=0; i<q-p; i++) {
                fprintf(stderr, "^");
            }
            fprintf(stderr, "\n");
            return 1;
        }

        ssize_t index = mData.indexOfKey(axis);
        if (index < 0) {
            mData.add(axis, SortedVector<uint32_t>());
        }
        SortedVector<uint32_t>& sv = mData.editValueFor(axis);
        sv.add(value);
        // if it's a locale with a region, also match an unmodified locale of the
        // same language
        if (axis == AXIS_LANGUAGE) {
            if (value & 0xffff0000) {
                sv.add(value & 0x0000ffff);
            }
        }
        p = q;
        if (!*p) break;
        p++;
    }

    return NO_ERROR;
}

bool
ResourceFilter::match(int axis, uint32_t value)
{
    if (value == 0) {
        // they didn't specify anything so take everything
        return true;
    }
    ssize_t index = mData.indexOfKey(axis);
    if (index < 0) {
        // we didn't request anything on this axis so take everything
        return true;
    }
    const SortedVector<uint32_t>& sv = mData.valueAt(index);
    return sv.indexOf(value) >= 0;
}

bool
ResourceFilter::match(const ResTable_config& config)
{
    if (config.locale) {
        uint32_t locale = (config.country[1] << 24) | (config.country[0] << 16)
                | (config.language[1] << 8) | (config.language[0]);
        if (!match(AXIS_LANGUAGE, locale)) {
            return false;
        }
    }
    if (!match(AXIS_ORIENTATION, config.orientation)) {
        return false;
    }
    if (!match(AXIS_UIMODETYPE, (config.uiMode&ResTable_config::MASK_UI_MODE_TYPE))) {
        return false;
    }
    if (!match(AXIS_UIMODENIGHT, (config.uiMode&ResTable_config::MASK_UI_MODE_NIGHT))) {
        return false;
    }
    if (!match(AXIS_DENSITY, config.density)) {
        return false;
    }
    if (!match(AXIS_TOUCHSCREEN, config.touchscreen)) {
        return false;
    }
    if (!match(AXIS_KEYSHIDDEN, config.inputFlags)) {
        return false;
    }
    if (!match(AXIS_KEYBOARD, config.keyboard)) {
        return false;
    }
    if (!match(AXIS_NAVIGATION, config.navigation)) {
        return false;
    }
    if (!match(AXIS_SCREENSIZE, config.screenSize)) {
        return false;
    }
    if (!match(AXIS_VERSION, config.version)) {
        return false;
    }
    return true;
}

status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest)
{
    ResourceFilter filter;
    status_t err = filter.parse(bundle->getConfigurations());
    if (err != NO_ERROR) {
        return err;
    }

    const size_t N = mOrderedPackages.size();
    size_t pi;

    bool useUTF8 = !bundle->getWantUTF16() && bundle->isMinSdkAtLeast(SDK_FROYO);

    // Iterate through all data, collecting all values (strings,
    // references, etc).
    StringPool valueStrings = StringPool(false, useUTF8);
    for (pi=0; pi<N; pi++) {
        sp<Package> p = mOrderedPackages.itemAt(pi);
        if (p->getTypes().size() == 0) {
            // Empty, skip!
            continue;
        }

        StringPool typeStrings = StringPool(false, useUTF8);
        StringPool keyStrings = StringPool(false, useUTF8);

        const size_t N = p->getOrderedTypes().size();
        for (size_t ti=0; ti<N; ti++) {
            sp<Type> t = p->getOrderedTypes().itemAt(ti);
            if (t == NULL) {
                typeStrings.add(String16("<empty>"), false);
                continue;
            }
            typeStrings.add(t->getName(), false);

            const size_t N = t->getOrderedConfigs().size();
            for (size_t ci=0; ci<N; ci++) {
                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);
                if (c == NULL) {
                    continue;
                }
                const size_t N = c->getEntries().size();
                for (size_t ei=0; ei<N; ei++) {
                    ConfigDescription config = c->getEntries().keyAt(ei);
                    if (!filter.match(config)) {
                        continue;
                    }
                    sp<Entry> e = c->getEntries().valueAt(ei);
                    if (e == NULL) {
                        continue;
                    }
                    e->setNameIndex(keyStrings.add(e->getName(), true));
                    status_t err = e->prepareFlatten(&valueStrings, this);
                    if (err != NO_ERROR) {
                        return err;
                    }
                }
            }
        }

        p->setTypeStrings(typeStrings.createStringBlock());
        p->setKeyStrings(keyStrings.createStringBlock());
    }

    ssize_t strAmt = 0;
    
    // Now build the array of package chunks.
    Vector<sp<AaptFile> > flatPackages;
    for (pi=0; pi<N; pi++) {
        sp<Package> p = mOrderedPackages.itemAt(pi);
        if (p->getTypes().size() == 0) {
            // Empty, skip!
            continue;
        }

        const size_t N = p->getTypeStrings().size();

        const size_t baseSize = sizeof(ResTable_package);

        // Start the package data.
        sp<AaptFile> data = new AaptFile(String8(), AaptGroupEntry(), String8());
        ResTable_package* header = (ResTable_package*)data->editData(baseSize);
        if (header == NULL) {
            fprintf(stderr, "ERROR: out of memory creating ResTable_package\n");
            return NO_MEMORY;
        }
        memset(header, 0, sizeof(*header));
        header->header.type = htods(RES_TABLE_PACKAGE_TYPE);
        header->header.headerSize = htods(sizeof(*header));
        header->id = htodl(p->getAssignedId());
        strcpy16_htod(header->name, p->getName().string());

        // Write the string blocks.
        const size_t typeStringsStart = data->getSize();
        sp<AaptFile> strFile = p->getTypeStringsData();
        ssize_t amt = data->writeData(strFile->getData(), strFile->getSize());
        #if PRINT_STRING_METRICS
        fprintf(stderr, "**** type strings: %d\n", amt);
        #endif
        strAmt += amt;
        if (amt < 0) {
            return amt;
        }
        const size_t keyStringsStart = data->getSize();
        strFile = p->getKeyStringsData();
        amt = data->writeData(strFile->getData(), strFile->getSize());
        #if PRINT_STRING_METRICS
        fprintf(stderr, "**** key strings: %d\n", amt);
        #endif
        strAmt += amt;
        if (amt < 0) {
            return amt;
        }

        // Build the type chunks inside of this package.
        for (size_t ti=0; ti<N; ti++) {
            // Retrieve them in the same order as the type string block.
            size_t len;
            String16 typeName(p->getTypeStrings().stringAt(ti, &len));
            sp<Type> t = p->getTypes().valueFor(typeName);
            LOG_ALWAYS_FATAL_IF(t == NULL && typeName != String16("<empty>"),
                                "Type name %s not found",
                                String8(typeName).string());

            const size_t N = t != NULL ? t->getOrderedConfigs().size() : 0;
            
            // First write the typeSpec chunk, containing information about
            // each resource entry in this type.
            {
                const size_t typeSpecSize = sizeof(ResTable_typeSpec) + sizeof(uint32_t)*N;
                const size_t typeSpecStart = data->getSize();
                ResTable_typeSpec* tsHeader = (ResTable_typeSpec*)
                    (((uint8_t*)data->editData(typeSpecStart+typeSpecSize)) + typeSpecStart);
                if (tsHeader == NULL) {
                    fprintf(stderr, "ERROR: out of memory creating ResTable_typeSpec\n");
                    return NO_MEMORY;
                }
                memset(tsHeader, 0, sizeof(*tsHeader));
                tsHeader->header.type = htods(RES_TABLE_TYPE_SPEC_TYPE);
                tsHeader->header.headerSize = htods(sizeof(*tsHeader));
                tsHeader->header.size = htodl(typeSpecSize);
                tsHeader->id = ti+1;
                tsHeader->entryCount = htodl(N);
                
                uint32_t* typeSpecFlags = (uint32_t*)
                    (((uint8_t*)data->editData())
                        + typeSpecStart + sizeof(ResTable_typeSpec));
                memset(typeSpecFlags, 0, sizeof(uint32_t)*N);
                        
                for (size_t ei=0; ei<N; ei++) {
                    sp<ConfigList> cl = t->getOrderedConfigs().itemAt(ei);
                    if (cl->getPublic()) {
                        typeSpecFlags[ei] |= htodl(ResTable_typeSpec::SPEC_PUBLIC);
                    }
                    const size_t CN = cl->getEntries().size();
                    for (size_t ci=0; ci<CN; ci++) {
                        if (!filter.match(cl->getEntries().keyAt(ci))) {
                            continue;
                        }
                        for (size_t cj=ci+1; cj<CN; cj++) {
                            if (!filter.match(cl->getEntries().keyAt(cj))) {
                                continue;
                            }
                            typeSpecFlags[ei] |= htodl(
                                cl->getEntries().keyAt(ci).diff(cl->getEntries().keyAt(cj)));
                        }
                    }
                }
            }
            
            // We need to write one type chunk for each configuration for
            // which we have entries in this type.
            const size_t NC = t->getUniqueConfigs().size();
            
            const size_t typeSize = sizeof(ResTable_type) + sizeof(uint32_t)*N;
            
            for (size_t ci=0; ci<NC; ci++) {
                ConfigDescription config = t->getUniqueConfigs().itemAt(ci);

                NOISY(printf("Writing config %d config: imsi:%d/%d lang:%c%c cnt:%c%c "
                     "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n",
                      ti+1,
                      config.mcc, config.mnc,
                      config.language[0] ? config.language[0] : '-',
                      config.language[1] ? config.language[1] : '-',
                      config.country[0] ? config.country[0] : '-',
                      config.country[1] ? config.country[1] : '-',
                      config.orientation,
                      config.uiMode,
                      config.touchscreen,
                      config.density,
                      config.keyboard,
                      config.inputFlags,
                      config.navigation,
                      config.screenWidth,
                      config.screenHeight));
                      
                if (!filter.match(config)) {
                    continue;
                }
                
                const size_t typeStart = data->getSize();

                ResTable_type* tHeader = (ResTable_type*)
                    (((uint8_t*)data->editData(typeStart+typeSize)) + typeStart);
                if (tHeader == NULL) {
                    fprintf(stderr, "ERROR: out of memory creating ResTable_type\n");
                    return NO_MEMORY;
                }

                memset(tHeader, 0, sizeof(*tHeader));
                tHeader->header.type = htods(RES_TABLE_TYPE_TYPE);
                tHeader->header.headerSize = htods(sizeof(*tHeader));
                tHeader->id = ti+1;
                tHeader->entryCount = htodl(N);
                tHeader->entriesStart = htodl(typeSize);
                tHeader->config = config;
                NOISY(printf("Writing type %d config: imsi:%d/%d lang:%c%c cnt:%c%c "
                     "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n",
                      ti+1,
                      tHeader->config.mcc, tHeader->config.mnc,
                      tHeader->config.language[0] ? tHeader->config.language[0] : '-',
                      tHeader->config.language[1] ? tHeader->config.language[1] : '-',
                      tHeader->config.country[0] ? tHeader->config.country[0] : '-',
                      tHeader->config.country[1] ? tHeader->config.country[1] : '-',
                      tHeader->config.orientation,
                      tHeader->config.uiMode,
                      tHeader->config.touchscreen,
                      tHeader->config.density,
                      tHeader->config.keyboard,
                      tHeader->config.inputFlags,
                      tHeader->config.navigation,
                      tHeader->config.screenWidth,
                      tHeader->config.screenHeight));
                tHeader->config.swapHtoD();

                // Build the entries inside of this type.
                for (size_t ei=0; ei<N; ei++) {
                    sp<ConfigList> cl = t->getOrderedConfigs().itemAt(ei);
                    sp<Entry> e = cl->getEntries().valueFor(config);

                    // Set the offset for this entry in its type.
                    uint32_t* index = (uint32_t*)
                        (((uint8_t*)data->editData())
                            + typeStart + sizeof(ResTable_type));
                    if (e != NULL) {
                        index[ei] = htodl(data->getSize()-typeStart-typeSize);

                        // Create the entry.
                        ssize_t amt = e->flatten(bundle, data, cl->getPublic());
                        if (amt < 0) {
                            return amt;
                        }
                    } else {
                        index[ei] = htodl(ResTable_type::NO_ENTRY);
                    }
                }

                // Fill in the rest of the type information.
                tHeader = (ResTable_type*)
                    (((uint8_t*)data->editData()) + typeStart);
                tHeader->header.size = htodl(data->getSize()-typeStart);
            }
        }

        // Fill in the rest of the package information.
        header = (ResTable_package*)data->editData();
        header->header.size = htodl(data->getSize());
        header->typeStrings = htodl(typeStringsStart);
        header->lastPublicType = htodl(p->getTypeStrings().size());
        header->keyStrings = htodl(keyStringsStart);
        header->lastPublicKey = htodl(p->getKeyStrings().size());

        flatPackages.add(data);
    }

    // And now write out the final chunks.
    const size_t dataStart = dest->getSize();

    {
        // blah
        ResTable_header header;
        memset(&header, 0, sizeof(header));
        header.header.type = htods(RES_TABLE_TYPE);
        header.header.headerSize = htods(sizeof(header));
        header.packageCount = htodl(flatPackages.size());
        status_t err = dest->writeData(&header, sizeof(header));
        if (err != NO_ERROR) {
            fprintf(stderr, "ERROR: out of memory creating ResTable_header\n");
            return err;
        }
    }
    
    ssize_t strStart = dest->getSize();
    err = valueStrings.writeStringBlock(dest);
    if (err != NO_ERROR) {
        return err;
    }

    ssize_t amt = (dest->getSize()-strStart);
    strAmt += amt;
    #if PRINT_STRING_METRICS
    fprintf(stderr, "**** value strings: %d\n", amt);
    fprintf(stderr, "**** total strings: %d\n", strAmt);
    #endif
    
    for (pi=0; pi<flatPackages.size(); pi++) {
        err = dest->writeData(flatPackages[pi]->getData(),
                              flatPackages[pi]->getSize());
        if (err != NO_ERROR) {
            fprintf(stderr, "ERROR: out of memory creating package chunk for ResTable_header\n");
            return err;
        }
    }

    ResTable_header* header = (ResTable_header*)
        (((uint8_t*)dest->getData()) + dataStart);
    header->header.size = htodl(dest->getSize() - dataStart);

    NOISY(aout << "Resource table:"
          << HexDump(dest->getData(), dest->getSize()) << endl);

    #if PRINT_STRING_METRICS
    fprintf(stderr, "**** total resource table size: %d / %d%% strings\n",
        dest->getSize(), (strAmt*100)/dest->getSize());
    #endif
    
    return NO_ERROR;
}

void ResourceTable::writePublicDefinitions(const String16& package, FILE* fp)
{
    fprintf(fp,
    "<!-- This file contains <public> resource definitions for all\n"
    "     resources that were generated from the source data. -->\n"
    "\n"
    "<resources>\n");

    writePublicDefinitions(package, fp, true);
    writePublicDefinitions(package, fp, false);

    fprintf(fp,
    "\n"
    "</resources>\n");
}

void ResourceTable::writePublicDefinitions(const String16& package, FILE* fp, bool pub)
{
    bool didHeader = false;

    sp<Package> pkg = mPackages.valueFor(package);
    if (pkg != NULL) {
        const size_t NT = pkg->getOrderedTypes().size();
        for (size_t i=0; i<NT; i++) {
            sp<Type> t = pkg->getOrderedTypes().itemAt(i);
            if (t == NULL) {
                continue;
            }

            bool didType = false;

            const size_t NC = t->getOrderedConfigs().size();
            for (size_t j=0; j<NC; j++) {
                sp<ConfigList> c = t->getOrderedConfigs().itemAt(j);
                if (c == NULL) {
                    continue;
                }

                if (c->getPublic() != pub) {
                    continue;
                }

                if (!didType) {
                    fprintf(fp, "\n");
                    didType = true;
                }
                if (!didHeader) {
                    if (pub) {
                        fprintf(fp,"  <!-- PUBLIC SECTION.  These resources have been declared public.\n");
                        fprintf(fp,"       Changes to these definitions will break binary compatibility. -->\n\n");
                    } else {
                        fprintf(fp,"  <!-- PRIVATE SECTION.  These resources have not been declared public.\n");
                        fprintf(fp,"       You can make them public my moving these lines into a file in res/values. -->\n\n");
                    }
                    didHeader = true;
                }
                if (!pub) {
                    const size_t NE = c->getEntries().size();
                    for (size_t k=0; k<NE; k++) {
                        const SourcePos& pos = c->getEntries().valueAt(k)->getPos();
                        if (pos.file != "") {
                            fprintf(fp,"  <!-- Declared at %s:%d -->\n",
                                    pos.file.string(), pos.line);
                        }
                    }
                }
                fprintf(fp, "  <public type=\"%s\" name=\"%s\" id=\"0x%08x\" />\n",
                        String8(t->getName()).string(),
                        String8(c->getName()).string(),
                        getResId(pkg, t, c->getEntryIndex()));
            }
        }
    }
}

ResourceTable::Item::Item(const SourcePos& _sourcePos,
                          bool _isId,
                          const String16& _value,
                          const Vector<StringPool::entry_style_span>* _style,
                          int32_t _format)
    : sourcePos(_sourcePos)
    , isId(_isId)
    , value(_value)
    , format(_format)
    , bagKeyId(0)
    , evaluating(false)
{
    if (_style) {
        style = *_style;
    }
}

status_t ResourceTable::Entry::makeItABag(const SourcePos& sourcePos)
{
    if (mType == TYPE_BAG) {
        return NO_ERROR;
    }
    if (mType == TYPE_UNKNOWN) {
        mType = TYPE_BAG;
        return NO_ERROR;
    }
    sourcePos.error("Resource entry %s is already defined as a single item.\n"
                    "%s:%d: Originally defined here.\n",
                    String8(mName).string(),
                    mItem.sourcePos.file.string(), mItem.sourcePos.line);
    return UNKNOWN_ERROR;
}

status_t ResourceTable::Entry::setItem(const SourcePos& sourcePos,
                                       const String16& value,
                                       const Vector<StringPool::entry_style_span>* style,
                                       int32_t format,
                                       const bool overwrite)
{
    Item item(sourcePos, false, value, style);

    if (mType == TYPE_BAG) {
        const Item& item(mBag.valueAt(0));
        sourcePos.error("Resource entry %s is already defined as a bag.\n"
                        "%s:%d: Originally defined here.\n",
                        String8(mName).string(),
                        item.sourcePos.file.string(), item.sourcePos.line);
        return UNKNOWN_ERROR;
    }
    if ( (mType != TYPE_UNKNOWN) && (overwrite == false) ) {
        sourcePos.error("Resource entry %s is already defined.\n"
                        "%s:%d: Originally defined here.\n",
                        String8(mName).string(),
                        mItem.sourcePos.file.string(), mItem.sourcePos.line);
        return UNKNOWN_ERROR;
    }

    mType = TYPE_ITEM;
    mItem = item;
    mItemFormat = format;
    return NO_ERROR;
}

status_t ResourceTable::Entry::addToBag(const SourcePos& sourcePos,
                                        const String16& key, const String16& value,
                                        const Vector<StringPool::entry_style_span>* style,
                                        bool replace, bool isId, int32_t format)
{
    status_t err = makeItABag(sourcePos);
    if (err != NO_ERROR) {
        return err;
    }

    Item item(sourcePos, isId, value, style, format);
    
    // XXX NOTE: there is an error if you try to have a bag with two keys,
    // one an attr and one an id, with the same name.  Not something we
    // currently ever have to worry about.
    ssize_t origKey = mBag.indexOfKey(key);
    if (origKey >= 0) {
        if (!replace) {
            const Item& item(mBag.valueAt(origKey));
            sourcePos.error("Resource entry %s already has bag item %s.\n"
                    "%s:%d: Originally defined here.\n",
                    String8(mName).string(), String8(key).string(),
                    item.sourcePos.file.string(), item.sourcePos.line);
            return UNKNOWN_ERROR;
        }
        //printf("Replacing %s with %s\n",
        //       String8(mBag.valueFor(key).value).string(), String8(value).string());
        mBag.replaceValueFor(key, item);
    }

    mBag.add(key, item);
    return NO_ERROR;
}

status_t ResourceTable::Entry::emptyBag(const SourcePos& sourcePos)
{
    status_t err = makeItABag(sourcePos);
    if (err != NO_ERROR) {
        return err;
    }

    mBag.clear();
    return NO_ERROR;
}

status_t ResourceTable::Entry::generateAttributes(ResourceTable* table,
                                                  const String16& package)
{
    const String16 attr16("attr");
    const String16 id16("id");
    const size_t N = mBag.size();
    for (size_t i=0; i<N; i++) {
        const String16& key = mBag.keyAt(i);
        const Item& it = mBag.valueAt(i);
        if (it.isId) {
            if (!table->hasBagOrEntry(key, &id16, &package)) {
                String16 value("false");
                status_t err = table->addEntry(SourcePos(String8("<generated>"), 0), package,
                                               id16, key, value);
                if (err != NO_ERROR) {
                    return err;
                }
            }
        } else if (!table->hasBagOrEntry(key, &attr16, &package)) {

#if 1
//             fprintf(stderr, "ERROR: Bag attribute '%s' has not been defined.\n",
//                     String8(key).string());
//             const Item& item(mBag.valueAt(i));
//             fprintf(stderr, "Referenced from file %s line %d\n",
//                     item.sourcePos.file.string(), item.sourcePos.line);
//             return UNKNOWN_ERROR;
#else
            char numberStr[16];
            sprintf(numberStr, "%d", ResTable_map::TYPE_ANY);
            status_t err = table->addBag(SourcePos("<generated>", 0), package,
                                         attr16, key, String16(""),
                                         String16("^type"),
                                         String16(numberStr), NULL, NULL);
            if (err != NO_ERROR) {
                return err;
            }
#endif
        }
    }
    return NO_ERROR;
}

status_t ResourceTable::Entry::assignResourceIds(ResourceTable* table,
                                                 const String16& package)
{
    bool hasErrors = false;
    
    if (mType == TYPE_BAG) {
        const char* errorMsg;
        const String16 style16("style");
        const String16 attr16("attr");
        const String16 id16("id");
        mParentId = 0;
        if (mParent.size() > 0) {
            mParentId = table->getResId(mParent, &style16, NULL, &errorMsg);
            if (mParentId == 0) {
                mPos.error("Error retrieving parent for item: %s '%s'.\n",
                        errorMsg, String8(mParent).string());
                hasErrors = true;
            }
        }
        const size_t N = mBag.size();
        for (size_t i=0; i<N; i++) {
            const String16& key = mBag.keyAt(i);
            Item& it = mBag.editValueAt(i);
            it.bagKeyId = table->getResId(key,
                    it.isId ? &id16 : &attr16, NULL, &errorMsg);
            //printf("Bag key of %s: #%08x\n", String8(key).string(), it.bagKeyId);
            if (it.bagKeyId == 0) {
                it.sourcePos.error("Error: %s: %s '%s'.\n", errorMsg,
                        String8(it.isId ? id16 : attr16).string(),
                        String8(key).string());
                hasErrors = true;
            }
        }
    }
    return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
}

status_t ResourceTable::Entry::prepareFlatten(StringPool* strings, ResourceTable* table)
{
    if (mType == TYPE_ITEM) {
        Item& it = mItem;
        AccessorCookie ac(it.sourcePos, String8(mName), String8(it.value));
        if (!table->stringToValue(&it.parsedValue, strings,
                                  it.value, false, true, 0,
                                  &it.style, NULL, &ac, mItemFormat)) {
            return UNKNOWN_ERROR;
        }
    } else if (mType == TYPE_BAG) {
        const size_t N = mBag.size();
        for (size_t i=0; i<N; i++) {
            const String16& key = mBag.keyAt(i);
            Item& it = mBag.editValueAt(i);
            AccessorCookie ac(it.sourcePos, String8(key), String8(it.value));
            if (!table->stringToValue(&it.parsedValue, strings,
                                      it.value, false, true, it.bagKeyId,
                                      &it.style, NULL, &ac, it.format)) {
                return UNKNOWN_ERROR;
            }
        }
    } else {
        mPos.error("Error: entry %s is not a single item or a bag.\n",
                   String8(mName).string());
        return UNKNOWN_ERROR;
    }
    return NO_ERROR;
}

ssize_t ResourceTable::Entry::flatten(Bundle* bundle, const sp<AaptFile>& data, bool isPublic)
{
    size_t amt = 0;
    ResTable_entry header;
    memset(&header, 0, sizeof(header));
    header.size = htods(sizeof(header));
    const type ty = this != NULL ? mType : TYPE_ITEM;
    if (this != NULL) {
        if (ty == TYPE_BAG) {
            header.flags |= htods(header.FLAG_COMPLEX);
        }
        if (isPublic) {
            header.flags |= htods(header.FLAG_PUBLIC);
        }
        header.key.index = htodl(mNameIndex);
    }
    if (ty != TYPE_BAG) {
        status_t err = data->writeData(&header, sizeof(header));
        if (err != NO_ERROR) {
            fprintf(stderr, "ERROR: out of memory creating ResTable_entry\n");
            return err;
        }

        const Item& it = mItem;
        Res_value par;
        memset(&par, 0, sizeof(par));
        par.size = htods(it.parsedValue.size);
        par.dataType = it.parsedValue.dataType;
        par.res0 = it.parsedValue.res0;
        par.data = htodl(it.parsedValue.data);
        #if 0
        printf("Writing item (%s): type=%d, data=0x%x, res0=0x%x\n",
               String8(mName).string(), it.parsedValue.dataType,
               it.parsedValue.data, par.res0);
        #endif
        err = data->writeData(&par, it.parsedValue.size);
        if (err != NO_ERROR) {
            fprintf(stderr, "ERROR: out of memory creating Res_value\n");
            return err;
        }
        amt += it.parsedValue.size;
    } else {
        size_t N = mBag.size();
        size_t i;
        // Create correct ordering of items.
        KeyedVector<uint32_t, const Item*> items;
        for (i=0; i<N; i++) {
            const Item& it = mBag.valueAt(i);
            items.add(it.bagKeyId, &it);
        }
        N = items.size();
        
        ResTable_map_entry mapHeader;
        memcpy(&mapHeader, &header, sizeof(header));
        mapHeader.size = htods(sizeof(mapHeader));
        mapHeader.parent.ident = htodl(mParentId);
        mapHeader.count = htodl(N);
        status_t err = data->writeData(&mapHeader, sizeof(mapHeader));
        if (err != NO_ERROR) {
            fprintf(stderr, "ERROR: out of memory creating ResTable_entry\n");
            return err;
        }

        for (i=0; i<N; i++) {
            const Item& it = *items.valueAt(i);
            ResTable_map map;
            map.name.ident = htodl(it.bagKeyId);
            map.value.size = htods(it.parsedValue.size);
            map.value.dataType = it.parsedValue.dataType;
            map.value.res0 = it.parsedValue.res0;
            map.value.data = htodl(it.parsedValue.data);
            err = data->writeData(&map, sizeof(map));
            if (err != NO_ERROR) {
                fprintf(stderr, "ERROR: out of memory creating Res_value\n");
                return err;
            }
            amt += sizeof(map);
        }
    }
    return amt;
}

void ResourceTable::ConfigList::appendComment(const String16& comment,
                                              bool onlyIfEmpty)
{
    if (comment.size() <= 0) {
        return;
    }
    if (onlyIfEmpty && mComment.size() > 0) {
        return;
    }
    if (mComment.size() > 0) {
        mComment.append(String16("\n"));
    }
    mComment.append(comment);
}

void ResourceTable::ConfigList::appendTypeComment(const String16& comment)
{
    if (comment.size() <= 0) {
        return;
    }
    if (mTypeComment.size() > 0) {
        mTypeComment.append(String16("\n"));
    }
    mTypeComment.append(comment);
}

status_t ResourceTable::Type::addPublic(const SourcePos& sourcePos,
                                        const String16& name,
                                        const uint32_t ident)
{
    #if 0
    int32_t entryIdx = Res_GETENTRY(ident);
    if (entryIdx < 0) {
        sourcePos.error("Public resource %s/%s has an invalid 0 identifier (0x%08x).\n",
                String8(mName).string(), String8(name).string(), ident);
        return UNKNOWN_ERROR;
    }
    #endif

    int32_t typeIdx = Res_GETTYPE(ident);
    if (typeIdx >= 0) {
        typeIdx++;
        if (mPublicIndex > 0 && mPublicIndex != typeIdx) {
            sourcePos.error("Public resource %s/%s has conflicting type codes for its"
                    " public identifiers (0x%x vs 0x%x).\n",
                    String8(mName).string(), String8(name).string(),
                    mPublicIndex, typeIdx);
            return UNKNOWN_ERROR;
        }
        mPublicIndex = typeIdx;
    }

    if (mFirstPublicSourcePos == NULL) {
        mFirstPublicSourcePos = new SourcePos(sourcePos);
    }

    if (mPublic.indexOfKey(name) < 0) {
        mPublic.add(name, Public(sourcePos, String16(), ident));
    } else {
        Public& p = mPublic.editValueFor(name);
        if (p.ident != ident) {
            sourcePos.error("Public resource %s/%s has conflicting public identifiers"
                    " (0x%08x vs 0x%08x).\n"
                    "%s:%d: Originally defined here.\n",
                    String8(mName).string(), String8(name).string(), p.ident, ident,
                    p.sourcePos.file.string(), p.sourcePos.line);
            return UNKNOWN_ERROR;
        }
    }

    return NO_ERROR;
}

void ResourceTable::Type::canAddEntry(const String16& name)
{
    mCanAddEntries.add(name);
}

sp<ResourceTable::Entry> ResourceTable::Type::getEntry(const String16& entry,
                                                       const SourcePos& sourcePos,
                                                       const ResTable_config* config,
                                                       bool doSetIndex,
                                                       bool overlay,
                                                       bool autoAddOverlay)
{
    int pos = -1;
    sp<ConfigList> c = mConfigs.valueFor(entry);
    if (c == NULL) {
        if (overlay && !autoAddOverlay && mCanAddEntries.indexOf(entry) < 0) {
            sourcePos.error("Resource at %s appears in overlay but not"
                            " in the base package; use <add-resource> to add.\n",
                            String8(entry).string());
            return NULL;
        }
        c = new ConfigList(entry, sourcePos);
        mConfigs.add(entry, c);
        pos = (int)mOrderedConfigs.size();
        mOrderedConfigs.add(c);
        if (doSetIndex) {
            c->setEntryIndex(pos);
        }
    }
    
    ConfigDescription cdesc;
    if (config) cdesc = *config;
    
    sp<Entry> e = c->getEntries().valueFor(cdesc);
    if (e == NULL) {
        if (config != NULL) {
            NOISY(printf("New entry at %s:%d: imsi:%d/%d lang:%c%c cnt:%c%c "
                    "orien:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n",
                      sourcePos.file.string(), sourcePos.line,
                      config->mcc, config->mnc,
                      config->language[0] ? config->language[0] : '-',
                      config->language[1] ? config->language[1] : '-',
                      config->country[0] ? config->country[0] : '-',
                      config->country[1] ? config->country[1] : '-',
                      config->orientation,
                      config->touchscreen,
                      config->density,
                      config->keyboard,
                      config->inputFlags,
                      config->navigation,
                      config->screenWidth,
                      config->screenHeight));
        } else {
            NOISY(printf("New entry at %s:%d: NULL config\n",
                      sourcePos.file.string(), sourcePos.line));
        }
        e = new Entry(entry, sourcePos);
        c->addEntry(cdesc, e);
        /*
        if (doSetIndex) {
            if (pos < 0) {
                for (pos=0; pos<(int)mOrderedConfigs.size(); pos++) {
                    if (mOrderedConfigs[pos] == c) {
                        break;
                    }
                }
                if (pos >= (int)mOrderedConfigs.size()) {
                    sourcePos.error("Internal error: config not found in mOrderedConfigs when adding entry");
                    return NULL;
                }
            }
            e->setEntryIndex(pos);
        }
        */
    }
    
    mUniqueConfigs.add(cdesc);
    
    return e;
}

status_t ResourceTable::Type::applyPublicEntryOrder()
{
    size_t N = mOrderedConfigs.size();
    Vector<sp<ConfigList> > origOrder(mOrderedConfigs);
    bool hasError = false;

    size_t i;
    for (i=0; i<N; i++) {
        mOrderedConfigs.replaceAt(NULL, i);
    }

    const size_t NP = mPublic.size();
    //printf("Ordering %d configs from %d public defs\n", N, NP);
    size_t j;
    for (j=0; j<NP; j++) {
        const String16& name = mPublic.keyAt(j);
        const Public& p = mPublic.valueAt(j);
        int32_t idx = Res_GETENTRY(p.ident);
        //printf("Looking for entry \"%s\"/\"%s\" (0x%08x) in %d...\n",
        //       String8(mName).string(), String8(name).string(), p.ident, N);
        bool found = false;
        for (i=0; i<N; i++) {
            sp<ConfigList> e = origOrder.itemAt(i);
            //printf("#%d: \"%s\"\n", i, String8(e->getName()).string());
            if (e->getName() == name) {
                if (idx >= (int32_t)mOrderedConfigs.size()) {
                    p.sourcePos.error("Public entry identifier 0x%x entry index "
                            "is larger than available symbols (index %d, total symbols %d).\n",
                            p.ident, idx, mOrderedConfigs.size());
                    hasError = true;
                } else if (mOrderedConfigs.itemAt(idx) == NULL) {
                    e->setPublic(true);
                    e->setPublicSourcePos(p.sourcePos);
                    mOrderedConfigs.replaceAt(e, idx);
                    origOrder.removeAt(i);
                    N--;
                    found = true;
                    break;
                } else {
                    sp<ConfigList> oe = mOrderedConfigs.itemAt(idx);

                    p.sourcePos.error("Multiple entry names declared for public entry"
                            " identifier 0x%x in type %s (%s vs %s).\n"
                            "%s:%d: Originally defined here.",
                            idx+1, String8(mName).string(),
                            String8(oe->getName()).string(),
                            String8(name).string(),
                            oe->getPublicSourcePos().file.string(),
                            oe->getPublicSourcePos().line);
                    hasError = true;
                }
            }
        }

        if (!found) {
            p.sourcePos.error("Public symbol %s/%s declared here is not defined.",
                    String8(mName).string(), String8(name).string());
            hasError = true;
        }
    }

    //printf("Copying back in %d non-public configs, have %d\n", N, origOrder.size());
    
    if (N != origOrder.size()) {
        printf("Internal error: remaining private symbol count mismatch\n");
        N = origOrder.size();
    }
    
    j = 0;
    for (i=0; i<N; i++) {
        sp<ConfigList> e = origOrder.itemAt(i);
        // There will always be enough room for the remaining entries.
        while (mOrderedConfigs.itemAt(j) != NULL) {
            j++;
        }
        mOrderedConfigs.replaceAt(e, j);
        j++;
    }

    return hasError ? UNKNOWN_ERROR : NO_ERROR;
}

ResourceTable::Package::Package(const String16& name, ssize_t includedId)
    : mName(name), mIncludedId(includedId),
      mTypeStringsMapping(0xffffffff),
      mKeyStringsMapping(0xffffffff)
{
}

sp<ResourceTable::Type> ResourceTable::Package::getType(const String16& type,
                                                        const SourcePos& sourcePos,
                                                        bool doSetIndex)
{
    sp<Type> t = mTypes.valueFor(type);
    if (t == NULL) {
        t = new Type(type, sourcePos);
        mTypes.add(type, t);
        mOrderedTypes.add(t);
        if (doSetIndex) {
            // For some reason the type's index is set to one plus the index
            // in the mOrderedTypes list, rather than just the index.
            t->setIndex(mOrderedTypes.size());
        }
    }
    return t;
}

status_t ResourceTable::Package::setTypeStrings(const sp<AaptFile>& data)
{
    mTypeStringsData = data;
    status_t err = setStrings(data, &mTypeStrings, &mTypeStringsMapping);
    if (err != NO_ERROR) {
        fprintf(stderr, "ERROR: Type string data is corrupt!\n");
    }
    return err;
}

status_t ResourceTable::Package::setKeyStrings(const sp<AaptFile>& data)
{
    mKeyStringsData = data;
    status_t err = setStrings(data, &mKeyStrings, &mKeyStringsMapping);
    if (err != NO_ERROR) {
        fprintf(stderr, "ERROR: Key string data is corrupt!\n");
    }
    return err;
}

status_t ResourceTable::Package::setStrings(const sp<AaptFile>& data,
                                            ResStringPool* strings,
                                            DefaultKeyedVector<String16, uint32_t>* mappings)
{
    if (data->getData() == NULL) {
        return UNKNOWN_ERROR;
    }

    NOISY(aout << "Setting restable string pool: "
          << HexDump(data->getData(), data->getSize()) << endl);

    status_t err = strings->setTo(data->getData(), data->getSize());
    if (err == NO_ERROR) {
        const size_t N = strings->size();
        for (size_t i=0; i<N; i++) {
            size_t len;
            mappings->add(String16(strings->stringAt(i, &len)), i);
        }
    }
    return err;
}

status_t ResourceTable::Package::applyPublicTypeOrder()
{
    size_t N = mOrderedTypes.size();
    Vector<sp<Type> > origOrder(mOrderedTypes);

    size_t i;
    for (i=0; i<N; i++) {
        mOrderedTypes.replaceAt(NULL, i);
    }

    for (i=0; i<N; i++) {
        sp<Type> t = origOrder.itemAt(i);
        int32_t idx = t->getPublicIndex();
        if (idx > 0) {
            idx--;
            while (idx >= (int32_t)mOrderedTypes.size()) {
                mOrderedTypes.add();
            }
            if (mOrderedTypes.itemAt(idx) != NULL) {
                sp<Type> ot = mOrderedTypes.itemAt(idx);
                t->getFirstPublicSourcePos().error("Multiple type names declared for public type"
                        " identifier 0x%x (%s vs %s).\n"
                        "%s:%d: Originally defined here.",
                        idx, String8(ot->getName()).string(),
                        String8(t->getName()).string(),
                        ot->getFirstPublicSourcePos().file.string(),
                        ot->getFirstPublicSourcePos().line);
                return UNKNOWN_ERROR;
            }
            mOrderedTypes.replaceAt(t, idx);
            origOrder.removeAt(i);
            i--;
            N--;
        }
    }

    size_t j=0;
    for (i=0; i<N; i++) {
        sp<Type> t = origOrder.itemAt(i);
        // There will always be enough room for the remaining types.
        while (mOrderedTypes.itemAt(j) != NULL) {
            j++;
        }
        mOrderedTypes.replaceAt(t, j);
    }

    return NO_ERROR;
}

sp<ResourceTable::Package> ResourceTable::getPackage(const String16& package)
{
    sp<Package> p = mPackages.valueFor(package);
    if (p == NULL) {
        if (mIsAppPackage) {
            if (mHaveAppPackage) {
                fprintf(stderr, "Adding multiple application package resources; only one is allowed.\n"
                                "Use -x to create extended resources.\n");
                return NULL;
            }
            mHaveAppPackage = true;
            p = new Package(package, 127);
        } else {
            p = new Package(package, mNextPackageId);
        }
        //printf("*** NEW PACKAGE: \"%s\" id=%d\n",
        //       String8(package).string(), p->getAssignedId());
        mPackages.add(package, p);
        mOrderedPackages.add(p);
        mNextPackageId++;
    }
    return p;
}

sp<ResourceTable::Type> ResourceTable::getType(const String16& package,
                                               const String16& type,
                                               const SourcePos& sourcePos,
                                               bool doSetIndex)
{
    sp<Package> p = getPackage(package);
    if (p == NULL) {
        return NULL;
    }
    return p->getType(type, sourcePos, doSetIndex);
}

sp<ResourceTable::Entry> ResourceTable::getEntry(const String16& package,
                                                 const String16& type,
                                                 const String16& name,
                                                 const SourcePos& sourcePos,
                                                 bool overlay,
                                                 const ResTable_config* config,
                                                 bool doSetIndex)
{
    sp<Type> t = getType(package, type, sourcePos, doSetIndex);
    if (t == NULL) {
        return NULL;
    }
    return t->getEntry(name, sourcePos, config, doSetIndex, overlay, mBundle->getAutoAddOverlay());
}

sp<const ResourceTable::Entry> ResourceTable::getEntry(uint32_t resID,
                                                       const ResTable_config* config) const
{
    int pid = Res_GETPACKAGE(resID)+1;
    const size_t N = mOrderedPackages.size();
    size_t i;
    sp<Package> p;
    for (i=0; i<N; i++) {
        sp<Package> check = mOrderedPackages[i];
        if (check->getAssignedId() == pid) {
            p = check;
            break;
        }

    }
    if (p == NULL) {
        fprintf(stderr, "warning: Package not found for resource #%08x\n", resID);
        return NULL;
    }

    int tid = Res_GETTYPE(resID);
    if (tid < 0 || tid >= (int)p->getOrderedTypes().size()) {
        fprintf(stderr, "warning: Type not found for resource #%08x\n", resID);
        return NULL;
    }
    sp<Type> t = p->getOrderedTypes()[tid];

    int eid = Res_GETENTRY(resID);
    if (eid < 0 || eid >= (int)t->getOrderedConfigs().size()) {
        fprintf(stderr, "warning: Entry not found for resource #%08x\n", resID);
        return NULL;
    }

    sp<ConfigList> c = t->getOrderedConfigs()[eid];
    if (c == NULL) {
        fprintf(stderr, "warning: Entry not found for resource #%08x\n", resID);
        return NULL;
    }
    
    ConfigDescription cdesc;
    if (config) cdesc = *config;
    sp<Entry> e = c->getEntries().valueFor(cdesc);
    if (c == NULL) {
        fprintf(stderr, "warning: Entry configuration not found for resource #%08x\n", resID);
        return NULL;
    }
    
    return e;
}

const ResourceTable::Item* ResourceTable::getItem(uint32_t resID, uint32_t attrID) const
{
    sp<const Entry> e = getEntry(resID);
    if (e == NULL) {
        return NULL;
    }

    const size_t N = e->getBag().size();
    for (size_t i=0; i<N; i++) {
        const Item& it = e->getBag().valueAt(i);
        if (it.bagKeyId == 0) {
            fprintf(stderr, "warning: ID not yet assigned to '%s' in bag '%s'\n",
                    String8(e->getName()).string(),
                    String8(e->getBag().keyAt(i)).string());
        }
        if (it.bagKeyId == attrID) {
            return &it;
        }
    }

    return NULL;
}

bool ResourceTable::getItemValue(
    uint32_t resID, uint32_t attrID, Res_value* outValue)
{
    const Item* item = getItem(resID, attrID);

    bool res = false;
    if (item != NULL) {
        if (item->evaluating) {
            sp<const Entry> e = getEntry(resID);
            const size_t N = e->getBag().size();
            size_t i;
            for (i=0; i<N; i++) {
                if (&e->getBag().valueAt(i) == item) {
                    break;
                }
            }
            fprintf(stderr, "warning: Circular reference detected in key '%s' of bag '%s'\n",
                    String8(e->getName()).string(),
                    String8(e->getBag().keyAt(i)).string());
            return false;
        }
        item->evaluating = true;
        res = stringToValue(outValue, NULL, item->value, false, false, item->bagKeyId);
        NOISY(
            if (res) {
                printf("getItemValue of #%08x[#%08x] (%s): type=#%08x, data=#%08x\n",
                       resID, attrID, String8(getEntry(resID)->getName()).string(),
                       outValue->dataType, outValue->data);
            } else {
                printf("getItemValue of #%08x[#%08x]: failed\n",
                       resID, attrID);
            }
        );
        item->evaluating = false;
    }
    return res;
}
