/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "apr.h"
#include "apr_private.h"
#include "apr_strings.h"

#define APR_WANT_STDIO          /* for sprintf() */
#define APR_WANT_STRFUNC
#include "apr_want.h"

#include "apr_xml.h"
typedef void* XML_Parser;
typedef int XML_Error;
typedef unsigned char XML_Char;
#include "apr_xml_internal.h"

#define DEBUG_CR "\r\n"

static const char APR_KW_xmlns[] = { 0x78, 0x6D, 0x6C, 0x6E, 0x73, '\0' };
static const char APR_KW_xmlns_lang[] = { 0x78, 0x6D, 0x6C, 0x3A, 0x6C, 0x61, 0x6E, 0x67, '\0' };

/* errors related to namespace processing */
#define APR_XML_NS_ERROR_UNKNOWN_PREFIX (-1000)
#define APR_XML_NS_ERROR_INVALID_DECL (-1001)

/* test for a namespace prefix that begins with [Xx][Mm][Ll] */
#define APR_XML_NS_IS_RESERVED(name) \
        ( (name[0] == 0x58 || name[0] == 0x78) && \
          (name[1] == 0x4D || name[1] == 0x6D) && \
          (name[2] == 0x4C || name[2] == 0x6C) )


/* struct for scoping namespace declarations */
typedef struct apr_xml_ns_scope {
    const char *prefix;         /* prefix used for this ns */
    int ns;                     /* index into namespace table */
    int emptyURI;               /* the namespace URI is the empty string */
    struct apr_xml_ns_scope *next;      /* next scoped namespace */
} apr_xml_ns_scope;


/* return namespace table index for a given prefix */
static int find_prefix(apr_xml_parser *parser, const char *prefix)
{
    apr_xml_elem *elem = parser->cur_elem;

    /*
    ** Walk up the tree, looking for a namespace scope that defines this
    ** prefix.
    */
    for (; elem; elem = elem->parent) {
        apr_xml_ns_scope *ns_scope;

        for (ns_scope = elem->ns_scope; ns_scope; ns_scope = ns_scope->next) {
            if (strcmp(prefix, ns_scope->prefix) == 0) {
                if (ns_scope->emptyURI) {
                    /*
                    ** It is possible to set the default namespace to an
                    ** empty URI string; this resets the default namespace
                    ** to mean "no namespace." We just found the prefix
                    ** refers to an empty URI, so return "no namespace."
                    */
                    return APR_XML_NS_NONE;
                }

                return ns_scope->ns;
            }
        }
    }

    /*
     * If the prefix is empty (""), this means that a prefix was not
     * specified in the element/attribute. The search that was performed
     * just above did not locate a default namespace URI (which is stored
     * into ns_scope with an empty prefix). This means the element/attribute
     * has "no namespace". We have a reserved value for this.
     */
    if (*prefix == '\0') {
        return APR_XML_NS_NONE;
    }

    /* not found */
    return APR_XML_NS_ERROR_UNKNOWN_PREFIX;
}

/* return original prefix given ns index */
static const char * find_prefix_name(const apr_xml_elem *elem, int ns, int parent)
{
    /*
    ** Walk up the tree, looking for a namespace scope that defines this
    ** prefix.
    */
    for (; elem; elem = parent ? elem->parent : NULL) {
       apr_xml_ns_scope *ns_scope = elem->ns_scope;

       for (; ns_scope; ns_scope = ns_scope->next) {
           if (ns_scope->ns == ns)
               return ns_scope->prefix;
       }
    }
    /* not found */
    return "";
}

