/* 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_strings.h"

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

#include "apr_xml.h"

#include "apu_config.h"

#if defined(HAVE_XMLPARSE_XMLPARSE_H)
#include <xmlparse/xmlparse.h>
#elif defined(HAVE_XMLTOK_XMLPARSE_H)
#include <xmltok/xmlparse.h>
#elif defined(HAVE_XML_XMLPARSE_H)
#include <xml/xmlparse.h>
#else
#include <expat.h>
#endif

#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' };
static const char APR_KW_DAV[] = { 0x44, 0x41, 0x56, 0x3A, '\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) )


/* the real (internal) definition of the parser context */
struct apr_xml_parser {
    apr_xml_doc *doc;		/* the doc we're parsing */
    apr_pool_t *p;		/* the pool we allocate from */
    apr_xml_elem *cur_elem;	/* current element */

    int error;			/* an error has occurred */
#define APR_XML_ERROR_EXPAT             1
#define APR_XML_ERROR_PARSE_DONE        2
/* also: public APR_XML_NS_ERROR_* values (if any) */

    XML_Parser xp;              /* the actual (Expat) XML parser */
    enum XML_Error xp_err;      /* stored Expat error code */
};

/* 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 = elem->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;
}

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

static apr_status_t cleanup_parser(void *ctx)
{
    apr_xml_parser *parser = ctx;

    XML_ParserFree(parser->xp);
    parser->xp = NULL;

    return APR_SUCCESS;
}

APU_DECLARE(apr_xml_parser *) apr_xml_parser_create(apr_pool_t *pool)
{
    apr_xml_parser *parser = apr_pcalloc(pool, sizeof(*parser));

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

    parser->doc->namespaces = apr_array_make(pool, 5, sizeof(const char *));

    /* ### is there a way to avoid hard-coding this? */
    apr_xml_insert_uri(parser->doc->namespaces, APR_KW_DAV);

    parser->xp = XML_ParserCreate(NULL);
    if (parser->xp == NULL) {
        (*apr_pool_abort_get(pool))(APR_ENOMEM);
        return NULL;
    }

    apr_pool_cleanup_register(pool, parser, cleanup_parser,
                              apr_pool_cleanup_null);

    XML_SetUserData(parser->xp, parser);
    XML_SetElementHandler(parser->xp, start_handler, end_handler);
    XML_SetCharacterDataHandler(parser->xp, cdata_handler);

    return parser;
}

static apr_status_t do_parse(apr_xml_parser *parser,
                             const char *data, apr_size_t len,
                             int is_final)
{
    if (parser->xp == NULL) {
        parser->error = APR_XML_ERROR_PARSE_DONE;
    }
    else {
        int rv = XML_Parse(parser->xp, data, (int)len, is_final);

        if (rv == 0) {
            parser->error = APR_XML_ERROR_EXPAT;
            parser->xp_err = XML_GetErrorCode(parser->xp);
        }
    }

    /* ### better error code? */
    return parser->error ? APR_EGENERAL : APR_SUCCESS;
}

APU_DECLARE(apr_status_t) apr_xml_parser_feed(apr_xml_parser *parser,
                                              const char *data,
                                              apr_size_t len)
{
    return do_parse(parser, data, len, 0 /* is_final */);
}

APU_DECLARE(apr_status_t) apr_xml_parser_done(apr_xml_parser *parser,
                                              apr_xml_doc **pdoc)
{
    char end;
    apr_status_t status = do_parse(parser, &end, 0, 1 /* is_final */);

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

    if (status)
        return status;

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

APU_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)",
                            XML_ErrorString(parser->xp_err), 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;
}

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

APU_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.
*/
APU_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) {
	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;
	    }
	}

	if (elem->ns == APR_XML_NS_NONE) {
	    /* compute size of: <%s> */
	    size += 1 + strlen(elem->name) + 1;
	}
	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 {
		/* 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, 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) {
	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 {
	    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 {
                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;
	    }
	}

	/* 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, 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) {
	if (elem->ns == APR_XML_NS_NONE) {
	    len = sprintf(s, "</%s>", 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;
}

APU_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 */
APU_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;
}

APU_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 */
APU_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 */
APU_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
