/* 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)
{
    char end;
    apr_status_t status = parser->impl->Parse(parser, &end, 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
