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

#include "XMLNode.h"
#include "ResourceTable.h"

#include <host/pseudolocalize.h>
#include <utils/ByteOrder.h>
#include <errno.h>
#include <string.h>

#ifndef HAVE_MS_C_RUNTIME
#define O_BINARY 0
#endif

#define NOISY(x) //x
#define NOISY_PARSE(x) //x

const char* const RESOURCES_ROOT_NAMESPACE = "http://schemas.android.com/apk/res/";
const char* const RESOURCES_ANDROID_NAMESPACE = "http://schemas.android.com/apk/res/android";
const char* const RESOURCES_ROOT_PRV_NAMESPACE = "http://schemas.android.com/apk/prv/res/";

const char* const XLIFF_XMLNS = "urn:oasis:names:tc:xliff:document:1.2";
const char* const ALLOWED_XLIFF_ELEMENTS[] = {
        "bpt",
        "ept",
        "it",
        "ph",
        "g",
        "bx",
        "ex",
        "x"
    };

bool isWhitespace(const char16_t* str)
{
    while (*str != 0 && *str < 128 && isspace(*str)) {
        str++;
    }
    return *str == 0;
}

static const String16 RESOURCES_PREFIX(RESOURCES_ROOT_NAMESPACE);
static const String16 RESOURCES_PRV_PREFIX(RESOURCES_ROOT_PRV_NAMESPACE);

String16 getNamespaceResourcePackage(String16 namespaceUri, bool* outIsPublic)
{
    //printf("%s starts with %s?\n", String8(namespaceUri).string(),
    //       String8(RESOURCES_PREFIX).string());
    size_t prefixSize;
    bool isPublic = true;
    if (namespaceUri.startsWith(RESOURCES_PREFIX)) {
        prefixSize = RESOURCES_PREFIX.size();
    } else if (namespaceUri.startsWith(RESOURCES_PRV_PREFIX)) {
        isPublic = false;
        prefixSize = RESOURCES_PRV_PREFIX.size();
    } else {
        if (outIsPublic) *outIsPublic = isPublic; // = true
        return String16();
    }

    //printf("YES!\n");
    //printf("namespace: %s\n", String8(String16(namespaceUri, namespaceUri.size()-prefixSize, prefixSize)).string());
    if (outIsPublic) *outIsPublic = isPublic;
    return String16(namespaceUri, namespaceUri.size()-prefixSize, prefixSize);
}

status_t hasSubstitutionErrors(const char* fileName,
                               ResXMLTree* inXml,
                               String16 str16)
{
    const char16_t* str = str16.string();
    const char16_t* p = str;
    const char16_t* end = str + str16.size();

    bool nonpositional = false;
    int argCount = 0;

    while (p < end) {
        /*
         * Look for the start of a Java-style substitution sequence.
         */
        if (*p == '%' && p + 1 < end) {
            p++;

            // A literal percent sign represented by %%
            if (*p == '%') {
                p++;
                continue;
            }

            argCount++;

            if (*p >= '0' && *p <= '9') {
                do {
                    p++;
                } while (*p >= '0' && *p <= '9');
                if (*p != '$') {
                    // This must be a size specification instead of position.
                    nonpositional = true;
                }
            } else if (*p == '<') {
                // Reusing last argument; bad idea since it can be re-arranged.
                nonpositional = true;
                p++;

                // Optionally '$' can be specified at the end.
                if (p < end && *p == '$') {
                    p++;
                }
            } else {
                nonpositional = true;
            }

            // Ignore flags and widths
            while (p < end && (*p == '-' ||
                    *p == '#' ||
                    *p == '+' ||
                    *p == ' ' ||
                    *p == ',' ||
                    *p == '(' ||
                    (*p >= '0' && *p <= '9'))) {
                p++;
            }

            /*
             * This is a shortcut to detect strings that are going to Time.format()
             * instead of String.format()
             *
             * Comparison of String.format() and Time.format() args:
             *
             * String: ABC E GH  ST X abcdefgh  nost x
             *   Time:    DEFGHKMS W Za  d   hkm  s w yz
             *
             * Therefore we know it's definitely Time if we have:
             *     DFKMWZkmwyz
             */
            if (p < end) {
                switch (*p) {
                case 'D':
                case 'F':
                case 'K':
                case 'M':
                case 'W':
                case 'Z':
                case 'k':
                case 'm':
                case 'w':
                case 'y':
                case 'z':
                    return NO_ERROR;
                }
            }
        }

        p++;
    }

    /*
     * If we have more than one substitution in this string and any of them
     * are not in positional form, give the user an error.
     */
    if (argCount > 1 && nonpositional) {
        SourcePos(String8(fileName), inXml->getLineNumber()).error(
                "Multiple substitutions specified in non-positional format; "
                "did you mean to add the formatted=\"false\" attribute?\n");
        return NOT_ENOUGH_DATA;
    }

    return NO_ERROR;
}