static void start_handler(void *userdata, const char *name, const char **attrs)
{
    apr_xml_parser *parser = userdata;
    apr_xml_elem *elem;
    apr_xml_attr *attr;
    apr_xml_attr *prev;
    char *colon;
    const char *quoted;
    char *elem_name;

    /* punt once we find an error */
    if (parser->error)
        return;

    elem = apr_pcalloc(parser->p, sizeof(*elem));

    /* prep the element */
    elem->name = elem_name = apr_pstrdup(parser->p, name);

    /* fill in the attributes (note: ends up in reverse order) */
    while (attrs && *attrs) {
        attr = apr_palloc(parser->p, sizeof(*attr));
        attr->name = apr_pstrdup(parser->p, *attrs++);
        attr->value = apr_pstrdup(parser->p, *attrs++);
        attr->next = elem->attr;
        elem->attr = attr;
    }

    /* hook the element into the tree */
    if (parser->cur_elem == NULL) {
        /* no current element; this also becomes the root */
        parser->cur_elem = parser->doc->root = elem;
    }
    else {
        /* this element appeared within the current elem */
        elem->parent = parser->cur_elem;

        /* set up the child/sibling links */
        if (elem->parent->last_child == NULL) {
            /* no first child either */
            elem->parent->first_child = elem->parent->last_child = elem;
        }
        else {
            /* hook onto the end of the parent's children */
            elem->parent->last_child->next = elem;
            elem->parent->last_child = elem;
        }

        /* this element is now the current element */
        parser->cur_elem = elem;
    }

    /* scan the attributes for namespace declarations */
    for (prev = NULL, attr = elem->attr;
         attr;
         attr = attr->next) {
        if (strncmp(attr->name, APR_KW_xmlns, 5) == 0) {
            const char *prefix = &attr->name[5];
            apr_xml_ns_scope *ns_scope;

            /* test for xmlns:foo= form and xmlns= form */
            if (*prefix == 0x3A) {
                /* a namespace prefix declaration must have a
                   non-empty value. */
                if (attr->value[0] == '\0') {
                    parser->error = APR_XML_NS_ERROR_INVALID_DECL;
                    return;
                }
                ++prefix;
            }
            else if (*prefix != '\0') {
                /* advance "prev" since "attr" is still present */
                prev = attr;
                continue;
            }

            /* quote the URI before we ever start working with it */
            quoted = apr_xml_quote_string(parser->p, attr->value, 1);

            /* build and insert the new scope */
            ns_scope = apr_pcalloc(parser->p, sizeof(*ns_scope));
            ns_scope->prefix = prefix;
            ns_scope->ns = apr_xml_insert_uri(parser->doc->namespaces, quoted);
            ns_scope->emptyURI = *quoted == '\0';
            ns_scope->next = elem->ns_scope;
            elem->ns_scope = ns_scope;

            /* remove this attribute from the element */
            if (prev == NULL)
                elem->attr = attr->next;
            else
                prev->next = attr->next;

            /* Note: prev will not be advanced since we just removed "attr" */
        }
        else if (strcmp(attr->name, APR_KW_xmlns_lang) == 0) {
            /* save away the language (in quoted form) */
            elem->lang = apr_xml_quote_string(parser->p, attr->value, 1);

            /* remove this attribute from the element */
            if (prev == NULL)
                elem->attr = attr->next;
            else
                prev->next = attr->next;

            /* Note: prev will not be advanced since we just removed "attr" */
        }
        else {
            /* advance "prev" since "attr" is still present */
            prev = attr;
        }
    }

    /*
    ** If an xml:lang attribute didn't exist (lang==NULL), then copy the
    ** language from the parent element (if present).
    **
    ** NOTE: elem_size() *depends* upon this pointer equality.
    */
    if (elem->lang == NULL && elem->parent != NULL)
        elem->lang = elem->parent->lang;

    /* adjust the element's namespace */
    colon = strchr(elem_name, 0x3A);
    if (colon == NULL) {
        /*
         * The element is using the default namespace, which will always
         * be found. Either it will be "no namespace", or a default
         * namespace URI has been specified at some point.
         */
        elem->ns = find_prefix(parser, "");
    }
    else if (APR_XML_NS_IS_RESERVED(elem->name)) {
        elem->ns = APR_XML_NS_NONE;
    }
    else {
        *colon = '\0';
        elem->ns = find_prefix(parser, elem->name);
        elem->name = colon + 1;

        if (APR_XML_NS_IS_ERROR(elem->ns)) {
            parser->error = elem->ns;
            return;
        }
    }

    /* adjust all remaining attributes' namespaces */
    for (attr = elem->attr; attr; attr = attr->next) {
        /*
         * apr_xml_attr defines this as "const" but we dup'd it, so we
         * know that we can change it. a bit hacky, but the existing
         * structure def is best.
         */
        char *attr_name = (char *)attr->name;

        colon = strchr(attr_name, 0x3A);
        if (colon == NULL) {
            /*
             * Attributes do NOT use the default namespace. Therefore,
             * we place them into the "no namespace" category.
             */
            attr->ns = APR_XML_NS_NONE;
        }
        else if (APR_XML_NS_IS_RESERVED(attr->name)) {
            attr->ns = APR_XML_NS_NONE;
        }
        else {
            *colon = '\0';
            attr->ns = find_prefix(parser, attr->name);
            attr->name = colon + 1;

            if (APR_XML_NS_IS_ERROR(attr->ns)) {
                parser->error = attr->ns;
                return;
            }
        }
    }
}

