//
// 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 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_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(String16 appPackage, 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)) {
        NOISY(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,
                               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;
    const char* errorMsg;
    int xliffDepth = 0;
    bool firstTime = true;

    size_t len;
    ResXMLTree::event_code_t code;
    // Bracketing if pseudolocalization accented method specified.
    if (pseudolocalize == PSEUDO_ACCENTED) {
        curString.append(String16(String8("[")));
    }
    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;
                }
            }
            if (xliffDepth == 0 && pseudolocalize > 0) {
                String16 pseudo;
                if (pseudolocalize == PSEUDO_ACCENTED) {
                    pseudo = pseudolocalize_string(text);
                } else if (pseudolocalize == PSEUDO_BIDI) {
                    pseudo = pseudobidi_string(text);
                } else {
                    pseudo = text;
                }
                curString.append(pseudo);
            } 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
        }
    }

    // Bracketing if pseudolocalization accented method specified.
    if (pseudolocalize == PSEUDO_ACCENTED) {
        const char16_t* str = outString->string();
        const char16_t* p = str;
        const char16_t* e = p + outString->size();
        int words_cnt = 0;
        while (p < e) {
            if (isspace(*p)) {
                words_cnt++;
            }
            p++;
        }
        unsigned int length = words_cnt > 3 ? outString->size() :
            outString->size() / 2;
        curString.append(String16(String8(" ")));
        curString.append(pseudo_generate_expansion(length));
        curString.append(String16(String8("]")));
    }

    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(),
                    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);

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

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

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(String16(assets->getPackage()), 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(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 (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);
                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;
    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;
}
