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

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

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

#ifndef _WIN32
#define O_BINARY 0
#endif

// STATUST: mingw does seem to redefine UNKNOWN_ERROR from our enum value, so a cast is necessary.
#if !defined(_WIN32)
#  define STATUST(x) x
#else
#  define STATUST(x) (status_t)x
#endif

// Set to true for noisy debug output.
static const bool kIsDebug = false;
// Set to true for noisy debug output of parsing.
static const bool kIsDebugParse = false;

#if PRINT_STRING_METRICS
static const bool kPrintStringMetrics = true;
#else
static const bool kPrintStringMetrics = false;
#endif

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_AUTO_PACKAGE_NAMESPACE = "http://schemas.android.com/apk/res-auto";
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_PREFIX_AUTO_PACKAGE(RESOURCES_AUTO_PACKAGE_NAMESPACE);
static const String16 RESOURCES_PRV_PREFIX(RESOURCES_ROOT_PRV_NAMESPACE);
static const String16 RESOURCES_TOOLS_NAMESPACE("http://schemas.android.com/tools");

String16 getNamespaceResourcePackage(const String16& appPackage, const 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_AUTO_PACKAGE)) {
        if (kIsDebug) {
            printf("Using default application package: %s -> %s\n", String8(namespaceUri).string(),
                   String8(appPackage).string());
        }
        isPublic = true;
        return appPackage;
    } else 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,
                               const 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,
                           PseudolocalizationMethod pseudolocalize)
{
    Vector<StringPool::entry_style_span> spanStack;
    String16 curString;
    String16 rawString;
    Pseudolocalizer pseudo(pseudolocalize);
    const char* errorMsg;
    int xliffDepth = 0;
    bool firstTime = true;

    size_t len;
    ResXMLTree::event_code_t code;
    curString.append(pseudo.start());
    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 = NO_PSEUDOLOCALIZATION;
                    pseudo.setMethod(pseudolocalize);
                    curString = String16();
                }
            }
            if (xliffDepth == 0 && pseudolocalize > 0) {
                curString.append(pseudo.text(text));
            } 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 char16_t* ns = inXml->getElementNamespace(&nslen);
            if (ns == NULL) {
                ns = (const char16_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 char16_t* ns = inXml->getElementNamespace(&nslen);
            if (ns == NULL) {
                ns = (const char16_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
        }
    }

    curString.append(pseudo.end());

    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 char16_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 char16_t* ns16 = block->getElementNamespace(&len);
            String8 elemNs = build_namespace(namespaces, ns16);
            const char16_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%08x", (int)value.data);
                } else if (value.dataType == Res_value::TYPE_ATTRIBUTE) {
                    printf("=?0x%08x", (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) {
            // Invalid tag nesting can be misused to break the parsing
            // code below. Break if detected.
            if (--depth < 0) {
                printf("***BAD DEPTH in XMLBlock: %d\n", depth);
                break;
            }
        } else if (code == ResXMLTree::START_NAMESPACE) {
            namespace_entry ns;
            size_t len;
            const char16_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) {
            if (--depth < 0) {
                printf("***BAD DEPTH in XMLBlock: %d\n", depth);
                break;
            }
            const namespace_entry& ns = namespaces.top();
            size_t len;
            const char16_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(),
                    ResTable::normalizeForOutput(String8(block->getText(&len)).string()).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);

    if (kIsDebug) {
        printf("Input XML from %s:\n", (const char*)file->getPrintableSource());
        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;
    }

    if (kIsDebug) {
        printf("Output XML:\n");
        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()
    : mNextAttributeIndex(0x80000000)
    , mStartLineNumber(0)
    , mEndLineNumber(0)
    , mUTF8(false) {}

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;
}


Vector<sp<XMLNode> >& XMLNode::getChildren()
{
    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;
}

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

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;
    }

    if (ns != RESOURCES_TOOLS_NAMESPACE) {
        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;
}

status_t XMLNode::removeAttribute(size_t index)
{
    if (getType() == TYPE_CDATA) {
        return UNKNOWN_ERROR;
    }

    if (index >= mAttributes.size()) {
        return UNKNOWN_ERROR;
    }

    const attribute_entry& e = mAttributes[index];
    const uint32_t key = e.nameResId ? e.nameResId : e.index;
    mAttributeOrder.removeItem(key);
    mAttributes.removeAt(index);

    // Shift all the indices.
    const size_t attrCount = mAttributeOrder.size();
    for (size_t i = 0; i < attrCount; i++) {
        size_t attrIdx = mAttributeOrder[i];
        if (attrIdx > index) {
            mAttributeOrder.replaceValueAt(i, attrIdx - 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);
    }
    if (kIsDebug) {
        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;
            }
            if (kIsDebug) {
                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 ? STATUST(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 = true;
            String16 pkg(getNamespaceResourcePackage(String16(assets->getPackage()), e.ns, &nsIsPublic));
            if (kIsDebug) {
                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) {
                if (kIsDebug) {
                    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 ? STATUST(UNKNOWN_ERROR) : NO_ERROR;
}

sp<XMLNode> XMLNode::clone() const {
    sp<XMLNode> copy = new XMLNode();
    copy->mNamespacePrefix = mNamespacePrefix;
    copy->mNamespaceUri = mNamespaceUri;
    copy->mElementName = mElementName;

    const size_t childCount = mChildren.size();
    for (size_t i = 0; i < childCount; i++) {
        copy->mChildren.add(mChildren[i]->clone());
    }

    copy->mAttributes = mAttributes;
    copy->mAttributeOrder = mAttributeOrder;
    copy->mNextAttributeIndex = mNextAttributeIndex;
    copy->mChars = mChars;
    memcpy(&copy->mCharsValue, &mCharsValue, sizeof(mCharsValue));
    copy->mComment = mComment;
    copy->mFilename = mFilename;
    copy->mStartLineNumber = mStartLineNumber;
    copy->mEndLineNumber = mEndLineNumber;
    copy->mUTF8 = mUTF8;
    return copy;
}

status_t XMLNode::flatten(const sp<AaptFile>& dest,
        bool stripComments, bool stripRawValues) const
{
    StringPool strings(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);

    sp<AaptFile> stringPool = strings.createStringBlock();

    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);
    hd->header.size = htodl(dest->getSize()-basePos);

    if (kPrintStringMetrics) {
        fprintf(stderr, "**** total xml size: %zu / %zu%% strings (in %s)\n",
                dest->getSize(), (stringPool->getSize()*100)/dest->getSize(),
                dest->getPath().string());
    }

    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)
{
    if (kIsDebugParse) {
        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)
{
    if (kIsDebugParse) {
        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)
{
    if (kIsDebugParse) {
        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)
{
    if (kIsDebugParse) {
        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 : "";
    if (kIsDebugParse) {
        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)
{
    if (kIsDebugParse) {
        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 (RESOURCES_TOOLS_NAMESPACE != mNamespaceUri) {
        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);
                if (kIsDebug) {
                    printf("Adding attr %s (resid 0x%08x) to pool: idx=%zd\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;
            if (kIsDebug) {
                printf("String %s offset=0x%08zd\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;
    bool writeCurrentNode = true;

    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) {
        if (mNamespaceUri == RESOURCES_TOOLS_NAMESPACE) {
            writeCurrentNode = false;
        } else {
            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));

    if (writeCurrentNode) {
        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) {
        if (writeCurrentNode) {
            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;
}