static void end_handler(void *userdata, const char *name)
{
    apr_xml_parser *parser = userdata;

    /* punt once we find an error */
    if (parser->error)
        return;

    /* pop up one level */
    parser->cur_elem = parser->cur_elem->parent;
}

static void cdata_handler(void *userdata, const char *data, int len)
{
    apr_xml_parser *parser = userdata;
    apr_xml_elem *elem;
    apr_text_header *hdr;
    const char *s;

    /* punt once we find an error */
    if (parser->error)
        return;

    elem = parser->cur_elem;
    s = apr_pstrndup(parser->p, data, len);

    if (elem->last_child == NULL) {
        /* no children yet. this cdata follows the start tag */
        hdr = &elem->first_cdata;
    }
    else {
        /* child elements exist. this cdata follows the last child. */
        hdr = &elem->last_child->following_cdata;
    }

    apr_text_append(parser->p, hdr, s);
}

APR_DECLARE(apr_xml_parser *) apr_xml_parser_create(apr_pool_t *pool)
{
    return apr_xml_parser_create_internal(pool, &start_handler, &end_handler, &cdata_handler);
}

APR_DECLARE(apr_status_t) apr_xml_parser_feed(apr_xml_parser *parser,
                                              const char *data,
                                              apr_size_t len)
{
    return parser->impl->Parse(parser, data, len, 0 /* is_final */);
}

APR_DECLARE(apr_status_t) apr_xml_parser_done(apr_xml_parser *parser,
                                              apr_xml_doc **pdoc)
{
    apr_status_t status = parser->impl->Parse(parser, "", 0, 1 /* is_final */);

    /* get rid of the parser */
    (void) apr_pool_cleanup_run(parser->p, parser, parser->impl->cleanup);

    if (status)
        return status;

    if (pdoc != NULL)
        *pdoc = parser->doc;
    return APR_SUCCESS;
}

APR_DECLARE(char *) apr_xml_parser_geterror(apr_xml_parser *parser,
                                            char *errbuf,
                                            apr_size_t errbufsize)
{
    int error = parser->error;
    const char *msg;

    /* clear our record of an error */
    parser->error = 0;

    switch (error) {
    case 0:
        msg = "No error.";
        break;

    case APR_XML_NS_ERROR_UNKNOWN_PREFIX:
        msg = "An undefined namespace prefix was used.";
        break;

    case APR_XML_NS_ERROR_INVALID_DECL:
        msg = "A namespace prefix was defined with an empty URI.";
        break;

    case APR_XML_ERROR_EXPAT:
        (void) apr_snprintf(errbuf, errbufsize,
                            "XML parser error code: %s (%d)",
                            parser->xp_msg, parser->xp_err);
        return errbuf;

    case APR_XML_ERROR_PARSE_DONE:
        msg = "The parser is not active.";
        break;

    default:
        msg = "There was an unknown error within the XML body.";
        break;
    }

    (void) apr_cpystrn(errbuf, msg, errbufsize);
    return errbuf;
}