status_t parseStyledString(Bundle* bundle,
                           const char* fileName,
                           ResXMLTree* inXml,
                           const String16& endTag,
                           String16* outString,
                           Vector<StringPool::entry_style_span>* outSpans,
                           bool isFormatted,
                           bool pseudolocalize)
{
    Vector<StringPool::entry_style_span> spanStack;
    String16 curString;
    String16 rawString;
    const char* errorMsg;
    int xliffDepth = 0;
    bool firstTime = true;

    size_t len;
    ResXMLTree::event_code_t code;
    while ((code=inXml->next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {

        if (code == ResXMLTree::TEXT) {
            String16 text(inXml->getText(&len));
            if (firstTime && text.size() > 0) {
                firstTime = false;
                if (text.string()[0] == '@') {
                    // If this is a resource reference, don't do the pseudoloc.
                    pseudolocalize = false;
                }
            }
            if (xliffDepth == 0 && pseudolocalize) {
                std::string orig(String8(text).string());
                std::string pseudo = pseudolocalize_string(orig);
                curString.append(String16(String8(pseudo.c_str())));
            } else {
                if (isFormatted && hasSubstitutionErrors(fileName, inXml, text) != NO_ERROR) {
                    return UNKNOWN_ERROR;
                } else {
                    curString.append(text);
                }
            }
        } else if (code == ResXMLTree::START_TAG) {
            const String16 element16(inXml->getElementName(&len));
            const String8 element8(element16);

            size_t nslen;
            const uint16_t* ns = inXml->getElementNamespace(&nslen);
            if (ns == NULL) {
                ns = (const uint16_t*)"\0\0";
                nslen = 0;
            }
            const String8 nspace(String16(ns, nslen));
            if (nspace == XLIFF_XMLNS) {
                const int N = sizeof(ALLOWED_XLIFF_ELEMENTS)/sizeof(ALLOWED_XLIFF_ELEMENTS[0]);
                for (int i=0; i<N; i++) {
                    if (element8 == ALLOWED_XLIFF_ELEMENTS[i]) {
                        xliffDepth++;
                        // in this case, treat it like it was just text, in other words, do nothing
                        // here and silently drop this element
                        goto moveon;
                    }
                }
                {
                    SourcePos(String8(fileName), inXml->getLineNumber()).error(
                            "Found unsupported XLIFF tag <%s>\n",
                            element8.string());
                    return UNKNOWN_ERROR;
                }
moveon:
                continue;
            }

            if (outSpans == NULL) {
                SourcePos(String8(fileName), inXml->getLineNumber()).error(
                        "Found style tag <%s> where styles are not allowed\n", element8.string());
                return UNKNOWN_ERROR;
            }

            if (!ResTable::collectString(outString, curString.string(),
                                         curString.size(), false, &errorMsg, true)) {
                SourcePos(String8(fileName), inXml->getLineNumber()).error("%s (in %s)\n",
                        errorMsg, String8(curString).string());
                return UNKNOWN_ERROR;
            }
            rawString.append(curString);
            curString = String16();

            StringPool::entry_style_span span;
            span.name = element16;
            for (size_t ai=0; ai<inXml->getAttributeCount(); ai++) {
                span.name.append(String16(";"));
                const char16_t* str = inXml->getAttributeName(ai, &len);
                span.name.append(str, len);
                span.name.append(String16("="));
                str = inXml->getAttributeStringValue(ai, &len);
                span.name.append(str, len);
            }
            //printf("Span: %s\n", String8(span.name).string());
            span.span.firstChar = span.span.lastChar = outString->size();
            spanStack.push(span);

        } else if (code == ResXMLTree::END_TAG) {
            size_t nslen;
            const uint16_t* ns = inXml->getElementNamespace(&nslen);
            if (ns == NULL) {
                ns = (const uint16_t*)"\0\0";
                nslen = 0;
            }
            const String8 nspace(String16(ns, nslen));
            if (nspace == XLIFF_XMLNS) {
                xliffDepth--;
                continue;
            }
            if (!ResTable::collectString(outString, curString.string(),
                                         curString.size(), false, &errorMsg, true)) {
                SourcePos(String8(fileName), inXml->getLineNumber()).error("%s (in %s)\n",
                        errorMsg, String8(curString).string());
                return UNKNOWN_ERROR;
            }
            rawString.append(curString);
            curString = String16();

            if (spanStack.size() == 0) {
                if (strcmp16(inXml->getElementName(&len), endTag.string()) != 0) {
                    SourcePos(String8(fileName), inXml->getLineNumber()).error(
                            "Found tag %s where <%s> close is expected\n",
                            String8(inXml->getElementName(&len)).string(),
                            String8(endTag).string());
                    return UNKNOWN_ERROR;
                }
                break;
            }
            StringPool::entry_style_span span = spanStack.top();
            String16 spanTag;
            ssize_t semi = span.name.findFirst(';');
            if (semi >= 0) {
                spanTag.setTo(span.name.string(), semi);
            } else {
                spanTag.setTo(span.name);
            }
            if (strcmp16(inXml->getElementName(&len), spanTag.string()) != 0) {
                SourcePos(String8(fileName), inXml->getLineNumber()).error(
                        "Found close tag %s where close tag %s is expected\n",
                        String8(inXml->getElementName(&len)).string(),
                        String8(spanTag).string());
                return UNKNOWN_ERROR;
            }
            bool empty = true;
            if (outString->size() > 0) {
                span.span.lastChar = outString->size()-1;
                if (span.span.lastChar >= span.span.firstChar) {
                    empty = false;
                    outSpans->add(span);
                }
            }
            spanStack.pop();

            /*
             * This warning seems to be just an irritation to most people,
             * since it is typically introduced by translators who then never
             * see the warning.
             */
            if (0 && empty) {
                fprintf(stderr, "%s:%d: warning: empty '%s' span found in text '%s'\n",
                        fileName, inXml->getLineNumber(),
                        String8(spanTag).string(), String8(*outString).string());

            }
        } else if (code == ResXMLTree::START_NAMESPACE) {
            // nothing
        }
    }

    if (code == ResXMLTree::BAD_DOCUMENT) {
            SourcePos(String8(fileName), inXml->getLineNumber()).error(
                    "Error parsing XML\n");
    }

    if (outSpans != NULL && outSpans->size() > 0) {
        if (curString.size() > 0) {
            if (!ResTable::collectString(outString, curString.string(),
                                         curString.size(), false, &errorMsg, true)) {
                SourcePos(String8(fileName), inXml->getLineNumber()).error(
                        "%s (in %s)\n",
                        errorMsg, String8(curString).string());
                return UNKNOWN_ERROR;
            }
        }
    } else {
        // There is no style information, so string processing will happen
        // later as part of the overall type conversion.  Return to the
        // client the raw unprocessed text.
        rawString.append(curString);
        outString->setTo(rawString);
    }

    return NO_ERROR;
}

struct namespace_entry {
    String8 prefix;
    String8 uri;
};

static String8 make_prefix(int depth)
{
    String8 prefix;
    int i;
    for (i=0; i<depth; i++) {
        prefix.append("  ");
    }
    return prefix;
}

static String8 build_namespace(const Vector<namespace_entry>& namespaces,
        const uint16_t* ns)
{
    String8 str;
    if (ns != NULL) {
        str = String8(ns);
        const size_t N = namespaces.size();
        for (size_t i=0; i<N; i++) {
            const namespace_entry& ne = namespaces.itemAt(i);
            if (ne.uri == str) {
                str = ne.prefix;
                break;
            }
        }
        str.append(":");
    }
    return str;
}

void printXMLBlock(ResXMLTree* block)
{
    block->restart();

    Vector<namespace_entry> namespaces;
    
    ResXMLTree::event_code_t code;
    int depth = 0;
    while ((code=block->next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
        String8 prefix = make_prefix(depth);
        int i;
        if (code == ResXMLTree::START_TAG) {
            size_t len;
            const uint16_t* ns16 = block->getElementNamespace(&len);
            String8 elemNs = build_namespace(namespaces, ns16);
            const uint16_t* com16 = block->getComment(&len);
            if (com16) {
                printf("%s <!-- %s -->\n", prefix.string(), String8(com16).string());
            }
            printf("%sE: %s%s (line=%d)\n", prefix.string(), elemNs.string(),
                   String8(block->getElementName(&len)).string(),
                   block->getLineNumber());
            int N = block->getAttributeCount();
            depth++;
            prefix = make_prefix(depth);
            for (i=0; i<N; i++) {
                uint32_t res = block->getAttributeNameResID(i);
                ns16 = block->getAttributeNamespace(i, &len);
                String8 ns = build_namespace(namespaces, ns16);
                String8 name(block->getAttributeName(i, &len));
                printf("%sA: ", prefix.string());
                if (res) {
                    printf("%s%s(0x%08x)", ns.string(), name.string(), res);
                } else {
                    printf("%s%s", ns.string(), name.string());
                }
                Res_value value;
                block->getAttributeValue(i, &value);
                if (value.dataType == Res_value::TYPE_NULL) {
                    printf("=(null)");
                } else if (value.dataType == Res_value::TYPE_REFERENCE) {
                    printf("=@0x%x", (int)value.data);
                } else if (value.dataType == Res_value::TYPE_ATTRIBUTE) {
                    printf("=?0x%x", (int)value.data);
                } else if (value.dataType == Res_value::TYPE_STRING) {
                    printf("=\"%s\"",
                            ResTable::normalizeForOutput(String8(block->getAttributeStringValue(i,
                                        &len)).string()).string());
                } else {
                    printf("=(type 0x%x)0x%x", (int)value.dataType, (int)value.data);
                }
                const char16_t* val = block->getAttributeStringValue(i, &len);
                if (val != NULL) {
                    printf(" (Raw: \"%s\")", ResTable::normalizeForOutput(String8(val).string()).
                            string());
                }
                printf("\n");
            }
        } else if (code == ResXMLTree::END_TAG) {
            depth--;
        } else if (code == ResXMLTree::START_NAMESPACE) {
            namespace_entry ns;
            size_t len;
            const uint16_t* prefix16 = block->getNamespacePrefix(&len);
            if (prefix16) {
                ns.prefix = String8(prefix16);
            } else {
                ns.prefix = "<DEF>";
            }
            ns.uri = String8(block->getNamespaceUri(&len));
            namespaces.push(ns);
            printf("%sN: %s=%s\n", prefix.string(), ns.prefix.string(),
                    ns.uri.string());
            depth++;
        } else if (code == ResXMLTree::END_NAMESPACE) {
            depth--;
            const namespace_entry& ns = namespaces.top();
            size_t len;
            const uint16_t* prefix16 = block->getNamespacePrefix(&len);
            String8 pr;
            if (prefix16) {
                pr = String8(prefix16);
            } else {
                pr = "<DEF>";
            }
            if (ns.prefix != pr) {
                prefix = make_prefix(depth);
                printf("%s*** BAD END NS PREFIX: found=%s, expected=%s\n",
                        prefix.string(), pr.string(), ns.prefix.string());
            }
            String8 uri = String8(block->getNamespaceUri(&len));
            if (ns.uri != uri) {
                prefix = make_prefix(depth);
                printf("%s *** BAD END NS URI: found=%s, expected=%s\n",
                        prefix.string(), uri.string(), ns.uri.string());
            }
            namespaces.pop();
        } else if (code == ResXMLTree::TEXT) {
            size_t len;
            printf("%sC: \"%s\"\n", prefix.string(), String8(block->getText(&len)).string());
        }
    }

    block->restart();
}

status_t parseXMLResource(const sp<AaptFile>& file, ResXMLTree* outTree,
                          bool stripAll, bool keepComments,
                          const char** cDataTags)
{
    sp<XMLNode> root = XMLNode::parse(file);
    if (root == NULL) {
        return UNKNOWN_ERROR;
    }
    root->removeWhitespace(stripAll, cDataTags);

    NOISY(printf("Input XML from %s:\n", (const char*)file->getPrintableSource()));
    NOISY(root->print());
    sp<AaptFile> rsc = new AaptFile(String8(), AaptGroupEntry(), String8());
    status_t err = root->flatten(rsc, !keepComments, false);
    if (err != NO_ERROR) {
        return err;
    }
    err = outTree->setTo(rsc->getData(), rsc->getSize(), true);
    if (err != NO_ERROR) {
        return err;
    }

    NOISY(printf("Output XML:\n"));
    NOISY(printXMLBlock(outTree));

    return NO_ERROR;
}

sp<XMLNode> XMLNode::parse(const sp<AaptFile>& file)
{
    char buf[16384];
    int fd = open(file->getSourceFile().string(), O_RDONLY | O_BINARY);
    if (fd < 0) {
        SourcePos(file->getSourceFile(), -1).error("Unable to open file for read: %s",
                strerror(errno));
        return NULL;
    }

    XML_Parser parser = XML_ParserCreateNS(NULL, 1);
    ParseState state;
    state.filename = file->getPrintableSource();
    state.parser = parser;
    XML_SetUserData(parser, &state);
    XML_SetElementHandler(parser, startElement, endElement);
    XML_SetNamespaceDeclHandler(parser, startNamespace, endNamespace);
    XML_SetCharacterDataHandler(parser, characterData);
    XML_SetCommentHandler(parser, commentData);

    ssize_t len;
    bool done;
    do {
        len = read(fd, buf, sizeof(buf));
        done = len < (ssize_t)sizeof(buf);
        if (len < 0) {
            SourcePos(file->getSourceFile(), -1).error("Error reading file: %s\n", strerror(errno));
            close(fd);
            return NULL;
        }
        if (XML_Parse(parser, buf, len, done) == XML_STATUS_ERROR) {
            SourcePos(file->getSourceFile(), (int)XML_GetCurrentLineNumber(parser)).error(
                    "Error parsing XML: %s\n", XML_ErrorString(XML_GetErrorCode(parser)));
            close(fd);
            return NULL;
        }
    } while (!done);

    XML_ParserFree(parser);
    if (state.root == NULL) {
        SourcePos(file->getSourceFile(), -1).error("No XML data generated when parsing");
    }
    close(fd);
    return state.root;
}

XMLNode::XMLNode(const String8& filename, const String16& s1, const String16& s2, bool isNamespace)
    : mNextAttributeIndex(0x80000000)
    , mFilename(filename)
    , mStartLineNumber(0)
    , mEndLineNumber(0)
    , mUTF8(false)
{
    if (isNamespace) {
        mNamespacePrefix = s1;
        mNamespaceUri = s2;
    } else {
        mNamespaceUri = s1;
        mElementName = s2;
    }
}

XMLNode::XMLNode(const String8& filename)
    : mFilename(filename)
{
    memset(&mCharsValue, 0, sizeof(mCharsValue));
}

XMLNode::type XMLNode::getType() const
{
    if (mElementName.size() != 0) {
        return TYPE_ELEMENT;
    }
    if (mNamespaceUri.size() != 0) {
        return TYPE_NAMESPACE;
    }
    return TYPE_CDATA;
}

const String16& XMLNode::getNamespacePrefix() const
{
    return mNamespacePrefix;
}

const String16& XMLNode::getNamespaceUri() const
{
    return mNamespaceUri;
}

const String16& XMLNode::getElementNamespace() const
{
    return mNamespaceUri;
}

const String16& XMLNode::getElementName() const
{
    return mElementName;
}

const Vector<sp<XMLNode> >& XMLNode::getChildren() const
{
    return mChildren;
}

const String8& XMLNode::getFilename() const
{
    return mFilename;
}
    
const Vector<XMLNode::attribute_entry>&
    XMLNode::getAttributes() const
{
    return mAttributes;
}

const XMLNode::attribute_entry* XMLNode::getAttribute(const String16& ns,
        const String16& name) const
{
    for (size_t i=0; i<mAttributes.size(); i++) {
        const attribute_entry& ae(mAttributes.itemAt(i));
        if (ae.ns == ns && ae.name == name) {
            return &ae;
        }
    }
    
    return NULL;
}

XMLNode::attribute_entry* XMLNode::editAttribute(const String16& ns,
        const String16& name)
{
    for (size_t i=0; i<mAttributes.size(); i++) {
        attribute_entry * ae = &mAttributes.editItemAt(i);
        if (ae->ns == ns && ae->name == name) {
            return ae;
        }
    }

    return NULL;
}

const String16& XMLNode::getCData() const
{
    return mChars;
}

const String16& XMLNode::getComment() const
{
    return mComment;
}

int32_t XMLNode::getStartLineNumber() const
{
    return mStartLineNumber;
}

int32_t XMLNode::getEndLineNumber() const
{
    return mEndLineNumber;
}

sp<XMLNode> XMLNode::searchElement(const String16& tagNamespace, const String16& tagName)
{
    if (getType() == XMLNode::TYPE_ELEMENT
            && mNamespaceUri == tagNamespace
            && mElementName == tagName) {
        return this;
    }
    
    for (size_t i=0; i<mChildren.size(); i++) {
        sp<XMLNode> found = mChildren.itemAt(i)->searchElement(tagNamespace, tagName);
        if (found != NULL) {
            return found;
        }
    }
    
    return NULL;
}

sp<XMLNode> XMLNode::getChildElement(const String16& tagNamespace, const String16& tagName)
{
    for (size_t i=0; i<mChildren.size(); i++) {
        sp<XMLNode> child = mChildren.itemAt(i);
        if (child->getType() == XMLNode::TYPE_ELEMENT
                && child->mNamespaceUri == tagNamespace
                && child->mElementName == tagName) {
            return child;
        }
    }
    
    return NULL;
}

status_t XMLNode::addChild(const sp<XMLNode>& child)
{
    if (getType() == TYPE_CDATA) {
        SourcePos(mFilename, child->getStartLineNumber()).error("Child to CDATA node.");
        return UNKNOWN_ERROR;
    }
    //printf("Adding child %p to parent %p\n", child.get(), this);
    mChildren.add(child);
    return NO_ERROR;
}

status_t XMLNode::insertChildAt(const sp<XMLNode>& child, size_t index)
{
    if (getType() == TYPE_CDATA) {
        SourcePos(mFilename, child->getStartLineNumber()).error("Child to CDATA node.");
        return UNKNOWN_ERROR;
    }
    //printf("Adding child %p to parent %p\n", child.get(), this);
    mChildren.insertAt(child, index);
    return NO_ERROR;
}

status_t XMLNode::addAttribute(const String16& ns, const String16& name,
                               const String16& value)
{
    if (getType() == TYPE_CDATA) {
        SourcePos(mFilename, getStartLineNumber()).error("Child to CDATA node.");
        return UNKNOWN_ERROR;
    }
    attribute_entry e;
    e.index = mNextAttributeIndex++;
    e.ns = ns;
    e.name = name;
    e.string = value;
    mAttributes.add(e);
    mAttributeOrder.add(e.index, mAttributes.size()-1);
    return NO_ERROR;
}

void XMLNode::setAttributeResID(size_t attrIdx, uint32_t resId)
{
    attribute_entry& e = mAttributes.editItemAt(attrIdx);
    if (e.nameResId) {
        mAttributeOrder.removeItem(e.nameResId);
    } else {
        mAttributeOrder.removeItem(e.index);
    }
    NOISY(printf("Elem %s %s=\"%s\": set res id = 0x%08x\n",
            String8(getElementName()).string(),
            String8(mAttributes.itemAt(attrIdx).name).string(),
            String8(mAttributes.itemAt(attrIdx).string).string(),
            resId));
    mAttributes.editItemAt(attrIdx).nameResId = resId;
    mAttributeOrder.add(resId, attrIdx);
}

status_t XMLNode::appendChars(const String16& chars)
{
    if (getType() != TYPE_CDATA) {
        SourcePos(mFilename, getStartLineNumber()).error("Adding characters to element node.");
        return UNKNOWN_ERROR;
    }
    mChars.append(chars);
    return NO_ERROR;
}

status_t XMLNode::appendComment(const String16& comment)
{
    if (mComment.size() > 0) {
        mComment.append(String16("\n"));
    }
    mComment.append(comment);
    return NO_ERROR;
}

void XMLNode::setStartLineNumber(int32_t line)
{
    mStartLineNumber = line;
}

void XMLNode::setEndLineNumber(int32_t line)
{
    mEndLineNumber = line;
}

void XMLNode::removeWhitespace(bool stripAll, const char** cDataTags)
{
    //printf("Removing whitespace in %s\n", String8(mElementName).string());
    size_t N = mChildren.size();
    if (cDataTags) {
        String8 tag(mElementName);
        const char** p = cDataTags;
        while (*p) {
            if (tag == *p) {
                stripAll = false;
                break;
            }
        }
    }
    for (size_t i=0; i<N; i++) {
        sp<XMLNode> node = mChildren.itemAt(i);
        if (node->getType() == TYPE_CDATA) {
            // This is a CDATA node...
            const char16_t* p = node->mChars.string();
            while (*p != 0 && *p < 128 && isspace(*p)) {
                p++;
            }
            //printf("Space ends at %d in \"%s\"\n",
            //       (int)(p-node->mChars.string()),
            //       String8(node->mChars).string());
            if (*p == 0) {
                if (stripAll) {
                    // Remove this node!
                    mChildren.removeAt(i);
                    N--;
                    i--;
                } else {
                    node->mChars = String16(" ");
                }
            } else {
                // Compact leading/trailing whitespace.
                const char16_t* e = node->mChars.string()+node->mChars.size()-1;
                while (e > p && *e < 128 && isspace(*e)) {
                    e--;
                }
                if (p > node->mChars.string()) {
                    p--;
                }
                if (e < (node->mChars.string()+node->mChars.size()-1)) {
                    e++;
                }
                if (p > node->mChars.string() ||
                    e < (node->mChars.string()+node->mChars.size()-1)) {
                    String16 tmp(p, e-p+1);
                    node->mChars = tmp;
                }
            }
        } else {
            node->removeWhitespace(stripAll, cDataTags);
        }
    }
}

status_t XMLNode::parseValues(const sp<AaptAssets>& assets,
                              ResourceTable* table)
{
    bool hasErrors = false;
    
    if (getType() == TYPE_ELEMENT) {
        const size_t N = mAttributes.size();
        String16 defPackage(assets->getPackage());
        for (size_t i=0; i<N; i++) {
            attribute_entry& e = mAttributes.editItemAt(i);
            AccessorCookie ac(SourcePos(mFilename, getStartLineNumber()), String8(e.name),
                    String8(e.string));
            table->setCurrentXmlPos(SourcePos(mFilename, getStartLineNumber()));
            if (!assets->getIncludedResources()
                    .stringToValue(&e.value, &e.string,
                                  e.string.string(), e.string.size(), true, true,
                                  e.nameResId, NULL, &defPackage, table, &ac)) {
                hasErrors = true;
            }
            NOISY(printf("Attr %s: type=0x%x, str=%s\n",
                   String8(e.name).string(), e.value.dataType,
                   String8(e.string).string()));
        }
    }
    const size_t N = mChildren.size();
    for (size_t i=0; i<N; i++) {
        status_t err = mChildren.itemAt(i)->parseValues(assets, table);
        if (err != NO_ERROR) {
            hasErrors = true;
        }
    }
    return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
}

status_t XMLNode::assignResourceIds(const sp<AaptAssets>& assets,
                                    const ResourceTable* table)
{
    bool hasErrors = false;
    
    if (getType() == TYPE_ELEMENT) {
        String16 attr("attr");
        const char* errorMsg;
        const size_t N = mAttributes.size();
        for (size_t i=0; i<N; i++) {
            const attribute_entry& e = mAttributes.itemAt(i);
            if (e.ns.size() <= 0) continue;
            bool nsIsPublic;
            String16 pkg(getNamespaceResourcePackage(e.ns, &nsIsPublic));
            NOISY(printf("Elem %s %s=\"%s\": namespace(%s) %s ===> %s\n",
                    String8(getElementName()).string(),
                    String8(e.name).string(),
                    String8(e.string).string(),
                    String8(e.ns).string(),
                    (nsIsPublic) ? "public" : "private",
                    String8(pkg).string()));
            if (pkg.size() <= 0) continue;
            uint32_t res = table != NULL
                ? table->getResId(e.name, &attr, &pkg, &errorMsg, nsIsPublic)
                : assets->getIncludedResources().
                    identifierForName(e.name.string(), e.name.size(),
                                      attr.string(), attr.size(),
                                      pkg.string(), pkg.size());
            if (res != 0) {
                NOISY(printf("XML attribute name %s: resid=0x%08x\n",
                             String8(e.name).string(), res));
                setAttributeResID(i, res);
            } else {
                SourcePos(mFilename, getStartLineNumber()).error(
                        "No resource identifier found for attribute '%s' in package '%s'\n",
                        String8(e.name).string(), String8(pkg).string());
                hasErrors = true;
            }
        }
    }
    const size_t N = mChildren.size();
    for (size_t i=0; i<N; i++) {
        status_t err = mChildren.itemAt(i)->assignResourceIds(assets, table);
        if (err < NO_ERROR) {
            hasErrors = true;
        }
    }

    return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
}

status_t XMLNode::flatten(const sp<AaptFile>& dest,
        bool stripComments, bool stripRawValues) const
{
    StringPool strings = StringPool(false, mUTF8);
    Vector<uint32_t> resids;
    
    // First collect just the strings for attribute names that have a
    // resource ID assigned to them.  This ensures that the resource ID
    // array is compact, and makes it easier to deal with attribute names
    // in different namespaces (and thus with different resource IDs).
    collect_resid_strings(&strings, &resids);

    // Next collect all remainibng strings.
    collect_strings(&strings, &resids, stripComments, stripRawValues);

#if 0  // No longer compiles
    NOISY(printf("Found strings:\n");
        const size_t N = strings.size();
        for (size_t i=0; i<N; i++) {
            printf("%s\n", String8(strings.entryAt(i).string).string());
        }
    );
#endif    

    sp<AaptFile> stringPool = strings.createStringBlock();
    NOISY(aout << "String pool:"
          << HexDump(stringPool->getData(), stringPool->getSize()) << endl);

    ResXMLTree_header header;
    memset(&header, 0, sizeof(header));
    header.header.type = htods(RES_XML_TYPE);
    header.header.headerSize = htods(sizeof(header));

    const size_t basePos = dest->getSize();
    dest->writeData(&header, sizeof(header));
    dest->writeData(stringPool->getData(), stringPool->getSize());

    // If we have resource IDs, write them.
    if (resids.size() > 0) {
        const size_t resIdsPos = dest->getSize();
        const size_t resIdsSize =
            sizeof(ResChunk_header)+(sizeof(uint32_t)*resids.size());
        ResChunk_header* idsHeader = (ResChunk_header*)
            (((const uint8_t*)dest->editData(resIdsPos+resIdsSize))+resIdsPos);
        idsHeader->type = htods(RES_XML_RESOURCE_MAP_TYPE);
        idsHeader->headerSize = htods(sizeof(*idsHeader));
        idsHeader->size = htodl(resIdsSize);
        uint32_t* ids = (uint32_t*)(idsHeader+1);
        for (size_t i=0; i<resids.size(); i++) {
            *ids++ = htodl(resids[i]);
        }
    }

    flatten_node(strings, dest, stripComments, stripRawValues);

    void* data = dest->editData();
    ResXMLTree_header* hd = (ResXMLTree_header*)(((uint8_t*)data)+basePos);
    size_t size = dest->getSize()-basePos;
    hd->header.size = htodl(dest->getSize()-basePos);

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

    #if PRINT_STRING_METRICS
    fprintf(stderr, "**** total xml size: %d / %d%% strings (in %s)\n",
        dest->getSize(), (stringPool->getSize()*100)/dest->getSize(),
        dest->getPath().string());
    #endif
        
    return NO_ERROR;
}

void XMLNode::print(int indent)
{
    String8 prefix;
    int i;
    for (i=0; i<indent; i++) {
        prefix.append("  ");
    }
    if (getType() == TYPE_ELEMENT) {
        String8 elemNs(getNamespaceUri());
        if (elemNs.size() > 0) {
            elemNs.append(":");
        }
        printf("%s E: %s%s", prefix.string(),
               elemNs.string(), String8(getElementName()).string());
        int N = mAttributes.size();
        for (i=0; i<N; i++) {
            ssize_t idx = mAttributeOrder.valueAt(i);
            if (i == 0) {
                printf(" / ");
            } else {
                printf(", ");
            }
            const attribute_entry& attr = mAttributes.itemAt(idx);
            String8 attrNs(attr.ns);
            if (attrNs.size() > 0) {
                attrNs.append(":");
            }
            if (attr.nameResId) {
                printf("%s%s(0x%08x)", attrNs.string(),
                       String8(attr.name).string(), attr.nameResId);
            } else {
                printf("%s%s", attrNs.string(), String8(attr.name).string());
            }
            printf("=%s", String8(attr.string).string());
        }
        printf("\n");
    } else if (getType() == TYPE_NAMESPACE) {
        printf("%s N: %s=%s\n", prefix.string(),
               getNamespacePrefix().size() > 0
                    ? String8(getNamespacePrefix()).string() : "<DEF>",
               String8(getNamespaceUri()).string());
    } else {
        printf("%s C: \"%s\"\n", prefix.string(), String8(getCData()).string());
    }
    int N = mChildren.size();
    for (i=0; i<N; i++) {
        mChildren.itemAt(i)->print(indent+1);
    }
}

static void splitName(const char* name, String16* outNs, String16* outName)
{
    const char* p = name;
    while (*p != 0 && *p != 1) {
        p++;
    }
    if (*p == 0) {
        *outNs = String16();
        *outName = String16(name);
    } else {
        *outNs = String16(name, (p-name));
        *outName = String16(p+1);
    }
}

void XMLCALL
XMLNode::startNamespace(void *userData, const char *prefix, const char *uri)
{
    NOISY_PARSE(printf("Start Namespace: %s %s\n", prefix, uri));
    ParseState* st = (ParseState*)userData;
    sp<XMLNode> node = XMLNode::newNamespace(st->filename, 
            String16(prefix != NULL ? prefix : ""), String16(uri));
    node->setStartLineNumber(XML_GetCurrentLineNumber(st->parser));
    if (st->stack.size() > 0) {
        st->stack.itemAt(st->stack.size()-1)->addChild(node);
    } else {
        st->root = node;
    }
    st->stack.push(node);
}

void XMLCALL
XMLNode::startElement(void *userData, const char *name, const char **atts)
{
    NOISY_PARSE(printf("Start Element: %s\n", name));
    ParseState* st = (ParseState*)userData;
    String16 ns16, name16;
    splitName(name, &ns16, &name16);
    sp<XMLNode> node = XMLNode::newElement(st->filename, ns16, name16);
    node->setStartLineNumber(XML_GetCurrentLineNumber(st->parser));
    if (st->pendingComment.size() > 0) {
        node->appendComment(st->pendingComment);
        st->pendingComment = String16();
    }
    if (st->stack.size() > 0) {
        st->stack.itemAt(st->stack.size()-1)->addChild(node);
    } else {
        st->root = node;
    }
    st->stack.push(node);

    for (int i = 0; atts[i]; i += 2) {
        splitName(atts[i], &ns16, &name16);
        node->addAttribute(ns16, name16, String16(atts[i+1]));
    }
}

void XMLCALL
XMLNode::characterData(void *userData, const XML_Char *s, int len)
{
    NOISY_PARSE(printf("CDATA: \"%s\"\n", String8(s, len).string()));
    ParseState* st = (ParseState*)userData;
    sp<XMLNode> node = NULL;
    if (st->stack.size() == 0) {
        return;
    }
    sp<XMLNode> parent = st->stack.itemAt(st->stack.size()-1);
    if (parent != NULL && parent->getChildren().size() > 0) {
        node = parent->getChildren()[parent->getChildren().size()-1];
        if (node->getType() != TYPE_CDATA) {
            // Last node is not CDATA, need to make a new node.
            node = NULL;
        }
    }

    if (node == NULL) {
        node = XMLNode::newCData(st->filename);
        node->setStartLineNumber(XML_GetCurrentLineNumber(st->parser));
        parent->addChild(node);
    }

    node->appendChars(String16(s, len));
}

void XMLCALL
XMLNode::endElement(void *userData, const char *name)
{
    NOISY_PARSE(printf("End Element: %s\n", name));
    ParseState* st = (ParseState*)userData;
    sp<XMLNode> node = st->stack.itemAt(st->stack.size()-1);
    node->setEndLineNumber(XML_GetCurrentLineNumber(st->parser));
    if (st->pendingComment.size() > 0) {
        node->appendComment(st->pendingComment);
        st->pendingComment = String16();
    }
    String16 ns16, name16;
    splitName(name, &ns16, &name16);
    LOG_ALWAYS_FATAL_IF(node->getElementNamespace() != ns16
                        || node->getElementName() != name16,
                        "Bad end element %s", name);
    st->stack.pop();
}

void XMLCALL
XMLNode::endNamespace(void *userData, const char *prefix)
{
    const char* nonNullPrefix = prefix != NULL ? prefix : "";
    NOISY_PARSE(printf("End Namespace: %s\n", prefix));
    ParseState* st = (ParseState*)userData;
    sp<XMLNode> node = st->stack.itemAt(st->stack.size()-1);
    node->setEndLineNumber(XML_GetCurrentLineNumber(st->parser));
    LOG_ALWAYS_FATAL_IF(node->getNamespacePrefix() != String16(nonNullPrefix),
                        "Bad end namespace %s", prefix);
    st->stack.pop();
}

void XMLCALL
XMLNode::commentData(void *userData, const char *comment)
{
    NOISY_PARSE(printf("Comment: %s\n", comment));
    ParseState* st = (ParseState*)userData;
    if (st->pendingComment.size() > 0) {
        st->pendingComment.append(String16("\n"));
    }
    st->pendingComment.append(String16(comment));
}

status_t XMLNode::collect_strings(StringPool* dest, Vector<uint32_t>* outResIds,
        bool stripComments, bool stripRawValues) const
{
    collect_attr_strings(dest, outResIds, true);
    
    int i;
    if (mNamespacePrefix.size() > 0) {
        dest->add(mNamespacePrefix, true);
    }
    if (mNamespaceUri.size() > 0) {
        dest->add(mNamespaceUri, true);
    }
    if (mElementName.size() > 0) {
        dest->add(mElementName, true);
    }

    if (!stripComments && mComment.size() > 0) {
        dest->add(mComment, true);
    }

    const int NA = mAttributes.size();

    for (i=0; i<NA; i++) {
        const attribute_entry& ae = mAttributes.itemAt(i);
        if (ae.ns.size() > 0) {
            dest->add(ae.ns, true);
        }
        if (!stripRawValues || ae.needStringValue()) {
            dest->add(ae.string, true);
        }
        /*
        if (ae.value.dataType == Res_value::TYPE_NULL
                || ae.value.dataType == Res_value::TYPE_STRING) {
            dest->add(ae.string, true);
        }
        */
    }

    if (mElementName.size() == 0) {
        // If not an element, include the CDATA, even if it is empty.
        dest->add(mChars, true);
    }

    const int NC = mChildren.size();

    for (i=0; i<NC; i++) {
        mChildren.itemAt(i)->collect_strings(dest, outResIds,
                stripComments, stripRawValues);
    }

    return NO_ERROR;
}

status_t XMLNode::collect_attr_strings(StringPool* outPool,
        Vector<uint32_t>* outResIds, bool allAttrs) const {
    const int NA = mAttributes.size();

    for (int i=0; i<NA; i++) {
        const attribute_entry& attr = mAttributes.itemAt(i);
        uint32_t id = attr.nameResId;
        if (id || allAttrs) {
            // See if we have already assigned this resource ID to a pooled
            // string...
            const Vector<size_t>* indices = outPool->offsetsForString(attr.name);
            ssize_t idx = -1;
            if (indices != NULL) {
                const int NJ = indices->size();
                const size_t NR = outResIds->size();
                for (int j=0; j<NJ; j++) {
                    size_t strIdx = indices->itemAt(j);
                    if (strIdx >= NR) {
                        if (id == 0) {
                            // We don't need to assign a resource ID for this one.
                            idx = strIdx;
                            break;
                        }
                        // Just ignore strings that are out of range of
                        // the currently assigned resource IDs...  we add
                        // strings as we assign the first ID.
                    } else if (outResIds->itemAt(strIdx) == id) {
                        idx = strIdx;
                        break;
                    }
                }
            }
            if (idx < 0) {
                idx = outPool->add(attr.name);
                NOISY(printf("Adding attr %s (resid 0x%08x) to pool: idx=%d\n",
                        String8(attr.name).string(), id, idx));
                if (id != 0) {
                    while ((ssize_t)outResIds->size() <= idx) {
                        outResIds->add(0);
                    }
                    outResIds->replaceAt(id, idx);
                }
            }
            attr.namePoolIdx = idx;
            NOISY(printf("String %s offset=0x%08x\n",
                         String8(attr.name).string(), idx));
        }
    }

    return NO_ERROR;
}

status_t XMLNode::collect_resid_strings(StringPool* outPool,
        Vector<uint32_t>* outResIds) const
{
    collect_attr_strings(outPool, outResIds, false);

    const int NC = mChildren.size();

    for (int i=0; i<NC; i++) {
        mChildren.itemAt(i)->collect_resid_strings(outPool, outResIds);
    }

    return NO_ERROR;
}

status_t XMLNode::flatten_node(const StringPool& strings, const sp<AaptFile>& dest,
        bool stripComments, bool stripRawValues) const
{
    ResXMLTree_node node;
    ResXMLTree_cdataExt cdataExt;
    ResXMLTree_namespaceExt namespaceExt;
    ResXMLTree_attrExt attrExt;
    const void* extData = NULL;
    size_t extSize = 0;
    ResXMLTree_attribute attr;

    const size_t NA = mAttributes.size();
    const size_t NC = mChildren.size();
    size_t i;

    LOG_ALWAYS_FATAL_IF(NA != mAttributeOrder.size(), "Attributes messed up!");

    const String16 id16("id");
    const String16 class16("class");
    const String16 style16("style");

    const type type = getType();
    
    memset(&node, 0, sizeof(node));
    memset(&attr, 0, sizeof(attr));
    node.header.headerSize = htods(sizeof(node));
    node.lineNumber = htodl(getStartLineNumber());
    if (!stripComments) {
        node.comment.index = htodl(
            mComment.size() > 0 ? strings.offsetForString(mComment) : -1);
        //if (mComment.size() > 0) {
        //  printf("Flattening comment: %s\n", String8(mComment).string());
        //}
    } else {
        node.comment.index = htodl((uint32_t)-1);
    }
    if (type == TYPE_ELEMENT) {
        node.header.type = htods(RES_XML_START_ELEMENT_TYPE);
        extData = &attrExt;
        extSize = sizeof(attrExt);
        memset(&attrExt, 0, sizeof(attrExt));
        if (mNamespaceUri.size() > 0) {
            attrExt.ns.index = htodl(strings.offsetForString(mNamespaceUri));
        } else {
            attrExt.ns.index = htodl((uint32_t)-1);
        }
        attrExt.name.index = htodl(strings.offsetForString(mElementName));
        attrExt.attributeStart = htods(sizeof(attrExt));
        attrExt.attributeSize = htods(sizeof(attr));
        attrExt.attributeCount = htods(NA);
        attrExt.idIndex = htods(0);
        attrExt.classIndex = htods(0);
        attrExt.styleIndex = htods(0);
        for (i=0; i<NA; i++) {
            ssize_t idx = mAttributeOrder.valueAt(i);
            const attribute_entry& ae = mAttributes.itemAt(idx);
            if (ae.ns.size() == 0) {
                if (ae.name == id16) {
                    attrExt.idIndex = htods(i+1);
                } else if (ae.name == class16) {
                    attrExt.classIndex = htods(i+1);
                } else if (ae.name == style16) {
                    attrExt.styleIndex = htods(i+1);
                }
            }
        }
    } else if (type == TYPE_NAMESPACE) {
        node.header.type = htods(RES_XML_START_NAMESPACE_TYPE);
        extData = &namespaceExt;
        extSize = sizeof(namespaceExt);
        memset(&namespaceExt, 0, sizeof(namespaceExt));
        if (mNamespacePrefix.size() > 0) {
            namespaceExt.prefix.index = htodl(strings.offsetForString(mNamespacePrefix));
        } else {
            namespaceExt.prefix.index = htodl((uint32_t)-1);
        }
        namespaceExt.prefix.index = htodl(strings.offsetForString(mNamespacePrefix));
        namespaceExt.uri.index = htodl(strings.offsetForString(mNamespaceUri));
        LOG_ALWAYS_FATAL_IF(NA != 0, "Namespace nodes can't have attributes!");
    } else if (type == TYPE_CDATA) {
        node.header.type = htods(RES_XML_CDATA_TYPE);
        extData = &cdataExt;
        extSize = sizeof(cdataExt);
        memset(&cdataExt, 0, sizeof(cdataExt));
        cdataExt.data.index = htodl(strings.offsetForString(mChars));
        cdataExt.typedData.size = htods(sizeof(cdataExt.typedData));
        cdataExt.typedData.res0 = 0;
        cdataExt.typedData.dataType = mCharsValue.dataType;
        cdataExt.typedData.data = htodl(mCharsValue.data);
        LOG_ALWAYS_FATAL_IF(NA != 0, "CDATA nodes can't have attributes!");
    }

    node.header.size = htodl(sizeof(node) + extSize + (sizeof(attr)*NA));

    dest->writeData(&node, sizeof(node));
    if (extSize > 0) {
        dest->writeData(extData, extSize);
    }

    for (i=0; i<NA; i++) {
        ssize_t idx = mAttributeOrder.valueAt(i);
        const attribute_entry& ae = mAttributes.itemAt(idx);
        if (ae.ns.size() > 0) {
            attr.ns.index = htodl(strings.offsetForString(ae.ns));
        } else {
            attr.ns.index = htodl((uint32_t)-1);
        }
        attr.name.index = htodl(ae.namePoolIdx);

        if (!stripRawValues || ae.needStringValue()) {
            attr.rawValue.index = htodl(strings.offsetForString(ae.string));
        } else {
            attr.rawValue.index = htodl((uint32_t)-1);
        }
        attr.typedValue.size = htods(sizeof(attr.typedValue));
        if (ae.value.dataType == Res_value::TYPE_NULL
                || ae.value.dataType == Res_value::TYPE_STRING) {
            attr.typedValue.res0 = 0;
            attr.typedValue.dataType = Res_value::TYPE_STRING;
            attr.typedValue.data = htodl(strings.offsetForString(ae.string));
        } else {
            attr.typedValue.res0 = 0;
            attr.typedValue.dataType = ae.value.dataType;
            attr.typedValue.data = htodl(ae.value.data);
        }
        dest->writeData(&attr, sizeof(attr));
    }

    for (i=0; i<NC; i++) {
        status_t err = mChildren.itemAt(i)->flatten_node(strings, dest,
                stripComments, stripRawValues);
        if (err != NO_ERROR) {
            return err;
        }
    }

    if (type == TYPE_ELEMENT) {
        ResXMLTree_endElementExt endElementExt;
        memset(&endElementExt, 0, sizeof(endElementExt));
        node.header.type = htods(RES_XML_END_ELEMENT_TYPE);
        node.header.size = htodl(sizeof(node)+sizeof(endElementExt));
        node.lineNumber = htodl(getEndLineNumber());
        node.comment.index = htodl((uint32_t)-1);
        endElementExt.ns.index = attrExt.ns.index;
        endElementExt.name.index = attrExt.name.index;
        dest->writeData(&node, sizeof(node));
        dest->writeData(&endElementExt, sizeof(endElementExt));
    } else if (type == TYPE_NAMESPACE) {
        node.header.type = htods(RES_XML_END_NAMESPACE_TYPE);
        node.lineNumber = htodl(getEndLineNumber());
        node.comment.index = htodl((uint32_t)-1);
        node.header.size = htodl(sizeof(node)+extSize);
        dest->writeData(&node, sizeof(node));
        dest->writeData(extData, extSize);
    }

    return NO_ERROR;
}