APR_DECLARE(apr_status_t) apr_xml_parse_file(apr_pool_t *p,
                                             apr_xml_parser **parser,
                                             apr_xml_doc **ppdoc,
                                             apr_file_t *xmlfd,
                                             apr_size_t buffer_length)
{
    apr_status_t rv;
    char *buffer;
    apr_size_t length;

    *parser = apr_xml_parser_create(p);
    if (*parser == NULL) {
        /* FIXME: returning an error code would be nice,
         * but we dont get one ;( */
        return APR_EGENERAL;
    }
    buffer = apr_palloc(p, buffer_length);
    length = buffer_length;

    rv = apr_file_read(xmlfd, buffer, &length);

    while (rv == APR_SUCCESS) {
        rv = apr_xml_parser_feed(*parser, buffer, length);
        if (rv != APR_SUCCESS) {
            return rv;
        }

        length = buffer_length;
        rv = apr_file_read(xmlfd, buffer, &length);
    }
    if (rv != APR_EOF) {
        return rv;
    }
    rv = apr_xml_parser_done(*parser, ppdoc);
    *parser = NULL;
    return rv;
}

APR_DECLARE(void) apr_text_append(apr_pool_t * p, apr_text_header *hdr,
                                  const char *text)
{
    apr_text *t = apr_palloc(p, sizeof(*t));

    t->text = text;
    t->next = NULL;

    if (hdr->first == NULL) {
        /* no text elements yet */
        hdr->first = hdr->last = t;
    }
    else {
        /* append to the last text element */
        hdr->last->next = t;
        hdr->last = t;
    }
}


/* ---------------------------------------------------------------
**
** XML UTILITY FUNCTIONS
*/

/*
** apr_xml_quote_string: quote an XML string
**
** Replace '<', '>', and '&' with '&lt;', '&gt;', and '&amp;'.
** If quotes is true, then replace '"' with '&quot;'.
**
** quotes is typically set to true for XML strings that will occur within
** double quotes -- attribute values.
*/
APR_DECLARE(const char *) apr_xml_quote_string(apr_pool_t *p, const char *s,
                                               int quotes)
{
    const char *scan;
    apr_size_t len = 0;
    apr_size_t extra = 0;
    char *qstr;
    char *qscan;
    char c;

    for (scan = s; (c = *scan) != '\0'; ++scan, ++len) {
        if (c == '<' || c == '>')
            extra += 3;         /* &lt; or &gt; */
        else if (c == '&')
            extra += 4;         /* &amp; */
        else if (quotes && c == '"')
            extra += 5;         /* &quot; */
    }

    /* nothing to do? */
    if (extra == 0)
        return s;

    qstr = apr_palloc(p, len + extra + 1);
    for (scan = s, qscan = qstr; (c = *scan) != '\0'; ++scan) {
        if (c == '<') {
            *qscan++ = '&';
            *qscan++ = 'l';
            *qscan++ = 't';
            *qscan++ = ';';
        }
        else if (c == '>') {
            *qscan++ = '&';
            *qscan++ = 'g';
            *qscan++ = 't';
            *qscan++ = ';';
        }
        else if (c == '&') {
            *qscan++ = '&';
            *qscan++ = 'a';
            *qscan++ = 'm';
            *qscan++ = 'p';
            *qscan++ = ';';
        }
        else if (quotes && c == '"') {
            *qscan++ = '&';
            *qscan++ = 'q';
            *qscan++ = 'u';
            *qscan++ = 'o';
            *qscan++ = 't';
            *qscan++ = ';';
        }
        else {
            *qscan++ = c;
        }
    }

    *qscan = '\0';
    return qstr;
}

/* how many characters for the given integer? */
#define APR_XML_NS_LEN(ns) ((ns) < 10 ? 1 : (ns) < 100 ? 2 : (ns) < 1000 ? 3 : \
                            (ns) < 10000 ? 4 : (ns) < 100000 ? 5 : \
                            (ns) < 1000000 ? 6 : (ns) < 10000000 ? 7 : \
                            (ns) < 100000000 ? 8 : (ns) < 1000000000 ? 9 : 10)

static apr_size_t text_size(const apr_text *t)
{
    apr_size_t size = 0;

    for (; t; t = t->next)
        size += strlen(t->text);
    return size;
}

static apr_size_t elem_size(const apr_xml_elem *elem, int style,
                            apr_array_header_t *namespaces, int *ns_map)
{
    apr_size_t size;

    if (style == APR_XML_X2T_FULL || style == APR_XML_X2T_FULL_NS_LANG ||
        style == APR_XML_X2T_PARSED) {
        const apr_xml_attr *attr;

        size = 0;

        if (style == APR_XML_X2T_FULL_NS_LANG) {
            int i;

            /*
            ** The outer element will contain xmlns:ns%d="%s" attributes
            ** and an xml:lang attribute, if applicable.
            */

            for (i = namespaces->nelts; i--;) {
                /* compute size of: ' xmlns:ns%d="%s"' */
                size += (9 + APR_XML_NS_LEN(i) + 2 +
                         strlen(APR_XML_GET_URI_ITEM(namespaces, i)) + 1);
            }

            if (elem->lang != NULL) {
                /* compute size of: ' xml:lang="%s"' */
                size += 11 + strlen(elem->lang) + 1;
            }
        }
        else if (style == APR_XML_X2T_PARSED) {
            apr_xml_ns_scope *ns_scope = elem->ns_scope;

            /* compute size of: ' xmlns:%s="%s"' */
            for (; ns_scope; ns_scope = ns_scope->next) {
                size += 10 + strlen(find_prefix_name(elem, ns_scope->ns, 0)) +
                             strlen(APR_XML_GET_URI_ITEM(namespaces, ns_scope->ns));
            }

            if (elem->lang != NULL) {
                /* compute size of: ' xml:lang="%s"' */
                size += 11 + strlen(elem->lang) + 1;
            }
        }

        if (elem->ns == APR_XML_NS_NONE) {
            /* compute size of: <%s> */
            size += 1 + strlen(elem->name) + 1;
        }
        else if (style == APR_XML_X2T_PARSED) {
            /* compute size of: <%s:%s> */
            size += 3 + strlen(find_prefix_name(elem, elem->ns, 1)) + strlen(elem->name);
        }
        else {
            int ns = ns_map ? ns_map[elem->ns] : elem->ns;

            /* compute size of: <ns%d:%s> */
            size += 3 + APR_XML_NS_LEN(ns) + 1 + strlen(elem->name) + 1;
        }

        if (APR_XML_ELEM_IS_EMPTY(elem)) {
            /* insert a closing "/" */
            size += 1;
        }
        else {
            /*
             * two of above plus "/":
             *     <ns%d:%s> ... </ns%d:%s>
             * OR  <%s> ... </%s>
             */
            size = 2 * size + 1;
        }

        for (attr = elem->attr; attr; attr = attr->next) {
            if (attr->ns == APR_XML_NS_NONE) {
                /* compute size of: ' %s="%s"' */
                size += 1 + strlen(attr->name) + 2 + strlen(attr->value) + 1;
            }
            else if (style == APR_XML_X2T_PARSED) {
                /* compute size of: ' %s:%s="%s"' */
                size += 5 + strlen(find_prefix_name(elem, attr->ns, 1)) + strlen(attr->name) + strlen(attr->value);
            }
            else {
                /* compute size of: ' ns%d:%s="%s"' */
                int ns = ns_map ? ns_map[attr->ns] : attr->ns;
                size += 3 + APR_XML_NS_LEN(ns) + 1 + strlen(attr->name) + 2 + strlen(attr->value) + 1;
            }
        }

        /*
        ** If the element has an xml:lang value that is *different* from
        ** its parent, then add the thing in: ' xml:lang="%s"'.
        **
        ** NOTE: we take advantage of the pointer equality established by
        ** the parsing for "inheriting" the xml:lang values from parents.
        */
        if (elem->lang != NULL &&
            (elem->parent == NULL || elem->lang != elem->parent->lang)) {
            size += 11 + strlen(elem->lang) + 1;
        }
    }
    else if (style == APR_XML_X2T_LANG_INNER) {
        /*
         * This style prepends the xml:lang value plus a null terminator.
         * If a lang value is not present, then we insert a null term.
         */
        size = elem->lang ? strlen(elem->lang) + 1 : 1;
    }
    else
        size = 0;

    size += text_size(elem->first_cdata.first);

    for (elem = elem->first_child; elem; elem = elem->next) {
        /* the size of the child element plus the CDATA that follows it */
        size += (elem_size(elem, style == APR_XML_X2T_PARSED ? APR_XML_X2T_PARSED : APR_XML_X2T_FULL, NULL, ns_map) +
                 text_size(elem->following_cdata.first));
    }

    return size;
}

static char *write_text(char *s, const apr_text *t)
{
    for (; t; t = t->next) {
        apr_size_t len = strlen(t->text);
        memcpy(s, t->text, len);
        s += len;
    }
    return s;
}

static char *write_elem(char *s, const apr_xml_elem *elem, int style,
                        apr_array_header_t *namespaces, int *ns_map)
{
    const apr_xml_elem *child;
    apr_size_t len;
    int ns;

    if (style == APR_XML_X2T_FULL || style == APR_XML_X2T_FULL_NS_LANG ||
        style == APR_XML_X2T_PARSED) {
        int empty = APR_XML_ELEM_IS_EMPTY(elem);
        const apr_xml_attr *attr;

        if (elem->ns == APR_XML_NS_NONE) {
            len = sprintf(s, "<%s", elem->name);
        }
        else if (style == APR_XML_X2T_PARSED) {
            len = sprintf(s, "<%s:%s", find_prefix_name(elem, elem->ns, 1), elem->name);
        }
        else {
            ns = ns_map ? ns_map[elem->ns] : elem->ns;
            len = sprintf(s, "<ns%d:%s", ns, elem->name);
        }
        s += len;

        for (attr = elem->attr; attr; attr = attr->next) {
            if (attr->ns == APR_XML_NS_NONE) {
                len = sprintf(s, " %s=\"%s\"", attr->name, attr->value);
            }
            else if (style == APR_XML_X2T_PARSED) {
                len = sprintf(s, " %s:%s=\"%s\"",
                              find_prefix_name(elem, attr->ns, 1), attr->name, attr->value);
            }
            else {
                ns = ns_map ? ns_map[attr->ns] : attr->ns;
                len = sprintf(s, " ns%d:%s=\"%s\"", ns, attr->name, attr->value);
            }
            s += len;
        }

        /* add the xml:lang value if necessary */
        if (elem->lang != NULL &&
            (style == APR_XML_X2T_FULL_NS_LANG ||
             elem->parent == NULL ||
             elem->lang != elem->parent->lang)) {
            len = sprintf(s, " xml:lang=\"%s\"", elem->lang);
            s += len;
        }

        /* add namespace definitions, if required */
        if (style == APR_XML_X2T_FULL_NS_LANG) {
            int i;

            for (i = namespaces->nelts; i--;) {
                len = sprintf(s, " xmlns:ns%d=\"%s\"", i,
                              APR_XML_GET_URI_ITEM(namespaces, i));
                s += len;
            }
        }

        else if (style == APR_XML_X2T_PARSED) {
            apr_xml_ns_scope *ns_scope = elem->ns_scope;

            for (; ns_scope; ns_scope = ns_scope->next) {
                const char *prefix = find_prefix_name(elem, ns_scope->ns, 0);

                len = sprintf(s, " xmlns%s%s=\"%s\"",
                              *prefix ? ":" : "", *prefix ? prefix : "",
                              APR_XML_GET_URI_ITEM(namespaces, ns_scope->ns));
                s += len;
            }
        }

        /* no more to do. close it up and go. */
        if (empty) {
            *s++ = '/';
            *s++ = '>';
            return s;
        }

        /* just close it */
        *s++ = '>';
    }
    else if (style == APR_XML_X2T_LANG_INNER) {
        /* prepend the xml:lang value */
        if (elem->lang != NULL) {
            len = strlen(elem->lang);
            memcpy(s, elem->lang, len);
            s += len;
        }
        *s++ = '\0';
    }

    s = write_text(s, elem->first_cdata.first);

    for (child = elem->first_child; child; child = child->next) {
        s = write_elem(s, child,
                       style == APR_XML_X2T_PARSED ? APR_XML_X2T_PARSED : APR_XML_X2T_FULL,
                       NULL, ns_map);
        s = write_text(s, child->following_cdata.first);
    }

    if (style == APR_XML_X2T_FULL || style == APR_XML_X2T_FULL_NS_LANG ||
        style == APR_XML_X2T_PARSED) {
        if (elem->ns == APR_XML_NS_NONE) {
            len = sprintf(s, "</%s>", elem->name);
        }
        else if (style == APR_XML_X2T_PARSED) {
            len = sprintf(s, "</%s:%s>", find_prefix_name(elem, elem->ns, 1), elem->name);
        }
        else {
            ns = ns_map ? ns_map[elem->ns] : elem->ns;
            len = sprintf(s, "</ns%d:%s>", ns, elem->name);
        }
        s += len;
    }

    return s;
}

APR_DECLARE(void) apr_xml_quote_elem(apr_pool_t *p, apr_xml_elem *elem)
{
    apr_text *scan_txt;
    apr_xml_attr *scan_attr;
    apr_xml_elem *scan_elem;

    /* convert the element's text */
    for (scan_txt = elem->first_cdata.first;
         scan_txt != NULL;
         scan_txt = scan_txt->next) {
        scan_txt->text = apr_xml_quote_string(p, scan_txt->text, 0);
    }
    for (scan_txt = elem->following_cdata.first;
         scan_txt != NULL;
         scan_txt = scan_txt->next) {
        scan_txt->text = apr_xml_quote_string(p, scan_txt->text, 0);
    }

    /* convert the attribute values */
    for (scan_attr = elem->attr;
         scan_attr != NULL;
         scan_attr = scan_attr->next) {
        scan_attr->value = apr_xml_quote_string(p, scan_attr->value, 1);
    }

    /* convert the child elements */
    for (scan_elem = elem->first_child;
         scan_elem != NULL;
         scan_elem = scan_elem->next) {
        apr_xml_quote_elem(p, scan_elem);
    }
}

/* convert an element to a text string */
APR_DECLARE(void) apr_xml_to_text(apr_pool_t * p, const apr_xml_elem *elem,
                                  int style, apr_array_header_t *namespaces,
                                  int *ns_map, const char **pbuf,
                                  apr_size_t *psize)
{
    /* get the exact size, plus a null terminator */
    apr_size_t size = elem_size(elem, style, namespaces, ns_map) + 1;
    char *s = apr_palloc(p, size);

    (void) write_elem(s, elem, style, namespaces, ns_map);
    s[size - 1] = '\0';

    *pbuf = s;
    if (psize)
        *psize = size;
}

APR_DECLARE(const char *) apr_xml_empty_elem(apr_pool_t * p,
                                             const apr_xml_elem *elem)
{
    if (elem->ns == APR_XML_NS_NONE) {
        /*
         * The prefix (xml...) is already within the prop name, or
         * the element simply has no prefix.
         */
        return apr_psprintf(p, "<%s/>" DEBUG_CR, elem->name);
    }

    return apr_psprintf(p, "<ns%d:%s/>" DEBUG_CR, elem->ns, elem->name);
}

/* return the URI's (existing) index, or insert it and return a new index */
APR_DECLARE(int) apr_xml_insert_uri(apr_array_header_t *uri_array,
                                    const char *uri)
{
    int i;
    const char **pelt;

    /* never insert an empty URI; this index is always APR_XML_NS_NONE */
    if (*uri == '\0')
        return APR_XML_NS_NONE;

    for (i = uri_array->nelts; i--;) {
        if (strcmp(uri, APR_XML_GET_URI_ITEM(uri_array, i)) == 0)
            return i;
    }

    pelt = apr_array_push(uri_array);
    *pelt = uri;                /* assume uri is const or in a pool */
    return uri_array->nelts - 1;
}

/* convert the element to EBCDIC */
#if APR_CHARSET_EBCDIC
static apr_status_t apr_xml_parser_convert_elem(apr_xml_elem *e,
                                                apr_xlate_t *convset)
{
    apr_xml_attr *a;
    apr_xml_elem *ec;
    apr_text *t;
    apr_size_t inbytes_left, outbytes_left;
    apr_status_t status;

    inbytes_left = outbytes_left = strlen(e->name);
    status = apr_xlate_conv_buffer(convset, e->name,  &inbytes_left, (char *) e->name, &outbytes_left);
    if (status) {
        return status;
    }

    for (t = e->first_cdata.first; t != NULL; t = t->next) {
        inbytes_left = outbytes_left = strlen(t->text);
        status = apr_xlate_conv_buffer(convset, t->text, &inbytes_left, (char *) t->text, &outbytes_left);
        if (status) {
            return status;
        }
    }

    for (t = e->following_cdata.first;  t != NULL; t = t->next) {
        inbytes_left = outbytes_left = strlen(t->text);
        status = apr_xlate_conv_buffer(convset, t->text, &inbytes_left, (char *) t->text, &outbytes_left);
        if (status) {
            return status;
        }
    }

    for (a = e->attr; a != NULL; a = a->next) {
        inbytes_left = outbytes_left = strlen(a->name);
        status = apr_xlate_conv_buffer(convset, a->name, &inbytes_left, (char *) a->name, &outbytes_left);
        if (status) {
            return status;
        }
        inbytes_left = outbytes_left = strlen(a->value);
        status = apr_xlate_conv_buffer(convset, a->value, &inbytes_left, (char *) a->value, &outbytes_left);
        if (status) {
            return status;
        }
    }

    for (ec = e->first_child; ec != NULL; ec = ec->next) {
        status = apr_xml_parser_convert_elem(ec, convset);
        if (status) {
            return status;
        }
    }
    return APR_SUCCESS;
}

/* convert the whole document to EBCDIC */
APR_DECLARE(apr_status_t) apr_xml_parser_convert_doc(apr_pool_t *pool,
                                                     apr_xml_doc *pdoc,
                                                     apr_xlate_t *convset)
{
    apr_status_t status;
    /* Don't convert the namespaces: they are constant! */
    if (pdoc->namespaces != NULL) {
        int i;
        apr_array_header_t *namespaces;
        namespaces = apr_array_make(pool, pdoc->namespaces->nelts, sizeof(const char *));
        if (namespaces == NULL)
            return APR_ENOMEM;
        for (i = 0; i < pdoc->namespaces->nelts; i++) {
            apr_size_t inbytes_left, outbytes_left;
            char *ptr = (char *) APR_XML_GET_URI_ITEM(pdoc->namespaces, i);
            ptr = apr_pstrdup(pool, ptr);
            if ( ptr == NULL)
                return APR_ENOMEM;
            inbytes_left = outbytes_left = strlen(ptr);
            status = apr_xlate_conv_buffer(convset, ptr, &inbytes_left, ptr, &outbytes_left);
            if (status) {
                return status;
            }
            apr_xml_insert_uri(namespaces, ptr);
        }
        pdoc->namespaces = namespaces;
    }
    return apr_xml_parser_convert_elem(pdoc->root, convset);
}
#endif
