/*
 * xmlreader.c: implements the xmlTextReader streaming node API
 *
 * NOTE:
 *   XmlTextReader.Normalization Property won't be supported, since
 *     it makes the parser non compliant to the XML recommendation
 *
 * See Copyright for the status of this software.
 *
 * daniel@veillard.com
 */

/*
 * TODOs:
 *   - XML Schemas validation
 */
#define IN_LIBXML
#include "libxml.h"

#ifdef LIBXML_READER_ENABLED
#include <string.h> /* for memset() only ! */
#include <stdarg.h>
#include <ctype.h>
#include <stdlib.h>

#include <libxml/xmlmemory.h>
#include <libxml/xmlIO.h>
#include <libxml/xmlreader.h>
#include <libxml/parserInternals.h>
#ifdef LIBXML_SCHEMAS_ENABLED
#include <libxml/relaxng.h>
#include <libxml/xmlschemas.h>
#endif
#include <libxml/uri.h>
#ifdef LIBXML_XINCLUDE_ENABLED
#include <libxml/xinclude.h>
#endif
#ifdef LIBXML_PATTERN_ENABLED
#include <libxml/pattern.h>
#endif

#include "private/buf.h"
#include "private/tree.h"
#ifdef LIBXML_XINCLUDE_ENABLED
#include "private/xinclude.h"
#endif

#define MAX_ERR_MSG_SIZE 64000

#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
/* Keeping free objects can hide memory errors. */
#define MAX_FREE_NODES 1
#else
#define MAX_FREE_NODES 100
#endif

/*
 * The following VA_COPY was coded following an example in
 * the Samba project.  It may not be sufficient for some
 * esoteric implementations of va_list but (hopefully) will
 * be sufficient for libxml2.
 */
#ifndef VA_COPY
  #ifdef HAVE_VA_COPY
    #define VA_COPY(dest, src) va_copy(dest, src)
  #else
    #ifdef HAVE___VA_COPY
      #define VA_COPY(dest,src) __va_copy(dest, src)
    #else
      #ifndef VA_LIST_IS_ARRAY
        #define VA_COPY(dest,src) (dest) = (src)
      #else
        #include <string.h>
        #define VA_COPY(dest,src) memcpy((char *)(dest),(char *)(src),sizeof(va_list))
      #endif
    #endif
  #endif
#endif

/**
 * TODO:
 *
 * macro to flag unimplemented blocks
 */
#define TODO								\
    xmlGenericError(xmlGenericErrorContext,				\
	    "Unimplemented block at %s:%d\n",				\
            __FILE__, __LINE__);

#define CHUNK_SIZE 512
/************************************************************************
 *									*
 *	The parser: maps the Text Reader API on top of the existing	*
 *		parsing routines building a tree			*
 *									*
 ************************************************************************/

#define XML_TEXTREADER_INPUT	1
#define XML_TEXTREADER_CTXT	2

typedef enum {
    XML_TEXTREADER_NONE = -1,
    XML_TEXTREADER_START= 0,
    XML_TEXTREADER_ELEMENT= 1,
    XML_TEXTREADER_END= 2,
    XML_TEXTREADER_EMPTY= 3,
    XML_TEXTREADER_BACKTRACK= 4,
    XML_TEXTREADER_DONE= 5,
    XML_TEXTREADER_ERROR= 6
} xmlTextReaderState;

typedef enum {
    XML_TEXTREADER_NOT_VALIDATE = 0,
    XML_TEXTREADER_VALIDATE_DTD = 1,
    XML_TEXTREADER_VALIDATE_RNG = 2,
    XML_TEXTREADER_VALIDATE_XSD = 4
} xmlTextReaderValidate;

struct _xmlTextReader {
    int				mode;	/* the parsing mode */
    xmlDocPtr			doc;    /* when walking an existing doc */
    xmlTextReaderValidate       validate;/* is there any validation */
    int				allocs;	/* what structure were deallocated */
    xmlTextReaderState		state;
    xmlParserCtxtPtr		ctxt;	/* the parser context */
    xmlSAXHandlerPtr		sax;	/* the parser SAX callbacks */
    xmlParserInputBufferPtr	input;	/* the input */
    startElementSAXFunc		startElement;/* initial SAX callbacks */
    endElementSAXFunc		endElement;  /* idem */
    startElementNsSAX2Func	startElementNs;/* idem */
    endElementNsSAX2Func	endElementNs;  /* idem */
    charactersSAXFunc		characters;
    cdataBlockSAXFunc		cdataBlock;
    unsigned int		base;	/* base of the segment in the input */
    unsigned int		cur;	/* current position in the input */
    xmlNodePtr			node;	/* current node */
    xmlNodePtr			curnode;/* current attribute node */
    int				depth;  /* depth of the current node */
    xmlNodePtr			faketext;/* fake xmlNs chld */
    int				preserve;/* preserve the resulting document */
    xmlBufPtr		        buffer; /* used to return const xmlChar * */
    xmlDictPtr			dict;	/* the context dictionary */

    /* entity stack when traversing entities content */
    xmlNodePtr         ent;          /* Current Entity Ref Node */
    int                entNr;        /* Depth of the entities stack */
    int                entMax;       /* Max depth of the entities stack */
    xmlNodePtr        *entTab;       /* array of entities */

    /* error handling */
    xmlTextReaderErrorFunc errorFunc;    /* callback function */
    void                  *errorFuncArg; /* callback function user argument */

#ifdef LIBXML_SCHEMAS_ENABLED
    /* Handling of RelaxNG validation */
    xmlRelaxNGPtr          rngSchemas;	/* The Relax NG schemas */
    xmlRelaxNGValidCtxtPtr rngValidCtxt;/* The Relax NG validation context */
    int                    rngPreserveCtxt; /* 1 if the context was provided by the user */
    int                    rngValidErrors;/* The number of errors detected */
    xmlNodePtr             rngFullNode;	/* the node if RNG not progressive */
    /* Handling of Schemas validation */
    xmlSchemaPtr          xsdSchemas;	/* The Schemas schemas */
    xmlSchemaValidCtxtPtr xsdValidCtxt;/* The Schemas validation context */
    int                   xsdPreserveCtxt; /* 1 if the context was provided by the user */
    int                   xsdValidErrors;/* The number of errors detected */
    xmlSchemaSAXPlugPtr   xsdPlug;	/* the schemas plug in SAX pipeline */
#endif
#ifdef LIBXML_XINCLUDE_ENABLED
    /* Handling of XInclude processing */
    int                xinclude;	/* is xinclude asked for */
    const xmlChar *    xinclude_name;	/* the xinclude name from dict */
    xmlXIncludeCtxtPtr xincctxt;	/* the xinclude context */
    int                in_xinclude;	/* counts for xinclude */
#endif
#ifdef LIBXML_PATTERN_ENABLED
    int                patternNr;       /* number of preserve patterns */
    int                patternMax;      /* max preserve patterns */
    xmlPatternPtr     *patternTab;      /* array of preserve patterns */
#endif
    int                preserves;	/* level of preserves */
    int                parserFlags;	/* the set of options set */
    /* Structured error handling */
    xmlStructuredErrorFunc sErrorFunc;  /* callback function */
};

#define NODE_IS_EMPTY		0x1
#define NODE_IS_PRESERVED	0x2
#define NODE_IS_SPRESERVED	0x4

/**
 * CONSTSTR:
 *
 * Macro used to return an interned string
 */
#define CONSTSTR(str) xmlDictLookup(reader->dict, (str), -1)
#define CONSTQSTR(p, str) xmlDictQLookup(reader->dict, (p), (str))

static int xmlTextReaderReadTree(xmlTextReaderPtr reader);
static int xmlTextReaderNextTree(xmlTextReaderPtr reader);

/************************************************************************
 *									*
 *	Our own version of the freeing routines as we recycle nodes	*
 *									*
 ************************************************************************/
/**
 * DICT_FREE:
 * @str:  a string
 *
 * Free a string if it is not owned by the "dict" dictionary in the
 * current scope
 */
#define DICT_FREE(str)						\
	if ((str) && ((!dict) ||				\
	    (xmlDictOwns(dict, (const xmlChar *)(str)) == 0)))	\
	    xmlFree((char *)(str));

static void xmlTextReaderFreeNode(xmlTextReaderPtr reader, xmlNodePtr cur);
static void xmlTextReaderFreeNodeList(xmlTextReaderPtr reader, xmlNodePtr cur);

/**
 * xmlTextReaderFreeProp:
 * @reader:  the xmlTextReaderPtr used
 * @cur:  the node
 *
 * Free a node.
 */
static void
xmlTextReaderFreeProp(xmlTextReaderPtr reader, xmlAttrPtr cur) {
    xmlDictPtr dict;

    if ((reader != NULL) && (reader->ctxt != NULL))
	dict = reader->ctxt->dict;
    else
        dict = NULL;
    if (cur == NULL) return;

    if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
	xmlDeregisterNodeDefaultValue((xmlNodePtr) cur);

    if (cur->children != NULL)
        xmlTextReaderFreeNodeList(reader, cur->children);

    DICT_FREE(cur->name);
    if ((reader != NULL) && (reader->ctxt != NULL) &&
        (reader->ctxt->freeAttrsNr < MAX_FREE_NODES)) {
        cur->next = reader->ctxt->freeAttrs;
	reader->ctxt->freeAttrs = cur;
	reader->ctxt->freeAttrsNr++;
    } else {
	xmlFree(cur);
    }
}

/**
 * xmlTextReaderFreePropList:
 * @reader:  the xmlTextReaderPtr used
 * @cur:  the first property in the list
 *
 * Free a property and all its siblings, all the children are freed too.
 */
static void
xmlTextReaderFreePropList(xmlTextReaderPtr reader, xmlAttrPtr cur) {
    xmlAttrPtr next;

    while (cur != NULL) {
        next = cur->next;
        xmlTextReaderFreeProp(reader, cur);
	cur = next;
    }
}

/**
 * xmlTextReaderFreeNodeList:
 * @reader:  the xmlTextReaderPtr used
 * @cur:  the first node in the list
 *
 * Free a node and all its siblings, this is a recursive behaviour, all
 * the children are freed too.
 */
static void
xmlTextReaderFreeNodeList(xmlTextReaderPtr reader, xmlNodePtr cur) {
    xmlNodePtr next;
    xmlNodePtr parent;
    xmlDictPtr dict;
    size_t depth = 0;

    if ((reader != NULL) && (reader->ctxt != NULL))
	dict = reader->ctxt->dict;
    else
        dict = NULL;
    if (cur == NULL) return;
    if (cur->type == XML_NAMESPACE_DECL) {
	xmlFreeNsList((xmlNsPtr) cur);
	return;
    }
    if ((cur->type == XML_DOCUMENT_NODE) ||
	(cur->type == XML_HTML_DOCUMENT_NODE)) {
	xmlFreeDoc((xmlDocPtr) cur);
	return;
    }
    while (1) {
        while ((cur->type != XML_DTD_NODE) &&
               (cur->type != XML_ENTITY_REF_NODE) &&
               (cur->children != NULL) &&
               (cur->children->parent == cur)) {
            cur = cur->children;
            depth += 1;
        }

        next = cur->next;
        parent = cur->parent;

	/* unroll to speed up freeing the document */
	if (cur->type != XML_DTD_NODE) {

	    if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
		xmlDeregisterNodeDefaultValue(cur);

	    if (((cur->type == XML_ELEMENT_NODE) ||
		 (cur->type == XML_XINCLUDE_START) ||
		 (cur->type == XML_XINCLUDE_END)) &&
		(cur->properties != NULL))
		xmlTextReaderFreePropList(reader, cur->properties);
	    if ((cur->content != (xmlChar *) &(cur->properties)) &&
	        (cur->type != XML_ELEMENT_NODE) &&
		(cur->type != XML_XINCLUDE_START) &&
		(cur->type != XML_XINCLUDE_END) &&
		(cur->type != XML_ENTITY_REF_NODE)) {
		DICT_FREE(cur->content);
	    }
	    if (((cur->type == XML_ELEMENT_NODE) ||
	         (cur->type == XML_XINCLUDE_START) ||
		 (cur->type == XML_XINCLUDE_END)) &&
		(cur->nsDef != NULL))
		xmlFreeNsList(cur->nsDef);

	    /*
	     * we don't free element names here they are interned now
	     */
	    if ((cur->type != XML_TEXT_NODE) &&
		(cur->type != XML_COMMENT_NODE))
		DICT_FREE(cur->name);
	    if (((cur->type == XML_ELEMENT_NODE) ||
		 (cur->type == XML_TEXT_NODE)) &&
	        (reader != NULL) && (reader->ctxt != NULL) &&
		(reader->ctxt->freeElemsNr < MAX_FREE_NODES)) {
	        cur->next = reader->ctxt->freeElems;
		reader->ctxt->freeElems = cur;
		reader->ctxt->freeElemsNr++;
	    } else {
		xmlFree(cur);
	    }
	}

        if (next != NULL) {
	    cur = next;
        } else {
            if ((depth == 0) || (parent == NULL))
                break;
            depth -= 1;
            cur = parent;
            cur->children = NULL;
        }
    }
}

/**
 * xmlTextReaderFreeNode:
 * @reader:  the xmlTextReaderPtr used
 * @cur:  the node
 *
 * Free a node, this is a recursive behaviour, all the children are freed too.
 * This doesn't unlink the child from the list, use xmlUnlinkNode() first.
 */
static void
xmlTextReaderFreeNode(xmlTextReaderPtr reader, xmlNodePtr cur) {
    xmlDictPtr dict;

    if ((reader != NULL) && (reader->ctxt != NULL))
	dict = reader->ctxt->dict;
    else
        dict = NULL;
    if (cur->type == XML_DTD_NODE) {
	xmlFreeDtd((xmlDtdPtr) cur);
	return;
    }
    if (cur->type == XML_NAMESPACE_DECL) {
	xmlFreeNs((xmlNsPtr) cur);
        return;
    }
    if (cur->type == XML_ATTRIBUTE_NODE) {
	xmlTextReaderFreeProp(reader, (xmlAttrPtr) cur);
	return;
    }

    if ((cur->children != NULL) &&
	(cur->type != XML_ENTITY_REF_NODE)) {
	if (cur->children->parent == cur)
	    xmlTextReaderFreeNodeList(reader, cur->children);
	cur->children = NULL;
    }

    if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
	xmlDeregisterNodeDefaultValue(cur);

    if (((cur->type == XML_ELEMENT_NODE) ||
	 (cur->type == XML_XINCLUDE_START) ||
	 (cur->type == XML_XINCLUDE_END)) &&
	(cur->properties != NULL))
	xmlTextReaderFreePropList(reader, cur->properties);
    if ((cur->content != (xmlChar *) &(cur->properties)) &&
        (cur->type != XML_ELEMENT_NODE) &&
	(cur->type != XML_XINCLUDE_START) &&
	(cur->type != XML_XINCLUDE_END) &&
	(cur->type != XML_ENTITY_REF_NODE)) {
	DICT_FREE(cur->content);
    }
    if (((cur->type == XML_ELEMENT_NODE) ||
	 (cur->type == XML_XINCLUDE_START) ||
	 (cur->type == XML_XINCLUDE_END)) &&
	(cur->nsDef != NULL))
	xmlFreeNsList(cur->nsDef);

    /*
     * we don't free names here they are interned now
     */
    if ((cur->type != XML_TEXT_NODE) &&
        (cur->type != XML_COMMENT_NODE))
	DICT_FREE(cur->name);

    if (((cur->type == XML_ELEMENT_NODE) ||
	 (cur->type == XML_TEXT_NODE)) &&
	(reader != NULL) && (reader->ctxt != NULL) &&
	(reader->ctxt->freeElemsNr < MAX_FREE_NODES)) {
	cur->next = reader->ctxt->freeElems;
	reader->ctxt->freeElems = cur;
	reader->ctxt->freeElemsNr++;
    } else {
	xmlFree(cur);
    }
}

/**
 * xmlTextReaderFreeDoc:
 * @reader:  the xmlTextReaderPtr used
 * @cur:  pointer to the document
 *
 * Free up all the structures used by a document, tree included.
 */
static void
xmlTextReaderFreeDoc(xmlTextReaderPtr reader, xmlDocPtr cur) {
    xmlDtdPtr extSubset, intSubset;

    if (cur == NULL) return;

    if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
	xmlDeregisterNodeDefaultValue((xmlNodePtr) cur);

    /*
     * Do this before freeing the children list to avoid ID lookups
     */
    if (cur->ids != NULL) xmlFreeIDTable((xmlIDTablePtr) cur->ids);
    cur->ids = NULL;
    if (cur->refs != NULL) xmlFreeRefTable((xmlRefTablePtr) cur->refs);
    cur->refs = NULL;
    extSubset = cur->extSubset;
    intSubset = cur->intSubset;
    if (intSubset == extSubset)
	extSubset = NULL;
    if (extSubset != NULL) {
	xmlUnlinkNode((xmlNodePtr) cur->extSubset);
	cur->extSubset = NULL;
	xmlFreeDtd(extSubset);
    }
    if (intSubset != NULL) {
	xmlUnlinkNode((xmlNodePtr) cur->intSubset);
	cur->intSubset = NULL;
	xmlFreeDtd(intSubset);
    }

    if (cur->children != NULL) xmlTextReaderFreeNodeList(reader, cur->children);

    if (cur->version != NULL) xmlFree((char *) cur->version);
    if (cur->name != NULL) xmlFree((char *) cur->name);
    if (cur->encoding != NULL) xmlFree((char *) cur->encoding);
    if (cur->oldNs != NULL) xmlFreeNsList(cur->oldNs);
    if (cur->URL != NULL) xmlFree((char *) cur->URL);
    if (cur->dict != NULL) xmlDictFree(cur->dict);

    xmlFree(cur);
}

/************************************************************************
 *									*
 *			The reader core parser				*
 *									*
 ************************************************************************/

/**
 * xmlTextReaderEntPush:
 * @reader:  the xmlTextReaderPtr used
 * @value:  the entity reference node
 *
 * Pushes a new entity reference node on top of the entities stack
 *
 * Returns -1 in case of error, the index in the stack otherwise
 */
static int
xmlTextReaderEntPush(xmlTextReaderPtr reader, xmlNodePtr value)
{
    if (reader->entNr >= reader->entMax) {
        size_t newSize = reader->entMax == 0 ? 10 : reader->entMax * 2;
        xmlNodePtr *tmp;

        tmp = (xmlNodePtr *) xmlRealloc(reader->entTab,
                                        newSize * sizeof(*tmp));
        if (tmp == NULL) {
            xmlGenericError(xmlGenericErrorContext, "xmlRealloc failed !\n");
            return (-1);
        }
        reader->entTab = tmp;
        reader->entMax = newSize;
    }
    reader->entTab[reader->entNr] = value;
    reader->ent = value;
    return (reader->entNr++);
}

/**
 * xmlTextReaderEntPop:
 * @reader:  the xmlTextReaderPtr used
 *
 * Pops the top element entity from the entities stack
 *
 * Returns the entity just removed
 */
static xmlNodePtr
xmlTextReaderEntPop(xmlTextReaderPtr reader)
{
    xmlNodePtr ret;

    if (reader->entNr <= 0)
        return (NULL);
    reader->entNr--;
    if (reader->entNr > 0)
        reader->ent = reader->entTab[reader->entNr - 1];
    else
        reader->ent = NULL;
    ret = reader->entTab[reader->entNr];
    reader->entTab[reader->entNr] = NULL;
    return (ret);
}

/**
 * xmlTextReaderStartElement:
 * @ctx: the user data (XML parser context)
 * @fullname:  The element name, including namespace prefix
 * @atts:  An array of name/value attributes pairs, NULL terminated
 *
 * called when an opening tag has been processed.
 */
static void
xmlTextReaderStartElement(void *ctx, const xmlChar *fullname,
	                  const xmlChar **atts) {
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
    xmlTextReaderPtr reader = ctxt->_private;

    if ((reader != NULL) && (reader->startElement != NULL)) {
	reader->startElement(ctx, fullname, atts);
	if ((ctxt->node != NULL) && (ctxt->input != NULL) &&
	    (ctxt->input->cur != NULL) && (ctxt->input->cur[0] == '/') &&
	    (ctxt->input->cur[1] == '>'))
	    ctxt->node->extra = NODE_IS_EMPTY;
    }
    if (reader != NULL)
	reader->state = XML_TEXTREADER_ELEMENT;
}

/**
 * xmlTextReaderEndElement:
 * @ctx: the user data (XML parser context)
 * @fullname:  The element name, including namespace prefix
 *
 * called when an ending tag has been processed.
 */
static void
xmlTextReaderEndElement(void *ctx, const xmlChar *fullname) {
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
    xmlTextReaderPtr reader = ctxt->_private;

    if ((reader != NULL) && (reader->endElement != NULL)) {
	reader->endElement(ctx, fullname);
    }
}

/**
 * xmlTextReaderStartElementNs:
 * @ctx: the user data (XML parser context)
 * @localname:  the local name of the element
 * @prefix:  the element namespace prefix if available
 * @URI:  the element namespace name if available
 * @nb_namespaces:  number of namespace definitions on that node
 * @namespaces:  pointer to the array of prefix/URI pairs namespace definitions
 * @nb_attributes:  the number of attributes on that node
 * nb_defaulted:  the number of defaulted attributes.
 * @attributes:  pointer to the array of (localname/prefix/URI/value/end)
 *               attribute values.
 *
 * called when an opening tag has been processed.
 */
static void
xmlTextReaderStartElementNs(void *ctx,
                      const xmlChar *localname,
		      const xmlChar *prefix,
		      const xmlChar *URI,
		      int nb_namespaces,
		      const xmlChar **namespaces,
		      int nb_attributes,
		      int nb_defaulted,
		      const xmlChar **attributes)
{
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
    xmlTextReaderPtr reader = ctxt->_private;

    if ((reader != NULL) && (reader->startElementNs != NULL)) {
	reader->startElementNs(ctx, localname, prefix, URI, nb_namespaces,
	                       namespaces, nb_attributes, nb_defaulted,
			       attributes);
	if ((ctxt->node != NULL) && (ctxt->input != NULL) &&
	    (ctxt->input->cur != NULL) && (ctxt->input->cur[0] == '/') &&
	    (ctxt->input->cur[1] == '>'))
	    ctxt->node->extra = NODE_IS_EMPTY;
    }
    if (reader != NULL)
	reader->state = XML_TEXTREADER_ELEMENT;
}

/**
 * xmlTextReaderEndElementNs:
 * @ctx: the user data (XML parser context)
 * @localname:  the local name of the element
 * @prefix:  the element namespace prefix if available
 * @URI:  the element namespace name if available
 *
 * called when an ending tag has been processed.
 */
static void
xmlTextReaderEndElementNs(void *ctx,
                          const xmlChar * localname,
                          const xmlChar * prefix,
		          const xmlChar * URI)
{
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
    xmlTextReaderPtr reader = ctxt->_private;

    if ((reader != NULL) && (reader->endElementNs != NULL)) {
	reader->endElementNs(ctx, localname, prefix, URI);
    }
}


/**
 * xmlTextReaderCharacters:
 * @ctx: the user data (XML parser context)
 * @ch:  a xmlChar string
 * @len: the number of xmlChar
 *
 * receiving some chars from the parser.
 */
static void
xmlTextReaderCharacters(void *ctx, const xmlChar *ch, int len)
{
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
    xmlTextReaderPtr reader = ctxt->_private;

    if ((reader != NULL) && (reader->characters != NULL)) {
	reader->characters(ctx, ch, len);
    }
}

/**
 * xmlTextReaderCDataBlock:
 * @ctx: the user data (XML parser context)
 * @value:  The pcdata content
 * @len:  the block length
 *
 * called when a pcdata block has been parsed
 */
static void
xmlTextReaderCDataBlock(void *ctx, const xmlChar *ch, int len)
{
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
    xmlTextReaderPtr reader = ctxt->_private;

    if ((reader != NULL) && (reader->cdataBlock != NULL)) {
	reader->cdataBlock(ctx, ch, len);
    }
}

/**
 * xmlTextReaderPushData:
 * @reader:  the xmlTextReaderPtr used
 *
 * Push data down the progressive parser until a significant callback
 * got raised.
 *
 * Returns -1 in case of failure, 0 otherwise
 */
static int
xmlTextReaderPushData(xmlTextReaderPtr reader) {
    xmlBufPtr inbuf;
    int val, s;
    xmlTextReaderState oldstate;

    if ((reader->input == NULL) || (reader->input->buffer == NULL))
	return(-1);

    oldstate = reader->state;
    reader->state = XML_TEXTREADER_NONE;
    inbuf = reader->input->buffer;

    while (reader->state == XML_TEXTREADER_NONE) {
	if (xmlBufUse(inbuf) < reader->cur + CHUNK_SIZE) {
	    /*
	     * Refill the buffer unless we are at the end of the stream
	     */
	    if (reader->mode != XML_TEXTREADER_MODE_EOF) {
		val = xmlParserInputBufferRead(reader->input, 4096);
		if (val == 0) {
		    if (xmlBufUse(inbuf) == reader->cur) {
			reader->mode = XML_TEXTREADER_MODE_EOF;
                        break;
		    }
		} else if (val < 0) {
                    xmlGenericError(xmlGenericErrorContext,
                                    "xmlParserInputBufferRead failed\n");
		    reader->mode = XML_TEXTREADER_MODE_EOF;
		    reader->state = oldstate;
		    return(val);
		}

	    } else
		break;
	}
	/*
	 * parse by block of CHUNK_SIZE bytes, various tests show that
	 * it's the best tradeoff at least on a 1.2GH Duron
	 */
	if (xmlBufUse(inbuf) >= reader->cur + CHUNK_SIZE) {
	    val = xmlParseChunk(reader->ctxt,
                 (const char *) xmlBufContent(inbuf) + reader->cur,
                                CHUNK_SIZE, 0);
	    reader->cur += CHUNK_SIZE;
	    if (val != 0)
		reader->ctxt->wellFormed = 0;
	    if (reader->ctxt->wellFormed == 0)
		break;
	} else {
	    s = xmlBufUse(inbuf) - reader->cur;
	    val = xmlParseChunk(reader->ctxt,
		 (const char *) xmlBufContent(inbuf) + reader->cur,
			        s, 0);
	    reader->cur += s;
	    if (val != 0)
		reader->ctxt->wellFormed = 0;
	    break;
	}
    }
    reader->state = oldstate;

    /*
     * Discard the consumed input when needed and possible
     */
    if (reader->mode == XML_TEXTREADER_MODE_INTERACTIVE) {
        if (reader->input->readcallback != NULL) {
	    if ((reader->cur >= 4096) &&
		(xmlBufUse(inbuf) - reader->cur <= CHUNK_SIZE)) {
		val = xmlBufShrink(inbuf, reader->cur);
		if (val >= 0) {
		    reader->cur -= val;
		}
	    }
	}
    }

    /*
     * At the end of the stream signal that the work is done to the Push
     * parser.
     */
    else if (reader->mode == XML_TEXTREADER_MODE_EOF) {
	if (reader->state != XML_TEXTREADER_DONE) {
	    s = xmlBufUse(inbuf) - reader->cur;
	    val = xmlParseChunk(reader->ctxt,
		 (const char *) xmlBufContent(inbuf) + reader->cur,
			        s, 1);
	    reader->cur = xmlBufUse(inbuf);
	    reader->state  = XML_TEXTREADER_DONE;
	    if (val != 0) {
	        if (reader->ctxt->wellFormed)
		    reader->ctxt->wellFormed = 0;
		else
		    return(-1);
	    }
	}
    }
    if (reader->ctxt->wellFormed == 0) {
	reader->mode = XML_TEXTREADER_MODE_EOF;
        return(-1);
    }

    return(0);
}

#ifdef LIBXML_REGEXP_ENABLED
/**
 * xmlTextReaderValidatePush:
 * @reader:  the xmlTextReaderPtr used
 *
 * Push the current node for validation
 */
static void
xmlTextReaderValidatePush(xmlTextReaderPtr reader ATTRIBUTE_UNUSED) {
    xmlNodePtr node = reader->node;

#ifdef LIBXML_VALID_ENABLED
    if ((reader->validate == XML_TEXTREADER_VALIDATE_DTD) &&
        (reader->ctxt != NULL) && (reader->ctxt->validate == 1)) {
	if ((node->ns == NULL) || (node->ns->prefix == NULL)) {
	    reader->ctxt->valid &= xmlValidatePushElement(&reader->ctxt->vctxt,
				    reader->ctxt->myDoc, node, node->name);
	} else {
	    /* TODO use the BuildQName interface */
	    xmlChar *qname;

	    qname = xmlStrdup(node->ns->prefix);
	    qname = xmlStrcat(qname, BAD_CAST ":");
	    qname = xmlStrcat(qname, node->name);
	    reader->ctxt->valid &= xmlValidatePushElement(&reader->ctxt->vctxt,
				    reader->ctxt->myDoc, node, qname);
	    if (qname != NULL)
		xmlFree(qname);
	}
    }
#endif /* LIBXML_VALID_ENABLED */
#ifdef LIBXML_SCHEMAS_ENABLED
    if ((reader->validate == XML_TEXTREADER_VALIDATE_RNG) &&
               (reader->rngValidCtxt != NULL)) {
	int ret;

	if (reader->rngFullNode != NULL) return;
	ret = xmlRelaxNGValidatePushElement(reader->rngValidCtxt,
	                                    reader->ctxt->myDoc,
					    node);
	if (ret == 0) {
	    /*
	     * this element requires a full tree
	     */
	    node = xmlTextReaderExpand(reader);
	    if (node == NULL) {
	        ret = -1;
	    } else {
		ret = xmlRelaxNGValidateFullElement(reader->rngValidCtxt,
						    reader->ctxt->myDoc,
						    node);
		reader->rngFullNode = node;
	    }
	}
	if (ret != 1)
	    reader->rngValidErrors++;
    }
#endif
}

/**
 * xmlTextReaderValidateCData:
 * @reader:  the xmlTextReaderPtr used
 * @data:  pointer to the CData
 * @len:  length of the CData block in bytes.
 *
 * Push some CData for validation
 */
static void
xmlTextReaderValidateCData(xmlTextReaderPtr reader,
                           const xmlChar *data, int len) {
#ifdef LIBXML_VALID_ENABLED
    if ((reader->validate == XML_TEXTREADER_VALIDATE_DTD) &&
        (reader->ctxt != NULL) && (reader->ctxt->validate == 1)) {
	reader->ctxt->valid &= xmlValidatePushCData(&reader->ctxt->vctxt,
	                                            data, len);
    }
#endif /* LIBXML_VALID_ENABLED */
#ifdef LIBXML_SCHEMAS_ENABLED
    if ((reader->validate == XML_TEXTREADER_VALIDATE_RNG) &&
               (reader->rngValidCtxt != NULL)) {
	int ret;

	if (reader->rngFullNode != NULL) return;
	ret = xmlRelaxNGValidatePushCData(reader->rngValidCtxt, data, len);
	if (ret != 1)
	    reader->rngValidErrors++;
    }
#endif
}

/**
 * xmlTextReaderValidatePop:
 * @reader:  the xmlTextReaderPtr used
 *
 * Pop the current node from validation
 */
static void
xmlTextReaderValidatePop(xmlTextReaderPtr reader) {
    xmlNodePtr node = reader->node;

#ifdef LIBXML_VALID_ENABLED
    if ((reader->validate == XML_TEXTREADER_VALIDATE_DTD) &&
        (reader->ctxt != NULL) && (reader->ctxt->validate == 1)) {
	if ((node->ns == NULL) || (node->ns->prefix == NULL)) {
	    reader->ctxt->valid &= xmlValidatePopElement(&reader->ctxt->vctxt,
				    reader->ctxt->myDoc, node, node->name);
	} else {
	    /* TODO use the BuildQName interface */
	    xmlChar *qname;

	    qname = xmlStrdup(node->ns->prefix);
	    qname = xmlStrcat(qname, BAD_CAST ":");
	    qname = xmlStrcat(qname, node->name);
	    reader->ctxt->valid &= xmlValidatePopElement(&reader->ctxt->vctxt,
				    reader->ctxt->myDoc, node, qname);
	    if (qname != NULL)
		xmlFree(qname);
	}
    }
#endif /* LIBXML_VALID_ENABLED */
#ifdef LIBXML_SCHEMAS_ENABLED
    if ((reader->validate == XML_TEXTREADER_VALIDATE_RNG) &&
               (reader->rngValidCtxt != NULL)) {
	int ret;

	if (reader->rngFullNode != NULL) {
	    if (node == reader->rngFullNode)
	        reader->rngFullNode = NULL;
	    return;
	}
	ret = xmlRelaxNGValidatePopElement(reader->rngValidCtxt,
	                                   reader->ctxt->myDoc,
					   node);
	if (ret != 1)
	    reader->rngValidErrors++;
    }
#endif
}

/**
 * xmlTextReaderValidateEntity:
 * @reader:  the xmlTextReaderPtr used
 *
 * Handle the validation when an entity reference is encountered and
 * entity substitution is not activated. As a result the parser interface
 * must walk through the entity and do the validation calls
 */
static void
xmlTextReaderValidateEntity(xmlTextReaderPtr reader) {
    xmlNodePtr oldnode = reader->node;
    xmlNodePtr node = reader->node;

    do {
	if (node->type == XML_ENTITY_REF_NODE) {
	    if ((node->children != NULL) &&
		(node->children->type == XML_ENTITY_DECL) &&
		(node->children->children != NULL)) {
		if (xmlTextReaderEntPush(reader, node) < 0) {
                    if (node == oldnode)
                        break;
                    goto skip_children;
                }
		node = node->children->children;
		continue;
	    } else {
		/*
		 * The error has probably been raised already.
		 */
		if (node == oldnode)
		    break;
                goto skip_children;
	    }
#ifdef LIBXML_REGEXP_ENABLED
	} else if (node->type == XML_ELEMENT_NODE) {
	    reader->node = node;
	    xmlTextReaderValidatePush(reader);
	} else if ((node->type == XML_TEXT_NODE) ||
		   (node->type == XML_CDATA_SECTION_NODE)) {
            xmlTextReaderValidateCData(reader, node->content,
	                               xmlStrlen(node->content));
#endif
	}

	/*
	 * go to next node
	 */
	if (node->children != NULL) {
	    node = node->children;
	    continue;
	} else if (node->type == XML_ELEMENT_NODE) {
	    xmlTextReaderValidatePop(reader);
	}
skip_children:
	if (node->next != NULL) {
	    node = node->next;
	    continue;
	}
	do {
	    node = node->parent;
	    if (node->type == XML_ELEMENT_NODE) {
	        xmlNodePtr tmp;
		if (reader->entNr == 0) {
		    while ((tmp = node->last) != NULL) {
			if ((tmp->extra & NODE_IS_PRESERVED) == 0) {
			    xmlUnlinkNode(tmp);
			    xmlTextReaderFreeNode(reader, tmp);
			} else
			    break;
		    }
		}
		reader->node = node;
		xmlTextReaderValidatePop(reader);
	    }
	    if ((node->type == XML_ENTITY_DECL) &&
		(reader->ent != NULL) && (reader->ent->children == node)) {
		node = xmlTextReaderEntPop(reader);
	    }
	    if (node == oldnode)
		break;
	    if (node->next != NULL) {
		node = node->next;
		break;
	    }
	} while ((node != NULL) && (node != oldnode));
    } while ((node != NULL) && (node != oldnode));
    reader->node = oldnode;
}
#endif /* LIBXML_REGEXP_ENABLED */


/**
 * xmlTextReaderGetSuccessor:
 * @cur:  the current node
 *
 * Get the successor of a node if available.
 *
 * Returns the successor node or NULL
 */
static xmlNodePtr
xmlTextReaderGetSuccessor(xmlNodePtr cur) {
    if (cur == NULL) return(NULL) ; /* ERROR */
    if (cur->next != NULL) return(cur->next) ;
    do {
        cur = cur->parent;
        if (cur == NULL) break;
        if (cur->next != NULL) return(cur->next);
    } while (cur != NULL);
    return(cur);
}

/**
 * xmlTextReaderDoExpand:
 * @reader:  the xmlTextReaderPtr used
 *
 * Makes sure that the current node is fully read as well as all its
 * descendant. It means the full DOM subtree must be available at the
 * end of the call.
 *
 * Returns 1 if the node was expanded successfully, 0 if there is no more
 *          nodes to read, or -1 in case of error
 */
static int
xmlTextReaderDoExpand(xmlTextReaderPtr reader) {
    int val;

    if ((reader == NULL) || (reader->node == NULL) || (reader->ctxt == NULL))
        return(-1);
    do {
	if (reader->ctxt->instate == XML_PARSER_EOF) return(1);

        if (xmlTextReaderGetSuccessor(reader->node) != NULL)
	    return(1);
	if (reader->ctxt->nodeNr < reader->depth)
	    return(1);
	if (reader->mode == XML_TEXTREADER_MODE_EOF)
	    return(1);
	val = xmlTextReaderPushData(reader);
	if (val < 0){
	    reader->mode = XML_TEXTREADER_MODE_ERROR;
	    return(-1);
	}
    } while(reader->mode != XML_TEXTREADER_MODE_EOF);
    return(1);
}

/**
 * xmlTextReaderCollectSiblings:
 * @node:    the first child
 *
 *  Traverse depth-first through all sibling nodes and their children
 *  nodes and concatenate their content. This is an auxiliary function
 *  to xmlTextReaderReadString.
 *
 *  Returns a string containing the content, or NULL in case of error.
 */
static xmlChar *
xmlTextReaderCollectSiblings(xmlNodePtr node)
{
    xmlBufferPtr buffer;
    xmlChar *ret;

    if ((node == NULL) || (node->type == XML_NAMESPACE_DECL))
        return(NULL);

    buffer = xmlBufferCreate();
    if (buffer == NULL)
       return NULL;
    xmlBufferSetAllocationScheme(buffer, XML_BUFFER_ALLOC_DOUBLEIT);

    for ( ; node != NULL; node = node->next) {
       switch (node->type) {
       case XML_TEXT_NODE:
       case XML_CDATA_SECTION_NODE:
           xmlBufferCat(buffer, node->content);
           break;
       case XML_ELEMENT_NODE: {
           xmlChar *tmp;

	   tmp = xmlTextReaderCollectSiblings(node->children);
           xmlBufferCat(buffer, tmp);
	   xmlFree(tmp);
	   break;
       }
       default:
           break;
       }
    }
    ret = buffer->content;
    buffer->content = NULL;
    xmlBufferFree(buffer);
    return(ret);
}

/**
 * xmlTextReaderRead:
 * @reader:  the xmlTextReaderPtr used
 *
 *  Moves the position of the current instance to the next node in
 *  the stream, exposing its properties.
 *
 *  Returns 1 if the node was read successfully, 0 if there is no more
 *          nodes to read, or -1 in case of error
 */
int
xmlTextReaderRead(xmlTextReaderPtr reader) {
    int val, olddepth = 0;
    xmlTextReaderState oldstate = XML_TEXTREADER_START;
    xmlNodePtr oldnode = NULL;


    if (reader == NULL)
	return(-1);
    reader->curnode = NULL;
    if (reader->doc != NULL)
        return(xmlTextReaderReadTree(reader));
    if (reader->ctxt == NULL)
	return(-1);

    if (reader->mode == XML_TEXTREADER_MODE_INITIAL) {
	reader->mode = XML_TEXTREADER_MODE_INTERACTIVE;
	/*
	 * Initial state
	 */
	do {
	    val = xmlTextReaderPushData(reader);
		if (val < 0){
			reader->mode = XML_TEXTREADER_MODE_ERROR;
			reader->state = XML_TEXTREADER_ERROR;
		return(-1);
		}
	} while ((reader->ctxt->node == NULL) &&
		 ((reader->mode != XML_TEXTREADER_MODE_EOF) &&
		  (reader->state != XML_TEXTREADER_DONE)));
	if (reader->ctxt->node == NULL) {
	    if (reader->ctxt->myDoc != NULL) {
		reader->node = reader->ctxt->myDoc->children;
	    }
	    if (reader->node == NULL){
			reader->mode = XML_TEXTREADER_MODE_ERROR;
			reader->state = XML_TEXTREADER_ERROR;
		return(-1);
		}
	    reader->state = XML_TEXTREADER_ELEMENT;
	} else {
	    if (reader->ctxt->myDoc != NULL) {
		reader->node = reader->ctxt->myDoc->children;
	    }
	    if (reader->node == NULL)
		reader->node = reader->ctxt->nodeTab[0];
	    reader->state = XML_TEXTREADER_ELEMENT;
	}
	reader->depth = 0;
	reader->ctxt->parseMode = XML_PARSE_READER;
	goto node_found;
    }
    oldstate = reader->state;
    olddepth = reader->ctxt->nodeNr;
    oldnode = reader->node;

get_next_node:
    if (reader->node == NULL) {
	if (reader->mode == XML_TEXTREADER_MODE_EOF)
	    return(0);
	else
	    return(-1);
    }

    /*
     * If we are not backtracking on ancestors or examined nodes,
     * that the parser didn't finished or that we aren't at the end
     * of stream, continue processing.
     */
    while ((reader->node != NULL) && (reader->node->next == NULL) &&
	   (reader->ctxt->nodeNr == olddepth) &&
           ((oldstate == XML_TEXTREADER_BACKTRACK) ||
            (reader->node->children == NULL) ||
	    (reader->node->type == XML_ENTITY_REF_NODE) ||
	    ((reader->node->children != NULL) &&
	     (reader->node->children->type == XML_TEXT_NODE) &&
	     (reader->node->children->next == NULL)) ||
	    (reader->node->type == XML_DTD_NODE) ||
	    (reader->node->type == XML_DOCUMENT_NODE) ||
	    (reader->node->type == XML_HTML_DOCUMENT_NODE)) &&
	   ((reader->ctxt->node == NULL) ||
	    (reader->ctxt->node == reader->node) ||
	    (reader->ctxt->node == reader->node->parent)) &&
	   (reader->ctxt->instate != XML_PARSER_EOF)) {
	val = xmlTextReaderPushData(reader);
	if (val < 0){
		reader->mode = XML_TEXTREADER_MODE_ERROR;
		reader->state = XML_TEXTREADER_ERROR;
	    return(-1);
	}
	if (reader->node == NULL)
	    goto node_end;
    }
    if (oldstate != XML_TEXTREADER_BACKTRACK) {
	if ((reader->node->children != NULL) &&
	    (reader->node->type != XML_ENTITY_REF_NODE) &&
	    (reader->node->type != XML_XINCLUDE_START) &&
	    (reader->node->type != XML_DTD_NODE)) {
	    reader->node = reader->node->children;
	    reader->depth++;
	    reader->state = XML_TEXTREADER_ELEMENT;
	    goto node_found;
	}
    }
    if (reader->node->next != NULL) {
	if ((oldstate == XML_TEXTREADER_ELEMENT) &&
            (reader->node->type == XML_ELEMENT_NODE) &&
	    (reader->node->children == NULL) &&
	    ((reader->node->extra & NODE_IS_EMPTY) == 0)
#ifdef LIBXML_XINCLUDE_ENABLED
	    && (reader->in_xinclude <= 0)
#endif
	    ) {
	    reader->state = XML_TEXTREADER_END;
	    goto node_found;
	}
#ifdef LIBXML_REGEXP_ENABLED
	if ((reader->validate) &&
	    (reader->node->type == XML_ELEMENT_NODE))
	    xmlTextReaderValidatePop(reader);
#endif /* LIBXML_REGEXP_ENABLED */
        if ((reader->preserves > 0) &&
	    (reader->node->extra & NODE_IS_SPRESERVED))
	    reader->preserves--;
	reader->node = reader->node->next;
	reader->state = XML_TEXTREADER_ELEMENT;

	/*
	 * Cleanup of the old node
	 */
	if ((reader->preserves == 0) &&
#ifdef LIBXML_XINCLUDE_ENABLED
	    (reader->in_xinclude == 0) &&
#endif
	    (reader->entNr == 0) &&
	    (reader->node->prev != NULL) &&
            (reader->node->prev->type != XML_DTD_NODE)) {
	    xmlNodePtr tmp = reader->node->prev;
	    if ((tmp->extra & NODE_IS_PRESERVED) == 0) {
                if (oldnode == tmp)
                    oldnode = NULL;
		xmlUnlinkNode(tmp);
		xmlTextReaderFreeNode(reader, tmp);
	    }
	}

	goto node_found;
    }
    if ((oldstate == XML_TEXTREADER_ELEMENT) &&
	(reader->node->type == XML_ELEMENT_NODE) &&
	(reader->node->children == NULL) &&
	((reader->node->extra & NODE_IS_EMPTY) == 0)) {;
	reader->state = XML_TEXTREADER_END;
	goto node_found;
    }
#ifdef LIBXML_REGEXP_ENABLED
    if ((reader->validate != XML_TEXTREADER_NOT_VALIDATE) && (reader->node->type == XML_ELEMENT_NODE))
	xmlTextReaderValidatePop(reader);
#endif /* LIBXML_REGEXP_ENABLED */
    if ((reader->preserves > 0) &&
	(reader->node->extra & NODE_IS_SPRESERVED))
	reader->preserves--;
    reader->node = reader->node->parent;
    if ((reader->node == NULL) ||
	(reader->node->type == XML_DOCUMENT_NODE) ||
	(reader->node->type == XML_HTML_DOCUMENT_NODE)) {
	if (reader->mode != XML_TEXTREADER_MODE_EOF) {
	    val = xmlParseChunk(reader->ctxt, "", 0, 1);
	    reader->state = XML_TEXTREADER_DONE;
	    if (val != 0)
	        return(-1);
	}
	reader->node = NULL;
	reader->depth = -1;

	/*
	 * Cleanup of the old node
	 */
	if ((oldnode != NULL) && (reader->preserves == 0) &&
#ifdef LIBXML_XINCLUDE_ENABLED
	    (reader->in_xinclude == 0) &&
#endif
	    (reader->entNr == 0) &&
	    (oldnode->type != XML_DTD_NODE) &&
	    ((oldnode->extra & NODE_IS_PRESERVED) == 0)) {
	    xmlUnlinkNode(oldnode);
	    xmlTextReaderFreeNode(reader, oldnode);
	}

	goto node_end;
    }
    if ((reader->preserves == 0) &&
#ifdef LIBXML_XINCLUDE_ENABLED
        (reader->in_xinclude == 0) &&
#endif
	(reader->entNr == 0) &&
        (reader->node->last != NULL) &&
        ((reader->node->last->extra & NODE_IS_PRESERVED) == 0)) {
	xmlNodePtr tmp = reader->node->last;
	xmlUnlinkNode(tmp);
	xmlTextReaderFreeNode(reader, tmp);
    }
    reader->depth--;
    reader->state = XML_TEXTREADER_BACKTRACK;

node_found:
    /*
     * If we are in the middle of a piece of CDATA make sure it's finished
     */
    if ((reader->node != NULL) &&
        (reader->node->next == NULL) &&
        ((reader->node->type == XML_TEXT_NODE) ||
	 (reader->node->type == XML_CDATA_SECTION_NODE))) {
            if (xmlTextReaderExpand(reader) == NULL)
	        return -1;
    }

#ifdef LIBXML_XINCLUDE_ENABLED
    /*
     * Handle XInclude if asked for
     */
    if ((reader->xinclude) && (reader->in_xinclude == 0) &&
        (reader->state != XML_TEXTREADER_BACKTRACK) &&
        (reader->node != NULL) &&
	(reader->node->type == XML_ELEMENT_NODE) &&
	(reader->node->ns != NULL) &&
	((xmlStrEqual(reader->node->ns->href, XINCLUDE_NS)) ||
	 (xmlStrEqual(reader->node->ns->href, XINCLUDE_OLD_NS)))) {
	if (reader->xincctxt == NULL) {
	    reader->xincctxt = xmlXIncludeNewContext(reader->ctxt->myDoc);
	    xmlXIncludeSetFlags(reader->xincctxt,
	                        reader->parserFlags & (~XML_PARSE_NOXINCNODE));
            xmlXIncludeSetStreamingMode(reader->xincctxt, 1);
	}
	/*
	 * expand that node and process it
	 */
	if (xmlTextReaderExpand(reader) == NULL)
	    return -1;
	xmlXIncludeProcessNode(reader->xincctxt, reader->node);
    }
    if ((reader->node != NULL) && (reader->node->type == XML_XINCLUDE_START)) {
        reader->in_xinclude++;
	goto get_next_node;
    }
    if ((reader->node != NULL) && (reader->node->type == XML_XINCLUDE_END)) {
        reader->in_xinclude--;
	goto get_next_node;
    }
#endif
    /*
     * Handle entities enter and exit when in entity replacement mode
     */
    if ((reader->node != NULL) &&
	(reader->node->type == XML_ENTITY_REF_NODE) &&
	(reader->ctxt != NULL) && (reader->ctxt->replaceEntities == 1)) {
	if ((reader->node->children != NULL) &&
	    (reader->node->children->type == XML_ENTITY_DECL) &&
	    (reader->node->children->children != NULL)) {
	    if (xmlTextReaderEntPush(reader, reader->node) < 0)
                goto get_next_node;
	    reader->node = reader->node->children->children;
	}
#ifdef LIBXML_REGEXP_ENABLED
    } else if ((reader->node != NULL) &&
	       (reader->node->type == XML_ENTITY_REF_NODE) &&
	       (reader->ctxt != NULL) && (reader->validate)) {
	xmlTextReaderValidateEntity(reader);
#endif /* LIBXML_REGEXP_ENABLED */
    }
    if ((reader->node != NULL) &&
	(reader->node->type == XML_ENTITY_DECL) &&
	(reader->ent != NULL) && (reader->ent->children == reader->node)) {
	reader->node = xmlTextReaderEntPop(reader);
	reader->depth++;
        goto get_next_node;
    }
#ifdef LIBXML_REGEXP_ENABLED
    if ((reader->validate != XML_TEXTREADER_NOT_VALIDATE) && (reader->node != NULL)) {
	xmlNodePtr node = reader->node;

	if ((node->type == XML_ELEMENT_NODE) &&
            ((reader->state != XML_TEXTREADER_END) &&
	     (reader->state != XML_TEXTREADER_BACKTRACK))) {
	    xmlTextReaderValidatePush(reader);
	} else if ((node->type == XML_TEXT_NODE) ||
		   (node->type == XML_CDATA_SECTION_NODE)) {
            xmlTextReaderValidateCData(reader, node->content,
	                               xmlStrlen(node->content));
	}
    }
#endif /* LIBXML_REGEXP_ENABLED */
#ifdef LIBXML_PATTERN_ENABLED
    if ((reader->patternNr > 0) && (reader->state != XML_TEXTREADER_END) &&
        (reader->state != XML_TEXTREADER_BACKTRACK)) {
        int i;
	for (i = 0;i < reader->patternNr;i++) {
	     if (xmlPatternMatch(reader->patternTab[i], reader->node) == 1) {
	         xmlTextReaderPreserve(reader);
		 break;
             }
	}
    }
#endif /* LIBXML_PATTERN_ENABLED */
#ifdef LIBXML_SCHEMAS_ENABLED
    if ((reader->validate == XML_TEXTREADER_VALIDATE_XSD) &&
        (reader->xsdValidErrors == 0) &&
	(reader->xsdValidCtxt != NULL)) {
	reader->xsdValidErrors = !xmlSchemaIsValid(reader->xsdValidCtxt);
    }
#endif /* LIBXML_PATTERN_ENABLED */
    return(1);
node_end:
    reader->state = XML_TEXTREADER_DONE;
    return(0);
}

/**
 * xmlTextReaderReadState:
 * @reader:  the xmlTextReaderPtr used
 *
 * Gets the read state of the reader.
 *
 * Returns the state value, or -1 in case of error
 */
int
xmlTextReaderReadState(xmlTextReaderPtr reader) {
    if (reader == NULL)
	return(-1);
    return(reader->mode);
}

/**
 * xmlTextReaderExpand:
 * @reader:  the xmlTextReaderPtr used
 *
 * Reads the contents of the current node and the full subtree. It then makes
 * the subtree available until the next xmlTextReaderRead() call
 *
 * Returns a node pointer valid until the next xmlTextReaderRead() call
 *         or NULL in case of error.
 */
xmlNodePtr
xmlTextReaderExpand(xmlTextReaderPtr reader) {
    if ((reader == NULL) || (reader->node == NULL))
        return(NULL);
    if (reader->doc != NULL)
        return(reader->node);
    if (reader->ctxt == NULL)
        return(NULL);
    if (xmlTextReaderDoExpand(reader) < 0)
        return(NULL);
    return(reader->node);
}

/**
 * xmlTextReaderNext:
 * @reader:  the xmlTextReaderPtr used
 *
 * Skip to the node following the current one in document order while
 * avoiding the subtree if any.
 *
 * Returns 1 if the node was read successfully, 0 if there is no more
 *          nodes to read, or -1 in case of error
 */
int
xmlTextReaderNext(xmlTextReaderPtr reader) {
    int ret;
    xmlNodePtr cur;

    if (reader == NULL)
	return(-1);
    if (reader->doc != NULL)
        return(xmlTextReaderNextTree(reader));
    cur = reader->node;
    if ((cur == NULL) || (cur->type != XML_ELEMENT_NODE))
        return(xmlTextReaderRead(reader));
    if (reader->state == XML_TEXTREADER_END || reader->state == XML_TEXTREADER_BACKTRACK)
        return(xmlTextReaderRead(reader));
    if (cur->extra & NODE_IS_EMPTY)
        return(xmlTextReaderRead(reader));
    do {
        ret = xmlTextReaderRead(reader);
	if (ret != 1)
	    return(ret);
    } while (reader->node != cur);
    return(xmlTextReaderRead(reader));
}

#ifdef LIBXML_WRITER_ENABLED
/**
 * xmlTextReaderReadInnerXml:
 * @reader:  the xmlTextReaderPtr used
 *
 * Reads the contents of the current node, including child nodes and markup.
 *
 * Returns a string containing the XML content, or NULL if the current node
 *         is neither an element nor attribute, or has no child nodes. The
 *         string must be deallocated by the caller.
 */
xmlChar *
xmlTextReaderReadInnerXml(xmlTextReaderPtr reader ATTRIBUTE_UNUSED)
{
    xmlChar *resbuf;
    xmlNodePtr node, cur_node;
    xmlBufferPtr buff, buff2;
    xmlDocPtr doc;

    if (xmlTextReaderExpand(reader) == NULL) {
        return NULL;
    }
    doc = reader->node->doc;
    buff = xmlBufferCreate();
    if (buff == NULL)
        return NULL;
    xmlBufferSetAllocationScheme(buff, XML_BUFFER_ALLOC_DOUBLEIT);
    for (cur_node = reader->node->children; cur_node != NULL;
         cur_node = cur_node->next) {
        /* XXX: Why is the node copied? */
        node = xmlDocCopyNode(cur_node, doc, 1);
        /* XXX: Why do we need a second buffer? */
        buff2 = xmlBufferCreate();
        xmlBufferSetAllocationScheme(buff2, XML_BUFFER_ALLOC_DOUBLEIT);
        if (xmlNodeDump(buff2, doc, node, 0, 0) == -1) {
            xmlFreeNode(node);
            xmlBufferFree(buff2);
            xmlBufferFree(buff);
            return NULL;
        }
        xmlBufferCat(buff, buff2->content);
        xmlFreeNode(node);
        xmlBufferFree(buff2);
    }
    resbuf = buff->content;
    buff->content = NULL;

    xmlBufferFree(buff);
    return resbuf;
}
#endif

#ifdef LIBXML_WRITER_ENABLED
/**
 * xmlTextReaderReadOuterXml:
 * @reader:  the xmlTextReaderPtr used
 *
 * Reads the contents of the current node, including child nodes and markup.
 *
 * Returns a string containing the node and any XML content, or NULL if the
 *         current node cannot be serialized. The string must be deallocated
 *         by the caller.
 */
xmlChar *
xmlTextReaderReadOuterXml(xmlTextReaderPtr reader ATTRIBUTE_UNUSED)
{
    xmlChar *resbuf;
    xmlNodePtr node;
    xmlBufferPtr buff;
    xmlDocPtr doc;

    if (xmlTextReaderExpand(reader) == NULL) {
        return NULL;
    }
    node = reader->node;
    doc = node->doc;
    /* XXX: Why is the node copied? */
	if (node->type == XML_DTD_NODE) {
		node = (xmlNodePtr) xmlCopyDtd((xmlDtdPtr) node);
	} else {
		node = xmlDocCopyNode(node, doc, 1);
	}
    buff = xmlBufferCreate();
    xmlBufferSetAllocationScheme(buff, XML_BUFFER_ALLOC_DOUBLEIT);
    if (xmlNodeDump(buff, doc, node, 0, 0) == -1) {
        xmlFreeNode(node);
        xmlBufferFree(buff);
        return NULL;
    }

    resbuf = buff->content;
    buff->content = NULL;

    xmlFreeNode(node);
    xmlBufferFree(buff);
    return resbuf;
}
#endif

/**
 * xmlTextReaderReadString:
 * @reader:  the xmlTextReaderPtr used
 *
 * Reads the contents of an element or a text node as a string.
 *
 * Returns a string containing the contents of the Element or Text node,
 *         or NULL if the reader is positioned on any other type of node.
 *         The string must be deallocated by the caller.
 */
xmlChar *
xmlTextReaderReadString(xmlTextReaderPtr reader)
{
    xmlNodePtr node;

    if ((reader == NULL) || (reader->node == NULL))
       return(NULL);

    node = (reader->curnode != NULL) ? reader->curnode : reader->node;
    switch (node->type) {
    case XML_TEXT_NODE:
       if (node->content != NULL)
           return(xmlStrdup(node->content));
       break;
    case XML_ELEMENT_NODE:
	if (xmlTextReaderDoExpand(reader) != -1) {
	    return xmlTextReaderCollectSiblings(node->children);
	}
	break;
    case XML_ATTRIBUTE_NODE:
	TODO
	break;
    default:
       break;
    }
    return(NULL);
}

#if 0
/**
 * xmlTextReaderReadBase64:
 * @reader:  the xmlTextReaderPtr used
 * @array:  a byte array to store the content.
 * @offset:  the zero-based index into array where the method should
 *           begin to write.
 * @len:  the number of bytes to write.
 *
 * Reads and decodes the Base64 encoded contents of an element and
 * stores the result in a byte buffer.
 *
 * Returns the number of bytes written to array, or zero if the current
 *         instance is not positioned on an element or -1 in case of error.
 */
int
xmlTextReaderReadBase64(xmlTextReaderPtr reader,
                        unsigned char *array ATTRIBUTE_UNUSED,
	                int offset ATTRIBUTE_UNUSED,
			int len ATTRIBUTE_UNUSED) {
    if ((reader == NULL) || (reader->ctxt == NULL))
	return(-1);
    if (reader->ctxt->wellFormed != 1)
	return(-1);

    if ((reader->node == NULL) || (reader->node->type == XML_ELEMENT_NODE))
	return(0);
    TODO
    return(0);
}

/**
 * xmlTextReaderReadBinHex:
 * @reader:  the xmlTextReaderPtr used
 * @array:  a byte array to store the content.
 * @offset:  the zero-based index into array where the method should
 *           begin to write.
 * @len:  the number of bytes to write.
 *
 * Reads and decodes the BinHex encoded contents of an element and
 * stores the result in a byte buffer.
 *
 * Returns the number of bytes written to array, or zero if the current
 *         instance is not positioned on an element or -1 in case of error.
 */
int
xmlTextReaderReadBinHex(xmlTextReaderPtr reader,
                        unsigned char *array ATTRIBUTE_UNUSED,
	                int offset ATTRIBUTE_UNUSED,
			int len ATTRIBUTE_UNUSED) {
    if ((reader == NULL) || (reader->ctxt == NULL))
	return(-1);
    if (reader->ctxt->wellFormed != 1)
	return(-1);

    if ((reader->node == NULL) || (reader->node->type == XML_ELEMENT_NODE))
	return(0);
    TODO
    return(0);
}
#endif

/************************************************************************
 *									*
 *			Operating on a preparsed tree			*
 *									*
 ************************************************************************/
static int
xmlTextReaderNextTree(xmlTextReaderPtr reader)
{
    if (reader == NULL)
        return(-1);

    if (reader->state == XML_TEXTREADER_END)
        return(0);

    if (reader->node == NULL) {
        if (reader->doc->children == NULL) {
            reader->state = XML_TEXTREADER_END;
            return(0);
        }

        reader->node = reader->doc->children;
        reader->state = XML_TEXTREADER_START;
        return(1);
    }

    if (reader->state != XML_TEXTREADER_BACKTRACK) {
	/* Here removed traversal to child, because we want to skip the subtree,
	replace with traversal to sibling to skip subtree */
        if (reader->node->next != 0) {
	    /* Move to sibling if present,skipping sub-tree */
            reader->node = reader->node->next;
            reader->state = XML_TEXTREADER_START;
            return(1);
        }

	/* if reader->node->next is NULL mean no subtree for current node,
	so need to move to sibling of parent node if present */
	reader->state = XML_TEXTREADER_BACKTRACK;
	/* This will move to parent if present */
	xmlTextReaderRead(reader);
    }

    if (reader->node->next != 0) {
        reader->node = reader->node->next;
        reader->state = XML_TEXTREADER_START;
        return(1);
    }

    if (reader->node->parent != 0) {
        if (reader->node->parent->type == XML_DOCUMENT_NODE) {
            reader->state = XML_TEXTREADER_END;
            return(0);
        }

        reader->node = reader->node->parent;
        reader->depth--;
        reader->state = XML_TEXTREADER_BACKTRACK;
	/* Repeat process to move to sibling of parent node if present */
        xmlTextReaderNextTree(reader);
    }

    reader->state = XML_TEXTREADER_END;

    return(1);
}

/**
 * xmlTextReaderReadTree:
 * @reader:  the xmlTextReaderPtr used
 *
 *  Moves the position of the current instance to the next node in
 *  the stream, exposing its properties.
 *
 *  Returns 1 if the node was read successfully, 0 if there is no more
 *          nodes to read, or -1 in case of error
 */
static int
xmlTextReaderReadTree(xmlTextReaderPtr reader) {
    if (reader->state == XML_TEXTREADER_END)
        return(0);

next_node:
    if (reader->node == NULL) {
        if (reader->doc->children == NULL) {
            reader->state = XML_TEXTREADER_END;
            return(0);
        }

        reader->node = reader->doc->children;
        reader->state = XML_TEXTREADER_START;
        goto found_node;
    }

    if ((reader->state != XML_TEXTREADER_BACKTRACK) &&
        (reader->node->type != XML_DTD_NODE) &&
        (reader->node->type != XML_XINCLUDE_START) &&
	(reader->node->type != XML_ENTITY_REF_NODE)) {
        if (reader->node->children != NULL) {
            reader->node = reader->node->children;
            reader->depth++;
            reader->state = XML_TEXTREADER_START;
            goto found_node;
        }

        if (reader->node->type == XML_ATTRIBUTE_NODE) {
            reader->state = XML_TEXTREADER_BACKTRACK;
            goto found_node;
        }
    }

    if (reader->node->next != NULL) {
        reader->node = reader->node->next;
        reader->state = XML_TEXTREADER_START;
        goto found_node;
    }

    if (reader->node->parent != NULL) {
        if ((reader->node->parent->type == XML_DOCUMENT_NODE) ||
	    (reader->node->parent->type == XML_HTML_DOCUMENT_NODE)) {
            reader->state = XML_TEXTREADER_END;
            return(0);
        }

        reader->node = reader->node->parent;
        reader->depth--;
        reader->state = XML_TEXTREADER_BACKTRACK;
        goto found_node;
    }

    reader->state = XML_TEXTREADER_END;

found_node:
    if ((reader->node->type == XML_XINCLUDE_START) ||
        (reader->node->type == XML_XINCLUDE_END))
	goto next_node;

    return(1);
}

/**
 * xmlTextReaderNextSibling:
 * @reader:  the xmlTextReaderPtr used
 *
 * Skip to the node following the current one in document order while
 * avoiding the subtree if any.
 * Currently implemented only for Readers built on a document
 *
 * Returns 1 if the node was read successfully, 0 if there is no more
 *          nodes to read, or -1 in case of error
 */
int
xmlTextReaderNextSibling(xmlTextReaderPtr reader) {
    if (reader == NULL)
        return(-1);
    if (reader->doc == NULL) {
        /* TODO */
	return(-1);
    }

    if (reader->state == XML_TEXTREADER_END)
        return(0);

    if (reader->node == NULL)
        return(xmlTextReaderNextTree(reader));

    if (reader->node->next != NULL) {
        reader->node = reader->node->next;
        reader->state = XML_TEXTREADER_START;
        return(1);
    }

    return(0);
}

/************************************************************************
 *									*
 *			Constructor and destructors			*
 *									*
 ************************************************************************/
/**
 * xmlNewTextReader:
 * @input: the xmlParserInputBufferPtr used to read data
 * @URI: the URI information for the source if available
 *
 * Create an xmlTextReader structure fed with @input
 *
 * Returns the new xmlTextReaderPtr or NULL in case of error
 */
xmlTextReaderPtr
xmlNewTextReader(xmlParserInputBufferPtr input, const char *URI) {
    xmlTextReaderPtr ret;

    if (input == NULL)
	return(NULL);
    ret = xmlMalloc(sizeof(xmlTextReader));
    if (ret == NULL) {
        xmlGenericError(xmlGenericErrorContext,
		"xmlNewTextReader : malloc failed\n");
	return(NULL);
    }
    memset(ret, 0, sizeof(xmlTextReader));
    ret->doc = NULL;
    ret->entTab = NULL;
    ret->entMax = 0;
    ret->entNr = 0;
    ret->input = input;
    ret->buffer = xmlBufCreateSize(100);
    if (ret->buffer == NULL) {
        xmlFree(ret);
        xmlGenericError(xmlGenericErrorContext,
		"xmlNewTextReader : malloc failed\n");
	return(NULL);
    }
    /* no operation on a reader should require a huge buffer */
    xmlBufSetAllocationScheme(ret->buffer,
			      XML_BUFFER_ALLOC_DOUBLEIT);
    ret->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
    if (ret->sax == NULL) {
	xmlBufFree(ret->buffer);
	xmlFree(ret);
        xmlGenericError(xmlGenericErrorContext,
		"xmlNewTextReader : malloc failed\n");
	return(NULL);
    }
    xmlSAXVersion(ret->sax, 2);
    ret->startElement = ret->sax->startElement;
    ret->sax->startElement = xmlTextReaderStartElement;
    ret->endElement = ret->sax->endElement;
    ret->sax->endElement = xmlTextReaderEndElement;
#ifdef LIBXML_SAX1_ENABLED
    if (ret->sax->initialized == XML_SAX2_MAGIC) {
#endif /* LIBXML_SAX1_ENABLED */
	ret->startElementNs = ret->sax->startElementNs;
	ret->sax->startElementNs = xmlTextReaderStartElementNs;
	ret->endElementNs = ret->sax->endElementNs;
	ret->sax->endElementNs = xmlTextReaderEndElementNs;
#ifdef LIBXML_SAX1_ENABLED
    } else {
	ret->startElementNs = NULL;
	ret->endElementNs = NULL;
    }
#endif /* LIBXML_SAX1_ENABLED */
    ret->characters = ret->sax->characters;
    ret->sax->characters = xmlTextReaderCharacters;
    ret->sax->ignorableWhitespace = xmlTextReaderCharacters;
    ret->cdataBlock = ret->sax->cdataBlock;
    ret->sax->cdataBlock = xmlTextReaderCDataBlock;

    ret->mode = XML_TEXTREADER_MODE_INITIAL;
    ret->node = NULL;
    ret->curnode = NULL;
    if (xmlBufUse(ret->input->buffer) < 4) {
	xmlParserInputBufferRead(input, 4);
    }
    if (xmlBufUse(ret->input->buffer) >= 4) {
	ret->ctxt = xmlCreatePushParserCtxt(ret->sax, NULL,
			     (const char *) xmlBufContent(ret->input->buffer),
                                            4, URI);
	ret->base = 0;
	ret->cur = 4;
    } else {
	ret->ctxt = xmlCreatePushParserCtxt(ret->sax, NULL, NULL, 0, URI);
	ret->base = 0;
	ret->cur = 0;
    }

    if (ret->ctxt == NULL) {
        xmlGenericError(xmlGenericErrorContext,
		"xmlNewTextReader : malloc failed\n");
	xmlBufFree(ret->buffer);
	xmlFree(ret->sax);
	xmlFree(ret);
	return(NULL);
    }
    ret->ctxt->parseMode = XML_PARSE_READER;
    ret->ctxt->_private = ret;
    ret->ctxt->linenumbers = 1;
    ret->ctxt->dictNames = 1;
    ret->allocs = XML_TEXTREADER_CTXT;
    /*
     * use the parser dictionary to allocate all elements and attributes names
     */
    ret->ctxt->docdict = 1;
    ret->dict = ret->ctxt->dict;
#ifdef LIBXML_XINCLUDE_ENABLED
    ret->xinclude = 0;
#endif
#ifdef LIBXML_PATTERN_ENABLED
    ret->patternMax = 0;
    ret->patternTab = NULL;
#endif
    return(ret);
}

/**
 * xmlNewTextReaderFilename:
 * @URI: the URI of the resource to process
 *
 * Create an xmlTextReader structure fed with the resource at @URI
 *
 * Returns the new xmlTextReaderPtr or NULL in case of error
 */
xmlTextReaderPtr
xmlNewTextReaderFilename(const char *URI) {
    xmlParserInputBufferPtr input;
    xmlTextReaderPtr ret;
    char *directory = NULL;

    input = xmlParserInputBufferCreateFilename(URI, XML_CHAR_ENCODING_NONE);
    if (input == NULL)
	return(NULL);
    ret = xmlNewTextReader(input, URI);
    if (ret == NULL) {
	xmlFreeParserInputBuffer(input);
	return(NULL);
    }
    ret->allocs |= XML_TEXTREADER_INPUT;
    if (ret->ctxt->directory == NULL)
        directory = xmlParserGetDirectory(URI);
    if ((ret->ctxt->directory == NULL) && (directory != NULL))
        ret->ctxt->directory = (char *) xmlStrdup((xmlChar *) directory);
    if (directory != NULL)
	xmlFree(directory);
    return(ret);
}

/**
 * xmlFreeTextReader:
 * @reader:  the xmlTextReaderPtr
 *
 * Deallocate all the resources associated to the reader
 */
void
xmlFreeTextReader(xmlTextReaderPtr reader) {
    if (reader == NULL)
	return;
#ifdef LIBXML_SCHEMAS_ENABLED
    if (reader->rngSchemas != NULL) {
	xmlRelaxNGFree(reader->rngSchemas);
	reader->rngSchemas = NULL;
    }
    if (reader->rngValidCtxt != NULL) {
	if (! reader->rngPreserveCtxt)
	    xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);
	reader->rngValidCtxt = NULL;
    }
    if (reader->xsdPlug != NULL) {
	xmlSchemaSAXUnplug(reader->xsdPlug);
	reader->xsdPlug = NULL;
    }
    if (reader->xsdValidCtxt != NULL) {
	if (! reader->xsdPreserveCtxt)
	    xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
	reader->xsdValidCtxt = NULL;
    }
    if (reader->xsdSchemas != NULL) {
	xmlSchemaFree(reader->xsdSchemas);
	reader->xsdSchemas = NULL;
    }
#endif
#ifdef LIBXML_XINCLUDE_ENABLED
    if (reader->xincctxt != NULL)
	xmlXIncludeFreeContext(reader->xincctxt);
#endif
#ifdef LIBXML_PATTERN_ENABLED
    if (reader->patternTab != NULL) {
        int i;
	for (i = 0;i < reader->patternNr;i++) {
	    if (reader->patternTab[i] != NULL)
	        xmlFreePattern(reader->patternTab[i]);
	}
	xmlFree(reader->patternTab);
    }
#endif
    if (reader->mode != XML_TEXTREADER_MODE_CLOSED)
        xmlTextReaderClose(reader);
    if (reader->ctxt != NULL) {
        if (reader->dict == reader->ctxt->dict)
	    reader->dict = NULL;
	if (reader->allocs & XML_TEXTREADER_CTXT)
	    xmlFreeParserCtxt(reader->ctxt);
    }
    if (reader->sax != NULL)
	xmlFree(reader->sax);
    if (reader->buffer != NULL)
        xmlBufFree(reader->buffer);
    if (reader->entTab != NULL)
	xmlFree(reader->entTab);
    if (reader->dict != NULL)
        xmlDictFree(reader->dict);
    xmlFree(reader);
}

/************************************************************************
 *									*
 *			Methods for XmlTextReader			*
 *									*
 ************************************************************************/
/**
 * xmlTextReaderClose:
 * @reader:  the xmlTextReaderPtr used
 *
 * This method releases any resources allocated by the current instance
 * changes the state to Closed and close any underlying input.
 *
 * Returns 0 or -1 in case of error
 */
int
xmlTextReaderClose(xmlTextReaderPtr reader) {
    if (reader == NULL)
	return(-1);
    reader->node = NULL;
    reader->curnode = NULL;
    reader->mode = XML_TEXTREADER_MODE_CLOSED;
    if (reader->faketext != NULL) {
        xmlFreeNode(reader->faketext);
        reader->faketext = NULL;
    }
    if (reader->ctxt != NULL) {
#ifdef LIBXML_VALID_ENABLED
	if ((reader->ctxt->vctxt.vstateTab != NULL) &&
	    (reader->ctxt->vctxt.vstateMax > 0)){
#ifdef LIBXML_REGEXP_ENABLED
            while (reader->ctxt->vctxt.vstateNr > 0)
                xmlValidatePopElement(&reader->ctxt->vctxt, NULL, NULL, NULL);
#endif /* LIBXML_REGEXP_ENABLED */
	    xmlFree(reader->ctxt->vctxt.vstateTab);
	    reader->ctxt->vctxt.vstateTab = NULL;
	    reader->ctxt->vctxt.vstateMax = 0;
	}
#endif /* LIBXML_VALID_ENABLED */
	xmlStopParser(reader->ctxt);
	if (reader->ctxt->myDoc != NULL) {
	    if (reader->preserve == 0)
		xmlTextReaderFreeDoc(reader, reader->ctxt->myDoc);
	    reader->ctxt->myDoc = NULL;
	}
    }
    if ((reader->input != NULL)  && (reader->allocs & XML_TEXTREADER_INPUT)) {
	xmlFreeParserInputBuffer(reader->input);
	reader->allocs -= XML_TEXTREADER_INPUT;
    }
    return(0);
}

/**
 * xmlTextReaderGetAttributeNo:
 * @reader:  the xmlTextReaderPtr used
 * @no: the zero-based index of the attribute relative to the containing element
 *
 * Provides the value of the attribute with the specified index relative
 * to the containing element.
 *
 * Returns a string containing the value of the specified attribute, or NULL
 *    in case of error. The string must be deallocated by the caller.
 */
xmlChar *
xmlTextReaderGetAttributeNo(xmlTextReaderPtr reader, int no) {
    xmlChar *ret;
    int i;
    xmlAttrPtr cur;
    xmlNsPtr ns;

    if (reader == NULL)
	return(NULL);
    if (reader->node == NULL)
	return(NULL);
    if (reader->curnode != NULL)
	return(NULL);
    /* TODO: handle the xmlDecl */
    if (reader->node->type != XML_ELEMENT_NODE)
	return(NULL);

    ns = reader->node->nsDef;
    for (i = 0;(i < no) && (ns != NULL);i++) {
	ns = ns->next;
    }
    if (ns != NULL)
	return(xmlStrdup(ns->href));

    cur = reader->node->properties;
    if (cur == NULL)
	return(NULL);
    for (;i < no;i++) {
	cur = cur->next;
	if (cur == NULL)
	    return(NULL);
    }
    /* TODO walk the DTD if present */

    ret = xmlNodeListGetString(reader->node->doc, cur->children, 1);
    if (ret == NULL) return(xmlStrdup((xmlChar *)""));
    return(ret);
}

/**
 * xmlTextReaderGetAttribute:
 * @reader:  the xmlTextReaderPtr used
 * @name: the qualified name of the attribute.
 *
 * Provides the value of the attribute with the specified qualified name.
 *
 * Returns a string containing the value of the specified attribute, or NULL
 *    in case of error. The string must be deallocated by the caller.
 */
xmlChar *
xmlTextReaderGetAttribute(xmlTextReaderPtr reader, const xmlChar *name) {
    xmlChar *prefix = NULL;
    xmlChar *localname;
    xmlNsPtr ns;
    xmlChar *ret = NULL;

    if ((reader == NULL) || (name == NULL))
	return(NULL);
    if (reader->node == NULL)
	return(NULL);
    if (reader->curnode != NULL)
	return(NULL);

    /* TODO: handle the xmlDecl */
    if (reader->node->type != XML_ELEMENT_NODE)
	return(NULL);

    localname = xmlSplitQName2(name, &prefix);
    if (localname == NULL) {
		/*
		 * Namespace default decl
		 */
		if (xmlStrEqual(name, BAD_CAST "xmlns")) {
			ns = reader->node->nsDef;
			while (ns != NULL) {
				if (ns->prefix == NULL) {
					return(xmlStrdup(ns->href));
				}
				ns = ns->next;
			}
			return NULL;
		}
		return(xmlGetNoNsProp(reader->node, name));
	}

    /*
     * Namespace default decl
     */
    if (xmlStrEqual(prefix, BAD_CAST "xmlns")) {
		ns = reader->node->nsDef;
		while (ns != NULL) {
			if ((ns->prefix != NULL) && (xmlStrEqual(ns->prefix, localname))) {
				ret = xmlStrdup(ns->href);
				break;
			}
			ns = ns->next;
		}
    } else {
		ns = xmlSearchNs(reader->node->doc, reader->node, prefix);
		if (ns != NULL)
			ret = xmlGetNsProp(reader->node, localname, ns->href);
	}

    xmlFree(localname);
    if (prefix != NULL)
        xmlFree(prefix);
    return(ret);
}


/**
 * xmlTextReaderGetAttributeNs:
 * @reader:  the xmlTextReaderPtr used
 * @localName: the local name of the attribute.
 * @namespaceURI: the namespace URI of the attribute.
 *
 * Provides the value of the specified attribute
 *
 * Returns a string containing the value of the specified attribute, or NULL
 *    in case of error. The string must be deallocated by the caller.
 */
xmlChar *
xmlTextReaderGetAttributeNs(xmlTextReaderPtr reader, const xmlChar *localName,
			    const xmlChar *namespaceURI) {
    xmlChar *prefix = NULL;
    xmlNsPtr ns;

    if ((reader == NULL) || (localName == NULL))
	return(NULL);
    if (reader->node == NULL)
	return(NULL);
    if (reader->curnode != NULL)
	return(NULL);

    /* TODO: handle the xmlDecl */
    if (reader->node->type != XML_ELEMENT_NODE)
	return(NULL);

    if (xmlStrEqual(namespaceURI, BAD_CAST "http://www.w3.org/2000/xmlns/")) {
		if (! xmlStrEqual(localName, BAD_CAST "xmlns")) {
			prefix = BAD_CAST localName;
		}
		ns = reader->node->nsDef;
		while (ns != NULL) {
			if ((prefix == NULL && ns->prefix == NULL) ||
				((ns->prefix != NULL) && (xmlStrEqual(ns->prefix, localName)))) {
				return xmlStrdup(ns->href);
			}
			ns = ns->next;
		}
		return NULL;
    }

    return(xmlGetNsProp(reader->node, localName, namespaceURI));
}

/**
 * xmlTextReaderGetRemainder:
 * @reader:  the xmlTextReaderPtr used
 *
 * Method to get the remainder of the buffered XML. this method stops the
 * parser, set its state to End Of File and return the input stream with
 * what is left that the parser did not use.
 *
 * The implementation is not good, the parser certainly progressed past
 * what's left in reader->input, and there is an allocation problem. Best
 * would be to rewrite it differently.
 *
 * Returns the xmlParserInputBufferPtr attached to the XML or NULL
 *    in case of error.
 */
xmlParserInputBufferPtr
xmlTextReaderGetRemainder(xmlTextReaderPtr reader) {
    xmlParserInputBufferPtr ret = NULL;

    if (reader == NULL)
	return(NULL);
    if (reader->node == NULL)
	return(NULL);

    reader->node = NULL;
    reader->curnode = NULL;
    reader->mode = XML_TEXTREADER_MODE_EOF;
    if (reader->ctxt != NULL) {
	xmlStopParser(reader->ctxt);
	if (reader->ctxt->myDoc != NULL) {
	    if (reader->preserve == 0)
		xmlTextReaderFreeDoc(reader, reader->ctxt->myDoc);
	    reader->ctxt->myDoc = NULL;
	}
    }
    if (reader->allocs & XML_TEXTREADER_INPUT) {
	ret = reader->input;
	reader->input = NULL;
	reader->allocs -= XML_TEXTREADER_INPUT;
    } else {
	/*
	 * Hum, one may need to duplicate the data structure because
	 * without reference counting the input may be freed twice:
	 *   - by the layer which allocated it.
	 *   - by the layer to which would have been returned to.
	 */
	TODO
	return(NULL);
    }
    return(ret);
}

/**
 * xmlTextReaderLookupNamespace:
 * @reader:  the xmlTextReaderPtr used
 * @prefix: the prefix whose namespace URI is to be resolved. To return
 *          the default namespace, specify NULL
 *
 * Resolves a namespace prefix in the scope of the current element.
 *
 * Returns a string containing the namespace URI to which the prefix maps
 *    or NULL in case of error. The string must be deallocated by the caller.
 */
xmlChar *
xmlTextReaderLookupNamespace(xmlTextReaderPtr reader, const xmlChar *prefix) {
    xmlNsPtr ns;

    if (reader == NULL)
	return(NULL);
    if (reader->node == NULL)
	return(NULL);

    ns = xmlSearchNs(reader->node->doc, reader->node, prefix);
    if (ns == NULL)
	return(NULL);
    return(xmlStrdup(ns->href));
}

/**
 * xmlTextReaderMoveToAttributeNo:
 * @reader:  the xmlTextReaderPtr used
 * @no: the zero-based index of the attribute relative to the containing
 *      element.
 *
 * Moves the position of the current instance to the attribute with
 * the specified index relative to the containing element.
 *
 * Returns 1 in case of success, -1 in case of error, 0 if not found
 */
int
xmlTextReaderMoveToAttributeNo(xmlTextReaderPtr reader, int no) {
    int i;
    xmlAttrPtr cur;
    xmlNsPtr ns;

    if (reader == NULL)
	return(-1);
    if (reader->node == NULL)
	return(-1);
    /* TODO: handle the xmlDecl */
    if (reader->node->type != XML_ELEMENT_NODE)
	return(-1);

    reader->curnode = NULL;

    ns = reader->node->nsDef;
    for (i = 0;(i < no) && (ns != NULL);i++) {
	ns = ns->next;
    }
    if (ns != NULL) {
	reader->curnode = (xmlNodePtr) ns;
	return(1);
    }

    cur = reader->node->properties;
    if (cur == NULL)
	return(0);
    for (;i < no;i++) {
	cur = cur->next;
	if (cur == NULL)
	    return(0);
    }
    /* TODO walk the DTD if present */

    reader->curnode = (xmlNodePtr) cur;
    return(1);
}

/**
 * xmlTextReaderMoveToAttribute:
 * @reader:  the xmlTextReaderPtr used
 * @name: the qualified name of the attribute.
 *
 * Moves the position of the current instance to the attribute with
 * the specified qualified name.
 *
 * Returns 1 in case of success, -1 in case of error, 0 if not found
 */
int
xmlTextReaderMoveToAttribute(xmlTextReaderPtr reader, const xmlChar *name) {
    xmlChar *prefix = NULL;
    xmlChar *localname;
    xmlNsPtr ns;
    xmlAttrPtr prop;

    if ((reader == NULL) || (name == NULL))
	return(-1);
    if (reader->node == NULL)
	return(-1);

    /* TODO: handle the xmlDecl */
    if (reader->node->type != XML_ELEMENT_NODE)
	return(0);

    localname = xmlSplitQName2(name, &prefix);
    if (localname == NULL) {
	/*
	 * Namespace default decl
	 */
	if (xmlStrEqual(name, BAD_CAST "xmlns")) {
	    ns = reader->node->nsDef;
	    while (ns != NULL) {
		if (ns->prefix == NULL) {
		    reader->curnode = (xmlNodePtr) ns;
		    return(1);
		}
		ns = ns->next;
	    }
	    return(0);
	}

	prop = reader->node->properties;
	while (prop != NULL) {
	    /*
	     * One need to have
	     *   - same attribute names
	     *   - and the attribute carrying that namespace
	     */
	    if ((xmlStrEqual(prop->name, name)) &&
		((prop->ns == NULL) || (prop->ns->prefix == NULL))) {
		reader->curnode = (xmlNodePtr) prop;
		return(1);
	    }
	    prop = prop->next;
	}
	return(0);
    }

    /*
     * Namespace default decl
     */
    if (xmlStrEqual(prefix, BAD_CAST "xmlns")) {
	ns = reader->node->nsDef;
	while (ns != NULL) {
	    if ((ns->prefix != NULL) && (xmlStrEqual(ns->prefix, localname))) {
		reader->curnode = (xmlNodePtr) ns;
		goto found;
	    }
	    ns = ns->next;
	}
	goto not_found;
    }
    prop = reader->node->properties;
    while (prop != NULL) {
	/*
	 * One need to have
	 *   - same attribute names
	 *   - and the attribute carrying that namespace
	 */
	if ((xmlStrEqual(prop->name, localname)) &&
	    (prop->ns != NULL) && (xmlStrEqual(prop->ns->prefix, prefix))) {
	    reader->curnode = (xmlNodePtr) prop;
	    goto found;
	}
	prop = prop->next;
    }
not_found:
    if (localname != NULL)
        xmlFree(localname);
    if (prefix != NULL)
        xmlFree(prefix);
    return(0);

found:
    if (localname != NULL)
        xmlFree(localname);
    if (prefix != NULL)
        xmlFree(prefix);
    return(1);
}

/**
 * xmlTextReaderMoveToAttributeNs:
 * @reader:  the xmlTextReaderPtr used
 * @localName:  the local name of the attribute.
 * @namespaceURI:  the namespace URI of the attribute.
 *
 * Moves the position of the current instance to the attribute with the
 * specified local name and namespace URI.
 *
 * Returns 1 in case of success, -1 in case of error, 0 if not found
 */
int
xmlTextReaderMoveToAttributeNs(xmlTextReaderPtr reader,
	const xmlChar *localName, const xmlChar *namespaceURI) {
    xmlAttrPtr prop;
    xmlNodePtr node;
    xmlNsPtr ns;
    xmlChar *prefix = NULL;

    if ((reader == NULL) || (localName == NULL) || (namespaceURI == NULL))
	return(-1);
    if (reader->node == NULL)
	return(-1);
    if (reader->node->type != XML_ELEMENT_NODE)
	return(0);
    node = reader->node;

    if (xmlStrEqual(namespaceURI, BAD_CAST "http://www.w3.org/2000/xmlns/")) {
		if (! xmlStrEqual(localName, BAD_CAST "xmlns")) {
			prefix = BAD_CAST localName;
		}
		ns = reader->node->nsDef;
		while (ns != NULL) {
			if ((prefix == NULL && ns->prefix == NULL) ||
				((ns->prefix != NULL) && (xmlStrEqual(ns->prefix, localName)))) {
				reader->curnode = (xmlNodePtr) ns;
				return(1);
			}
			ns = ns->next;
		}
		return(0);
    }

    prop = node->properties;
    while (prop != NULL) {
	/*
	 * One need to have
	 *   - same attribute names
	 *   - and the attribute carrying that namespace
	 */
        if (xmlStrEqual(prop->name, localName) &&
	    ((prop->ns != NULL) &&
	     (xmlStrEqual(prop->ns->href, namespaceURI)))) {
	    reader->curnode = (xmlNodePtr) prop;
	    return(1);
        }
	prop = prop->next;
    }
    return(0);
}

/**
 * xmlTextReaderMoveToFirstAttribute:
 * @reader:  the xmlTextReaderPtr used
 *
 * Moves the position of the current instance to the first attribute
 * associated with the current node.
 *
 * Returns 1 in case of success, -1 in case of error, 0 if not found
 */
int
xmlTextReaderMoveToFirstAttribute(xmlTextReaderPtr reader) {
    if (reader == NULL)
	return(-1);
    if (reader->node == NULL)
	return(-1);
    if (reader->node->type != XML_ELEMENT_NODE)
	return(0);

    if (reader->node->nsDef != NULL) {
	reader->curnode = (xmlNodePtr) reader->node->nsDef;
	return(1);
    }
    if (reader->node->properties != NULL) {
	reader->curnode = (xmlNodePtr) reader->node->properties;
	return(1);
    }
    return(0);
}

/**
 * xmlTextReaderMoveToNextAttribute:
 * @reader:  the xmlTextReaderPtr used
 *
 * Moves the position of the current instance to the next attribute
 * associated with the current node.
 *
 * Returns 1 in case of success, -1 in case of error, 0 if not found
 */
int
xmlTextReaderMoveToNextAttribute(xmlTextReaderPtr reader) {
    if (reader == NULL)
	return(-1);
    if (reader->node == NULL)
	return(-1);
    if (reader->node->type != XML_ELEMENT_NODE)
	return(0);
    if (reader->curnode == NULL)
	return(xmlTextReaderMoveToFirstAttribute(reader));

    if (reader->curnode->type == XML_NAMESPACE_DECL) {
	xmlNsPtr ns = (xmlNsPtr) reader->curnode;
	if (ns->next != NULL) {
	    reader->curnode = (xmlNodePtr) ns->next;
	    return(1);
	}
	if (reader->node->properties != NULL) {
	    reader->curnode = (xmlNodePtr) reader->node->properties;
	    return(1);
	}
	return(0);
    } else if ((reader->curnode->type == XML_ATTRIBUTE_NODE) &&
	       (reader->curnode->next != NULL)) {
	reader->curnode = reader->curnode->next;
	return(1);
    }
    return(0);
}

/**
 * xmlTextReaderMoveToElement:
 * @reader:  the xmlTextReaderPtr used
 *
 * Moves the position of the current instance to the node that
 * contains the current Attribute  node.
 *
 * Returns 1 in case of success, -1 in case of error, 0 if not moved
 */
int
xmlTextReaderMoveToElement(xmlTextReaderPtr reader) {
    if (reader == NULL)
	return(-1);
    if (reader->node == NULL)
	return(-1);
    if (reader->node->type != XML_ELEMENT_NODE)
	return(0);
    if (reader->curnode != NULL) {
	reader->curnode = NULL;
	return(1);
    }
    return(0);
}

/**
 * xmlTextReaderReadAttributeValue:
 * @reader:  the xmlTextReaderPtr used
 *
 * Parses an attribute value into one or more Text and EntityReference nodes.
 *
 * Returns 1 in case of success, 0 if the reader was not positioned on an
 *         attribute node or all the attribute values have been read, or -1
 *         in case of error.
 */
int
xmlTextReaderReadAttributeValue(xmlTextReaderPtr reader) {
    if (reader == NULL)
	return(-1);
    if (reader->node == NULL)
	return(-1);
    if (reader->curnode == NULL)
	return(0);
    if (reader->curnode->type == XML_ATTRIBUTE_NODE) {
	if (reader->curnode->children == NULL)
	    return(0);
	reader->curnode = reader->curnode->children;
    } else if (reader->curnode->type == XML_NAMESPACE_DECL) {
	xmlNsPtr ns = (xmlNsPtr) reader->curnode;

	if (reader->faketext == NULL) {
	    reader->faketext = xmlNewDocText(reader->node->doc,
		                             ns->href);
	} else {
            if ((reader->faketext->content != NULL) &&
	        (reader->faketext->content !=
		 (xmlChar *) &(reader->faketext->properties)))
		xmlFree(reader->faketext->content);
	    reader->faketext->content = xmlStrdup(ns->href);
	}
	reader->curnode = reader->faketext;
    } else {
	if (reader->curnode->next == NULL)
	    return(0);
	reader->curnode = reader->curnode->next;
    }
    return(1);
}

/**
 * xmlTextReaderConstEncoding:
 * @reader:  the xmlTextReaderPtr used
 *
 * Determine the encoding of the document being read.
 *
 * Returns a string containing the encoding of the document or NULL in
 * case of error.  The string is deallocated with the reader.
 */
const xmlChar *
xmlTextReaderConstEncoding(xmlTextReaderPtr reader) {
    xmlDocPtr doc = NULL;
    if (reader == NULL)
	return(NULL);
    if (reader->doc != NULL)
        doc = reader->doc;
    else if (reader->ctxt != NULL)
	doc = reader->ctxt->myDoc;
    if (doc == NULL)
	return(NULL);

    if (doc->encoding == NULL)
	return(NULL);
    else
      return(CONSTSTR(doc->encoding));
}


/************************************************************************
 *									*
 *			Access API to the current node			*
 *									*
 ************************************************************************/
/**
 * xmlTextReaderAttributeCount:
 * @reader:  the xmlTextReaderPtr used
 *
 * Provides the number of attributes of the current node
 *
 * Returns 0 i no attributes, -1 in case of error or the attribute count
 */
int
xmlTextReaderAttributeCount(xmlTextReaderPtr reader) {
    int ret;
    xmlAttrPtr attr;
    xmlNsPtr ns;
    xmlNodePtr node;

    if (reader == NULL)
	return(-1);
    if (reader->node == NULL)
	return(0);

    if (reader->curnode != NULL)
	node = reader->curnode;
    else
	node = reader->node;

    if (node->type != XML_ELEMENT_NODE)
	return(0);
    if ((reader->state == XML_TEXTREADER_END) ||
	(reader->state == XML_TEXTREADER_BACKTRACK))
	return(0);
    ret = 0;
    attr = node->properties;
    while (attr != NULL) {
	ret++;
	attr = attr->next;
    }
    ns = node->nsDef;
    while (ns != NULL) {
	ret++;
	ns = ns->next;
    }
    return(ret);
}

/**
 * xmlTextReaderNodeType:
 * @reader:  the xmlTextReaderPtr used
 *
 * Get the node type of the current node
 * Reference:
 * http://www.gnu.org/software/dotgnu/pnetlib-doc/System/Xml/XmlNodeType.html
 *
 * Returns the xmlReaderTypes of the current node or -1 in case of error
 */
int
xmlTextReaderNodeType(xmlTextReaderPtr reader) {
    xmlNodePtr node;

    if (reader == NULL)
	return(-1);
    if (reader->node == NULL)
	return(XML_READER_TYPE_NONE);
    if (reader->curnode != NULL)
	node = reader->curnode;
    else
	node = reader->node;
    switch (node->type) {
        case XML_ELEMENT_NODE:
	    if ((reader->state == XML_TEXTREADER_END) ||
		(reader->state == XML_TEXTREADER_BACKTRACK))
		return(XML_READER_TYPE_END_ELEMENT);
	    return(XML_READER_TYPE_ELEMENT);
        case XML_NAMESPACE_DECL:
        case XML_ATTRIBUTE_NODE:
	    return(XML_READER_TYPE_ATTRIBUTE);
        case XML_TEXT_NODE:
	    if (xmlIsBlankNode(reader->node)) {
		if (xmlNodeGetSpacePreserve(reader->node))
		    return(XML_READER_TYPE_SIGNIFICANT_WHITESPACE);
		else
		    return(XML_READER_TYPE_WHITESPACE);
	    } else {
		return(XML_READER_TYPE_TEXT);
	    }
        case XML_CDATA_SECTION_NODE:
	    return(XML_READER_TYPE_CDATA);
        case XML_ENTITY_REF_NODE:
	    return(XML_READER_TYPE_ENTITY_REFERENCE);
        case XML_ENTITY_NODE:
	    return(XML_READER_TYPE_ENTITY);
        case XML_PI_NODE:
	    return(XML_READER_TYPE_PROCESSING_INSTRUCTION);
        case XML_COMMENT_NODE:
	    return(XML_READER_TYPE_COMMENT);
        case XML_DOCUMENT_NODE:
        case XML_HTML_DOCUMENT_NODE:
	    return(XML_READER_TYPE_DOCUMENT);
        case XML_DOCUMENT_FRAG_NODE:
	    return(XML_READER_TYPE_DOCUMENT_FRAGMENT);
        case XML_NOTATION_NODE:
	    return(XML_READER_TYPE_NOTATION);
        case XML_DOCUMENT_TYPE_NODE:
        case XML_DTD_NODE:
	    return(XML_READER_TYPE_DOCUMENT_TYPE);

        case XML_ELEMENT_DECL:
        case XML_ATTRIBUTE_DECL:
        case XML_ENTITY_DECL:
        case XML_XINCLUDE_START:
        case XML_XINCLUDE_END:
	    return(XML_READER_TYPE_NONE);
    }
    return(-1);
}

/**
 * xmlTextReaderIsEmptyElement:
 * @reader:  the xmlTextReaderPtr used
 *
 * Check if the current node is empty
 *
 * Returns 1 if empty, 0 if not and -1 in case of error
 */
int
xmlTextReaderIsEmptyElement(xmlTextReaderPtr reader) {
    if ((reader == NULL) || (reader->node == NULL))
	return(-1);
    if (reader->node->type != XML_ELEMENT_NODE)
	return(0);
    if (reader->curnode != NULL)
	return(0);
    if (reader->node->children != NULL)
	return(0);
    if (reader->state == XML_TEXTREADER_END)
	return(0);
    if (reader->doc != NULL)
        return(1);
#ifdef LIBXML_XINCLUDE_ENABLED
    if (reader->in_xinclude > 0)
        return(1);
#endif
    return((reader->node->extra & NODE_IS_EMPTY) != 0);
}

/**
 * xmlTextReaderLocalName:
 * @reader:  the xmlTextReaderPtr used
 *
 * The local name of the node.
 *
 * Returns the local name or NULL if not available,
 *   if non NULL it need to be freed by the caller.
 */
xmlChar *
xmlTextReaderLocalName(xmlTextReaderPtr reader) {
    xmlNodePtr node;
    if ((reader == NULL) || (reader->node == NULL))
	return(NULL);
    if (reader->curnode != NULL)
	node = reader->curnode;
    else
	node = reader->node;
    if (node->type == XML_NAMESPACE_DECL) {
	xmlNsPtr ns = (xmlNsPtr) node;
	if (ns->prefix == NULL)
	    return(xmlStrdup(BAD_CAST "xmlns"));
	else
	    return(xmlStrdup(ns->prefix));
    }
    if ((node->type != XML_ELEMENT_NODE) &&
	(node->type != XML_ATTRIBUTE_NODE))
	return(xmlTextReaderName(reader));
    return(xmlStrdup(node->name));
}

/**
 * xmlTextReaderConstLocalName:
 * @reader:  the xmlTextReaderPtr used
 *
 * The local name of the node.
 *
 * Returns the local name or NULL if not available, the
 *         string will be deallocated with the reader.
 */
const xmlChar *
xmlTextReaderConstLocalName(xmlTextReaderPtr reader) {
    xmlNodePtr node;
    if ((reader == NULL) || (reader->node == NULL))
	return(NULL);
    if (reader->curnode != NULL)
	node = reader->curnode;
    else
	node = reader->node;
    if (node->type == XML_NAMESPACE_DECL) {
	xmlNsPtr ns = (xmlNsPtr) node;
	if (ns->prefix == NULL)
	    return(CONSTSTR(BAD_CAST "xmlns"));
	else
	    return(ns->prefix);
    }
    if ((node->type != XML_ELEMENT_NODE) &&
	(node->type != XML_ATTRIBUTE_NODE))
	return(xmlTextReaderConstName(reader));
    return(node->name);
}

/**
 * xmlTextReaderName:
 * @reader:  the xmlTextReaderPtr used
 *
 * The qualified name of the node, equal to Prefix :LocalName.
 *
 * Returns the local name or NULL if not available,
 *   if non NULL it need to be freed by the caller.
 */
xmlChar *
xmlTextReaderName(xmlTextReaderPtr reader) {
    xmlNodePtr node;
    xmlChar *ret;

    if ((reader == NULL) || (reader->node == NULL))
	return(NULL);
    if (reader->curnode != NULL)
	node = reader->curnode;
    else
	node = reader->node;
    switch (node->type) {
        case XML_ELEMENT_NODE:
        case XML_ATTRIBUTE_NODE:
	    if ((node->ns == NULL) ||
		(node->ns->prefix == NULL))
		return(xmlStrdup(node->name));

	    ret = xmlStrdup(node->ns->prefix);
	    ret = xmlStrcat(ret, BAD_CAST ":");
	    ret = xmlStrcat(ret, node->name);
	    return(ret);
        case XML_TEXT_NODE:
	    return(xmlStrdup(BAD_CAST "#text"));
        case XML_CDATA_SECTION_NODE:
	    return(xmlStrdup(BAD_CAST "#cdata-section"));
        case XML_ENTITY_NODE:
        case XML_ENTITY_REF_NODE:
	    return(xmlStrdup(node->name));
        case XML_PI_NODE:
	    return(xmlStrdup(node->name));
        case XML_COMMENT_NODE:
	    return(xmlStrdup(BAD_CAST "#comment"));
        case XML_DOCUMENT_NODE:
        case XML_HTML_DOCUMENT_NODE:
	    return(xmlStrdup(BAD_CAST "#document"));
        case XML_DOCUMENT_FRAG_NODE:
	    return(xmlStrdup(BAD_CAST "#document-fragment"));
        case XML_NOTATION_NODE:
	    return(xmlStrdup(node->name));
        case XML_DOCUMENT_TYPE_NODE:
        case XML_DTD_NODE:
	    return(xmlStrdup(node->name));
        case XML_NAMESPACE_DECL: {
	    xmlNsPtr ns = (xmlNsPtr) node;

	    ret = xmlStrdup(BAD_CAST "xmlns");
	    if (ns->prefix == NULL)
		return(ret);
	    ret = xmlStrcat(ret, BAD_CAST ":");
	    ret = xmlStrcat(ret, ns->prefix);
	    return(ret);
	}

        case XML_ELEMENT_DECL:
        case XML_ATTRIBUTE_DECL:
        case XML_ENTITY_DECL:
        case XML_XINCLUDE_START:
        case XML_XINCLUDE_END:
	    return(NULL);
    }
    return(NULL);
}

/**
 * xmlTextReaderConstName:
 * @reader:  the xmlTextReaderPtr used
 *
 * The qualified name of the node, equal to Prefix :LocalName.
 *
 * Returns the local name or NULL if not available, the string is
 *         deallocated with the reader.
 */
const xmlChar *
xmlTextReaderConstName(xmlTextReaderPtr reader) {
    xmlNodePtr node;

    if ((reader == NULL) || (reader->node == NULL))
	return(NULL);
    if (reader->curnode != NULL)
	node = reader->curnode;
    else
	node = reader->node;
    switch (node->type) {
        case XML_ELEMENT_NODE:
        case XML_ATTRIBUTE_NODE:
	    if ((node->ns == NULL) ||
		(node->ns->prefix == NULL))
		return(node->name);
	    return(CONSTQSTR(node->ns->prefix, node->name));
        case XML_TEXT_NODE:
	    return(CONSTSTR(BAD_CAST "#text"));
        case XML_CDATA_SECTION_NODE:
	    return(CONSTSTR(BAD_CAST "#cdata-section"));
        case XML_ENTITY_NODE:
        case XML_ENTITY_REF_NODE:
	    return(CONSTSTR(node->name));
        case XML_PI_NODE:
	    return(CONSTSTR(node->name));
        case XML_COMMENT_NODE:
	    return(CONSTSTR(BAD_CAST "#comment"));
        case XML_DOCUMENT_NODE:
        case XML_HTML_DOCUMENT_NODE:
	    return(CONSTSTR(BAD_CAST "#document"));
        case XML_DOCUMENT_FRAG_NODE:
	    return(CONSTSTR(BAD_CAST "#document-fragment"));
        case XML_NOTATION_NODE:
	    return(CONSTSTR(node->name));
        case XML_DOCUMENT_TYPE_NODE:
        case XML_DTD_NODE:
	    return(CONSTSTR(node->name));
        case XML_NAMESPACE_DECL: {
	    xmlNsPtr ns = (xmlNsPtr) node;

	    if (ns->prefix == NULL)
		return(CONSTSTR(BAD_CAST "xmlns"));
	    return(CONSTQSTR(BAD_CAST "xmlns", ns->prefix));
	}

        case XML_ELEMENT_DECL:
        case XML_ATTRIBUTE_DECL:
        case XML_ENTITY_DECL:
        case XML_XINCLUDE_START:
        case XML_XINCLUDE_END:
	    return(NULL);
    }
    return(NULL);
}

/**
 * xmlTextReaderPrefix:
 * @reader:  the xmlTextReaderPtr used
 *
 * A shorthand reference to the namespace associated with the node.
 *
 * Returns the prefix or NULL if not available,
 *    if non NULL it need to be freed by the caller.
 */
xmlChar *
xmlTextReaderPrefix(xmlTextReaderPtr reader) {
    xmlNodePtr node;
    if ((reader == NULL) || (reader->node == NULL))
	return(NULL);
    if (reader->curnode != NULL)
	node = reader->curnode;
    else
	node = reader->node;
    if (node->type == XML_NAMESPACE_DECL) {
	xmlNsPtr ns = (xmlNsPtr) node;
	if (ns->prefix == NULL)
	    return(NULL);
	return(xmlStrdup(BAD_CAST "xmlns"));
    }
    if ((node->type != XML_ELEMENT_NODE) &&
	(node->type != XML_ATTRIBUTE_NODE))
	return(NULL);
    if ((node->ns != NULL) && (node->ns->prefix != NULL))
	return(xmlStrdup(node->ns->prefix));
    return(NULL);
}

/**
 * xmlTextReaderConstPrefix:
 * @reader:  the xmlTextReaderPtr used
 *
 * A shorthand reference to the namespace associated with the node.
 *
 * Returns the prefix or NULL if not available, the string is deallocated
 *         with the reader.
 */
const xmlChar *
xmlTextReaderConstPrefix(xmlTextReaderPtr reader) {
    xmlNodePtr node;
    if ((reader == NULL) || (reader->node == NULL))
	return(NULL);
    if (reader->curnode != NULL)
	node = reader->curnode;
    else
	node = reader->node;
    if (node->type == XML_NAMESPACE_DECL) {
	xmlNsPtr ns = (xmlNsPtr) node;
	if (ns->prefix == NULL)
	    return(NULL);
	return(CONSTSTR(BAD_CAST "xmlns"));
    }
    if ((node->type != XML_ELEMENT_NODE) &&
	(node->type != XML_ATTRIBUTE_NODE))
	return(NULL);
    if ((node->ns != NULL) && (node->ns->prefix != NULL))
	return(CONSTSTR(node->ns->prefix));
    return(NULL);
}

/**
 * xmlTextReaderNamespaceUri:
 * @reader:  the xmlTextReaderPtr used
 *
 * The URI defining the namespace associated with the node.
 *
 * Returns the namespace URI or NULL if not available,
 *    if non NULL it need to be freed by the caller.
 */
xmlChar *
xmlTextReaderNamespaceUri(xmlTextReaderPtr reader) {
    xmlNodePtr node;
    if ((reader == NULL) || (reader->node == NULL))
	return(NULL);
    if (reader->curnode != NULL)
	node = reader->curnode;
    else
	node = reader->node;
    if (node->type == XML_NAMESPACE_DECL)
	return(xmlStrdup(BAD_CAST "http://www.w3.org/2000/xmlns/"));
    if ((node->type != XML_ELEMENT_NODE) &&
	(node->type != XML_ATTRIBUTE_NODE))
	return(NULL);
    if (node->ns != NULL)
	return(xmlStrdup(node->ns->href));
    return(NULL);
}

/**
 * xmlTextReaderConstNamespaceUri:
 * @reader:  the xmlTextReaderPtr used
 *
 * The URI defining the namespace associated with the node.
 *
 * Returns the namespace URI or NULL if not available, the string
 *         will be deallocated with the reader
 */
const xmlChar *
xmlTextReaderConstNamespaceUri(xmlTextReaderPtr reader) {
    xmlNodePtr node;
    if ((reader == NULL) || (reader->node == NULL))
	return(NULL);
    if (reader->curnode != NULL)
	node = reader->curnode;
    else
	node = reader->node;
    if (node->type == XML_NAMESPACE_DECL)
	return(CONSTSTR(BAD_CAST "http://www.w3.org/2000/xmlns/"));
    if ((node->type != XML_ELEMENT_NODE) &&
	(node->type != XML_ATTRIBUTE_NODE))
	return(NULL);
    if (node->ns != NULL)
	return(CONSTSTR(node->ns->href));
    return(NULL);
}

/**
 * xmlTextReaderBaseUri:
 * @reader:  the xmlTextReaderPtr used
 *
 * The base URI of the node.
 *
 * Returns the base URI or NULL if not available,
 *    if non NULL it need to be freed by the caller.
 */
xmlChar *
xmlTextReaderBaseUri(xmlTextReaderPtr reader) {
    if ((reader == NULL) || (reader->node == NULL))
	return(NULL);
    return(xmlNodeGetBase(NULL, reader->node));
}

/**
 * xmlTextReaderConstBaseUri:
 * @reader:  the xmlTextReaderPtr used
 *
 * The base URI of the node.
 *
 * Returns the base URI or NULL if not available, the string
 *         will be deallocated with the reader
 */
const xmlChar *
xmlTextReaderConstBaseUri(xmlTextReaderPtr reader) {
    xmlChar *tmp;
    const xmlChar *ret;

    if ((reader == NULL) || (reader->node == NULL))
	return(NULL);
    tmp = xmlNodeGetBase(NULL, reader->node);
    if (tmp == NULL)
        return(NULL);
    ret = CONSTSTR(tmp);
    xmlFree(tmp);
    return(ret);
}

/**
 * xmlTextReaderDepth:
 * @reader:  the xmlTextReaderPtr used
 *
 * The depth of the node in the tree.
 *
 * Returns the depth or -1 in case of error
 */
int
xmlTextReaderDepth(xmlTextReaderPtr reader) {
    if (reader == NULL)
	return(-1);
    if (reader->node == NULL)
	return(0);

    if (reader->curnode != NULL) {
	if ((reader->curnode->type == XML_ATTRIBUTE_NODE) ||
	    (reader->curnode->type == XML_NAMESPACE_DECL))
	    return(reader->depth + 1);
	return(reader->depth + 2);
    }
    return(reader->depth);
}

/**
 * xmlTextReaderHasAttributes:
 * @reader:  the xmlTextReaderPtr used
 *
 * Whether the node has attributes.
 *
 * Returns 1 if true, 0 if false, and -1 in case or error
 */
int
xmlTextReaderHasAttributes(xmlTextReaderPtr reader) {
    xmlNodePtr node;
    if (reader == NULL)
	return(-1);
    if (reader->node == NULL)
	return(0);
    if (reader->curnode != NULL)
	node = reader->curnode;
    else
	node = reader->node;

    if ((node->type == XML_ELEMENT_NODE) &&
	((node->properties != NULL) || (node->nsDef != NULL)))
	return(1);
    /* TODO: handle the xmlDecl */
    return(0);
}

/**
 * xmlTextReaderHasValue:
 * @reader:  the xmlTextReaderPtr used
 *
 * Whether the node can have a text value.
 *
 * Returns 1 if true, 0 if false, and -1 in case or error
 */
int
xmlTextReaderHasValue(xmlTextReaderPtr reader) {
    xmlNodePtr node;
    if (reader == NULL)
	return(-1);
    if (reader->node == NULL)
	return(0);
    if (reader->curnode != NULL)
	node = reader->curnode;
    else
	node = reader->node;

    switch (node->type) {
        case XML_ATTRIBUTE_NODE:
        case XML_TEXT_NODE:
        case XML_CDATA_SECTION_NODE:
        case XML_PI_NODE:
        case XML_COMMENT_NODE:
        case XML_NAMESPACE_DECL:
	    return(1);
	default:
	    break;
    }
    return(0);
}

/**
 * xmlTextReaderValue:
 * @reader:  the xmlTextReaderPtr used
 *
 * Provides the text value of the node if present
 *
 * Returns the string or NULL if not available. The result must be deallocated
 *     with xmlFree()
 */
xmlChar *
xmlTextReaderValue(xmlTextReaderPtr reader) {
    xmlNodePtr node;
    if (reader == NULL)
	return(NULL);
    if (reader->node == NULL)
	return(NULL);
    if (reader->curnode != NULL)
	node = reader->curnode;
    else
	node = reader->node;

    switch (node->type) {
        case XML_NAMESPACE_DECL:
	    return(xmlStrdup(((xmlNsPtr) node)->href));
        case XML_ATTRIBUTE_NODE:{
	    xmlAttrPtr attr = (xmlAttrPtr) node;

	    if (attr->parent != NULL)
		return (xmlNodeListGetString
			(attr->parent->doc, attr->children, 1));
	    else
		return (xmlNodeListGetString(NULL, attr->children, 1));
	    break;
	}
        case XML_TEXT_NODE:
        case XML_CDATA_SECTION_NODE:
        case XML_PI_NODE:
        case XML_COMMENT_NODE:
            if (node->content != NULL)
                return (xmlStrdup(node->content));
	default:
	    break;
    }
    return(NULL);
}

/**
 * xmlTextReaderConstValue:
 * @reader:  the xmlTextReaderPtr used
 *
 * Provides the text value of the node if present
 *
 * Returns the string or NULL if not available. The result will be
 *     deallocated on the next Read() operation.
 */
const xmlChar *
xmlTextReaderConstValue(xmlTextReaderPtr reader) {
    xmlNodePtr node;
    if (reader == NULL)
	return(NULL);
    if (reader->node == NULL)
	return(NULL);
    if (reader->curnode != NULL)
	node = reader->curnode;
    else
	node = reader->node;

    switch (node->type) {
        case XML_NAMESPACE_DECL:
	    return(((xmlNsPtr) node)->href);
        case XML_ATTRIBUTE_NODE:{
	    xmlAttrPtr attr = (xmlAttrPtr) node;
	    const xmlChar *ret;

	    if ((attr->children != NULL) &&
	        (attr->children->type == XML_TEXT_NODE) &&
		(attr->children->next == NULL))
		return(attr->children->content);
	    else {
		if (reader->buffer == NULL) {
		    reader->buffer = xmlBufCreateSize(100);
                    if (reader->buffer == NULL) {
                        xmlGenericError(xmlGenericErrorContext,
                                        "xmlTextReaderSetup : malloc failed\n");
                        return (NULL);
                    }
		    xmlBufSetAllocationScheme(reader->buffer,
		                              XML_BUFFER_ALLOC_DOUBLEIT);
                } else
                    xmlBufEmpty(reader->buffer);
	        xmlBufGetNodeContent(reader->buffer, node);
		ret = xmlBufContent(reader->buffer);
		if (ret == NULL) {
		    /* error on the buffer best to reallocate */
		    xmlBufFree(reader->buffer);
		    reader->buffer = xmlBufCreateSize(100);
		    xmlBufSetAllocationScheme(reader->buffer,
		                              XML_BUFFER_ALLOC_DOUBLEIT);
		    ret = BAD_CAST "";
		}
		return(ret);
	    }
	    break;
	}
        case XML_TEXT_NODE:
        case XML_CDATA_SECTION_NODE:
        case XML_PI_NODE:
        case XML_COMMENT_NODE:
	    return(node->content);
	default:
	    break;
    }
    return(NULL);
}

/**
 * xmlTextReaderIsDefault:
 * @reader:  the xmlTextReaderPtr used
 *
 * Whether an Attribute  node was generated from the default value
 * defined in the DTD or schema.
 *
 * Returns 0 if not defaulted, 1 if defaulted, and -1 in case of error
 */
int
xmlTextReaderIsDefault(xmlTextReaderPtr reader) {
    if (reader == NULL)
	return(-1);
    return(0);
}

/**
 * xmlTextReaderQuoteChar:
 * @reader:  the xmlTextReaderPtr used
 *
 * The quotation mark character used to enclose the value of an attribute.
 *
 * Returns " or ' and -1 in case of error
 */
int
xmlTextReaderQuoteChar(xmlTextReaderPtr reader) {
    if (reader == NULL)
	return(-1);
    /* TODO maybe lookup the attribute value for " first */
    return('"');
}

/**
 * xmlTextReaderXmlLang:
 * @reader:  the xmlTextReaderPtr used
 *
 * The xml:lang scope within which the node resides.
 *
 * Returns the xml:lang value or NULL if none exists.,
 *    if non NULL it need to be freed by the caller.
 */
xmlChar *
xmlTextReaderXmlLang(xmlTextReaderPtr reader) {
    if (reader == NULL)
	return(NULL);
    if (reader->node == NULL)
	return(NULL);
    return(xmlNodeGetLang(reader->node));
}

/**
 * xmlTextReaderConstXmlLang:
 * @reader:  the xmlTextReaderPtr used
 *
 * The xml:lang scope within which the node resides.
 *
 * Returns the xml:lang value or NULL if none exists.
 */
const xmlChar *
xmlTextReaderConstXmlLang(xmlTextReaderPtr reader) {
    xmlChar *tmp;
    const xmlChar *ret;

    if (reader == NULL)
	return(NULL);
    if (reader->node == NULL)
	return(NULL);
    tmp = xmlNodeGetLang(reader->node);
    if (tmp == NULL)
        return(NULL);
    ret = CONSTSTR(tmp);
    xmlFree(tmp);
    return(ret);
}

/**
 * xmlTextReaderConstString:
 * @reader:  the xmlTextReaderPtr used
 * @str:  the string to intern.
 *
 * Get an interned string from the reader, allows for example to
 * speedup string name comparisons
 *
 * Returns an interned copy of the string or NULL in case of error. The
 *         string will be deallocated with the reader.
 */
const xmlChar *
xmlTextReaderConstString(xmlTextReaderPtr reader, const xmlChar *str) {
    if (reader == NULL)
	return(NULL);
    return(CONSTSTR(str));
}

/**
 * xmlTextReaderNormalization:
 * @reader:  the xmlTextReaderPtr used
 *
 * The value indicating whether to normalize white space and attribute values.
 * Since attribute value and end of line normalizations are a MUST in the XML
 * specification only the value true is accepted. The broken behaviour of
 * accepting out of range character entities like &#0; is of course not
 * supported either.
 *
 * Returns 1 or -1 in case of error.
 */
int
xmlTextReaderNormalization(xmlTextReaderPtr reader) {
    if (reader == NULL)
	return(-1);
    return(1);
}

/************************************************************************
 *									*
 *			Extensions to the base APIs			*
 *									*
 ************************************************************************/

/**
 * xmlTextReaderSetParserProp:
 * @reader:  the xmlTextReaderPtr used
 * @prop:  the xmlParserProperties to set
 * @value:  usually 0 or 1 to (de)activate it
 *
 * Change the parser processing behaviour by changing some of its internal
 * properties. Note that some properties can only be changed before any
 * read has been done.
 *
 * Returns 0 if the call was successful, or -1 in case of error
 */
int
xmlTextReaderSetParserProp(xmlTextReaderPtr reader, int prop, int value) {
    xmlParserProperties p = (xmlParserProperties) prop;
    xmlParserCtxtPtr ctxt;

    if ((reader == NULL) || (reader->ctxt == NULL))
	return(-1);
    ctxt = reader->ctxt;

    switch (p) {
        case XML_PARSER_LOADDTD:
	    if (value != 0) {
		if (ctxt->loadsubset == 0) {
		    if (reader->mode != XML_TEXTREADER_MODE_INITIAL)
			return(-1);
		    ctxt->loadsubset = XML_DETECT_IDS;
		}
	    } else {
		ctxt->loadsubset = 0;
	    }
	    return(0);
        case XML_PARSER_DEFAULTATTRS:
	    if (value != 0) {
		ctxt->loadsubset |= XML_COMPLETE_ATTRS;
	    } else {
		if (ctxt->loadsubset & XML_COMPLETE_ATTRS)
		    ctxt->loadsubset -= XML_COMPLETE_ATTRS;
	    }
	    return(0);
        case XML_PARSER_VALIDATE:
	    if (value != 0) {
                ctxt->options |= XML_PARSE_DTDVALID;
		ctxt->validate = 1;
		reader->validate = XML_TEXTREADER_VALIDATE_DTD;
	    } else {
                ctxt->options &= ~XML_PARSE_DTDVALID;
		ctxt->validate = 0;
	    }
	    return(0);
        case XML_PARSER_SUBST_ENTITIES:
	    if (value != 0) {
                ctxt->options |= XML_PARSE_NOENT;
		ctxt->replaceEntities = 1;
	    } else {
                ctxt->options &= ~XML_PARSE_NOENT;
		ctxt->replaceEntities = 0;
	    }
	    return(0);
    }
    return(-1);
}

/**
 * xmlTextReaderGetParserProp:
 * @reader:  the xmlTextReaderPtr used
 * @prop:  the xmlParserProperties to get
 *
 * Read the parser internal property.
 *
 * Returns the value, usually 0 or 1, or -1 in case of error.
 */
int
xmlTextReaderGetParserProp(xmlTextReaderPtr reader, int prop) {
    xmlParserProperties p = (xmlParserProperties) prop;
    xmlParserCtxtPtr ctxt;

    if ((reader == NULL) || (reader->ctxt == NULL))
	return(-1);
    ctxt = reader->ctxt;

    switch (p) {
        case XML_PARSER_LOADDTD:
	    if ((ctxt->loadsubset != 0) || (ctxt->validate != 0))
		return(1);
	    return(0);
        case XML_PARSER_DEFAULTATTRS:
	    if (ctxt->loadsubset & XML_COMPLETE_ATTRS)
		return(1);
	    return(0);
        case XML_PARSER_VALIDATE:
	    return(reader->validate);
	case XML_PARSER_SUBST_ENTITIES:
	    return(ctxt->replaceEntities);
    }
    return(-1);
}


/**
 * xmlTextReaderGetParserLineNumber:
 * @reader: the user data (XML reader context)
 *
 * Provide the line number of the current parsing point.
 *
 * Returns an int or 0 if not available
 */
int
xmlTextReaderGetParserLineNumber(xmlTextReaderPtr reader)
{
    if ((reader == NULL) || (reader->ctxt == NULL) ||
        (reader->ctxt->input == NULL)) {
        return (0);
    }
    return (reader->ctxt->input->line);
}

/**
 * xmlTextReaderGetParserColumnNumber:
 * @reader: the user data (XML reader context)
 *
 * Provide the column number of the current parsing point.
 *
 * Returns an int or 0 if not available
 */
int
xmlTextReaderGetParserColumnNumber(xmlTextReaderPtr reader)
{
    if ((reader == NULL) || (reader->ctxt == NULL) ||
        (reader->ctxt->input == NULL)) {
        return (0);
    }
    return (reader->ctxt->input->col);
}

/**
 * xmlTextReaderCurrentNode:
 * @reader:  the xmlTextReaderPtr used
 *
 * Hacking interface allowing to get the xmlNodePtr corresponding to the
 * current node being accessed by the xmlTextReader. This is dangerous
 * because the underlying node may be destroyed on the next Reads.
 *
 * Returns the xmlNodePtr or NULL in case of error.
 */
xmlNodePtr
xmlTextReaderCurrentNode(xmlTextReaderPtr reader) {
    if (reader == NULL)
	return(NULL);

    if (reader->curnode != NULL)
	return(reader->curnode);
    return(reader->node);
}

/**
 * xmlTextReaderPreserve:
 * @reader:  the xmlTextReaderPtr used
 *
 * This tells the XML Reader to preserve the current node.
 * The caller must also use xmlTextReaderCurrentDoc() to
 * keep an handle on the resulting document once parsing has finished
 *
 * Returns the xmlNodePtr or NULL in case of error.
 */
xmlNodePtr
xmlTextReaderPreserve(xmlTextReaderPtr reader) {
    xmlNodePtr cur, parent;

    if (reader == NULL)
	return(NULL);

    if (reader->curnode != NULL)
        cur = reader->curnode;
    else
        cur = reader->node;
    if (cur == NULL)
        return(NULL);

    if ((cur->type != XML_DOCUMENT_NODE) && (cur->type != XML_DTD_NODE)) {
	cur->extra |= NODE_IS_PRESERVED;
	cur->extra |= NODE_IS_SPRESERVED;
    }
    reader->preserves++;

    parent = cur->parent;;
    while (parent != NULL) {
        if (parent->type == XML_ELEMENT_NODE)
	    parent->extra |= NODE_IS_PRESERVED;
	parent = parent->parent;
    }
    return(cur);
}

#ifdef LIBXML_PATTERN_ENABLED
/**
 * xmlTextReaderPreservePattern:
 * @reader:  the xmlTextReaderPtr used
 * @pattern:  an XPath subset pattern
 * @namespaces: the prefix definitions, array of [URI, prefix] or NULL
 *
 * This tells the XML Reader to preserve all nodes matched by the
 * pattern. The caller must also use xmlTextReaderCurrentDoc() to
 * keep an handle on the resulting document once parsing has finished
 *
 * Returns a non-negative number in case of success and -1 in case of error
 */
int
xmlTextReaderPreservePattern(xmlTextReaderPtr reader, const xmlChar *pattern,
                             const xmlChar **namespaces)
{
    xmlPatternPtr comp;

    if ((reader == NULL) || (pattern == NULL))
	return(-1);

    comp = xmlPatterncompile(pattern, reader->dict, 0, namespaces);
    if (comp == NULL)
        return(-1);

    if (reader->patternMax <= 0) {
	reader->patternMax = 4;
	reader->patternTab = (xmlPatternPtr *) xmlMalloc(reader->patternMax *
					      sizeof(reader->patternTab[0]));
        if (reader->patternTab == NULL) {
            xmlGenericError(xmlGenericErrorContext, "xmlMalloc failed !\n");
            return (-1);
        }
    }
    if (reader->patternNr >= reader->patternMax) {
        xmlPatternPtr *tmp;
        reader->patternMax *= 2;
	tmp = (xmlPatternPtr *) xmlRealloc(reader->patternTab,
                                      reader->patternMax *
                                      sizeof(reader->patternTab[0]));
        if (tmp == NULL) {
            xmlGenericError(xmlGenericErrorContext, "xmlRealloc failed !\n");
	    reader->patternMax /= 2;
            return (-1);
        }
	reader->patternTab = tmp;
    }
    reader->patternTab[reader->patternNr] = comp;
    return(reader->patternNr++);
}
#endif

/**
 * xmlTextReaderCurrentDoc:
 * @reader:  the xmlTextReaderPtr used
 *
 * Hacking interface allowing to get the xmlDocPtr corresponding to the
 * current document being accessed by the xmlTextReader.
 * NOTE: as a result of this call, the reader will not destroy the
 *       associated XML document and calling xmlFreeDoc() on the result
 *       is needed once the reader parsing has finished.
 *
 * Returns the xmlDocPtr or NULL in case of error.
 */
xmlDocPtr
xmlTextReaderCurrentDoc(xmlTextReaderPtr reader) {
    if (reader == NULL)
	return(NULL);
    if (reader->doc != NULL)
        return(reader->doc);
    if ((reader->ctxt == NULL) || (reader->ctxt->myDoc == NULL))
	return(NULL);

    reader->preserve = 1;
    return(reader->ctxt->myDoc);
}

#ifdef LIBXML_SCHEMAS_ENABLED
static char *xmlTextReaderBuildMessage(const char *msg, va_list ap) LIBXML_ATTR_FORMAT(1,0);

static void
xmlTextReaderValidityError(void *ctxt, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);

static void
xmlTextReaderValidityWarning(void *ctxt, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);

static void
xmlTextReaderValidityErrorRelay(void *ctx, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);

static void
xmlTextReaderValidityWarningRelay(void *ctx, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);

static void
xmlTextReaderValidityErrorRelay(void *ctx, const char *msg, ...)
{
    xmlTextReaderPtr reader = (xmlTextReaderPtr) ctx;

    char *str;

    va_list ap;

    va_start(ap, msg);
    str = xmlTextReaderBuildMessage(msg, ap);
    if (!reader->errorFunc) {
        xmlTextReaderValidityError(ctx, "%s", str);
    } else {
        reader->errorFunc(reader->errorFuncArg, str,
                          XML_PARSER_SEVERITY_VALIDITY_ERROR,
                          NULL /* locator */ );
    }
    if (str != NULL)
        xmlFree(str);
    va_end(ap);
}

static void
xmlTextReaderValidityWarningRelay(void *ctx, const char *msg, ...)
{
    xmlTextReaderPtr reader = (xmlTextReaderPtr) ctx;

    char *str;

    va_list ap;

    va_start(ap, msg);
    str = xmlTextReaderBuildMessage(msg, ap);
    if (!reader->errorFunc) {
        xmlTextReaderValidityWarning(ctx, "%s", str);
    } else {
        reader->errorFunc(reader->errorFuncArg, str,
                          XML_PARSER_SEVERITY_VALIDITY_WARNING,
                          NULL /* locator */ );
    }
    if (str != NULL)
        xmlFree(str);
    va_end(ap);
}

static void
xmlTextReaderStructuredError(void *ctxt, const xmlError *error);

static void
xmlTextReaderValidityStructuredRelay(void *userData, const xmlError *error)
{
    xmlTextReaderPtr reader = (xmlTextReaderPtr) userData;

    if (reader->sErrorFunc) {
        reader->sErrorFunc(reader->errorFuncArg, error);
    } else {
        xmlTextReaderStructuredError(reader, error);
    }
}
/**
 * xmlTextReaderRelaxNGSetSchema:
 * @reader:  the xmlTextReaderPtr used
 * @schema:  a precompiled RelaxNG schema
 *
 * Use RelaxNG to validate the document as it is processed.
 * Activation is only possible before the first Read().
 * if @schema is NULL, then RelaxNG validation is deactivated.
 @ The @schema should not be freed until the reader is deallocated
 * or its use has been deactivated.
 *
 * Returns 0 in case the RelaxNG validation could be (de)activated and
 *         -1 in case of error.
 */
int
xmlTextReaderRelaxNGSetSchema(xmlTextReaderPtr reader, xmlRelaxNGPtr schema) {
    if (reader == NULL)
        return(-1);
    if (schema == NULL) {
        if (reader->rngSchemas != NULL) {
	    xmlRelaxNGFree(reader->rngSchemas);
	    reader->rngSchemas = NULL;
	}
        if (reader->rngValidCtxt != NULL) {
	    if (! reader->rngPreserveCtxt)
		xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);
	    reader->rngValidCtxt = NULL;
        }
	reader->rngPreserveCtxt = 0;
	return(0);
    }
    if (reader->mode != XML_TEXTREADER_MODE_INITIAL)
	return(-1);
    if (reader->rngSchemas != NULL) {
	xmlRelaxNGFree(reader->rngSchemas);
	reader->rngSchemas = NULL;
    }
    if (reader->rngValidCtxt != NULL) {
	if (! reader->rngPreserveCtxt)
	    xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);
	reader->rngValidCtxt = NULL;
    }
    reader->rngPreserveCtxt = 0;
    reader->rngValidCtxt = xmlRelaxNGNewValidCtxt(schema);
    if (reader->rngValidCtxt == NULL)
        return(-1);
    if (reader->errorFunc != NULL) {
	xmlRelaxNGSetValidErrors(reader->rngValidCtxt,
			xmlTextReaderValidityErrorRelay,
			xmlTextReaderValidityWarningRelay,
			reader);
    }
	if (reader->sErrorFunc != NULL) {
		xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,
			xmlTextReaderValidityStructuredRelay,
			reader);
    }
    reader->rngValidErrors = 0;
    reader->rngFullNode = NULL;
    reader->validate = XML_TEXTREADER_VALIDATE_RNG;
    return(0);
}

/**
 * xmlTextReaderLocator:
 * @ctx: the xmlTextReaderPtr used
 * @file: returned file information
 * @line: returned line information
 *
 * Internal locator function for the readers
 *
 * Returns 0 in case the Schema validation could be (de)activated and
 *         -1 in case of error.
 */
static int
xmlTextReaderLocator(void *ctx, const char **file, unsigned long *line) {
    xmlTextReaderPtr reader;

    if ((ctx == NULL) || ((file == NULL) && (line == NULL)))
        return(-1);

    if (file != NULL)
        *file = NULL;
    if (line != NULL)
        *line = 0;

    reader = (xmlTextReaderPtr) ctx;
    if ((reader->ctxt != NULL) && (reader->ctxt->input != NULL)) {
	if (file != NULL)
	    *file = reader->ctxt->input->filename;
	if (line != NULL)
	    *line = reader->ctxt->input->line;
	return(0);
    }
    if (reader->node != NULL) {
        long res;
	int ret = 0;

	if (line != NULL) {
	    res = xmlGetLineNo(reader->node);
	    if (res > 0)
	        *line = (unsigned long) res;
	    else
                ret = -1;
	}
        if (file != NULL) {
	    xmlDocPtr doc = reader->node->doc;
	    if ((doc != NULL) && (doc->URL != NULL))
	        *file = (const char *) doc->URL;
	    else
                ret = -1;
	}
	return(ret);
    }
    return(-1);
}

/**
 * xmlTextReaderSetSchema:
 * @reader:  the xmlTextReaderPtr used
 * @schema:  a precompiled Schema schema
 *
 * Use XSD Schema to validate the document as it is processed.
 * Activation is only possible before the first Read().
 * if @schema is NULL, then Schema validation is deactivated.
 * The @schema should not be freed until the reader is deallocated
 * or its use has been deactivated.
 *
 * Returns 0 in case the Schema validation could be (de)activated and
 *         -1 in case of error.
 */
int
xmlTextReaderSetSchema(xmlTextReaderPtr reader, xmlSchemaPtr schema) {
    if (reader == NULL)
        return(-1);
    if (schema == NULL) {
	if (reader->xsdPlug != NULL) {
	    xmlSchemaSAXUnplug(reader->xsdPlug);
	    reader->xsdPlug = NULL;
	}
        if (reader->xsdValidCtxt != NULL) {
	    if (! reader->xsdPreserveCtxt)
		xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
	    reader->xsdValidCtxt = NULL;
        }
	reader->xsdPreserveCtxt = 0;
        if (reader->xsdSchemas != NULL) {
	    xmlSchemaFree(reader->xsdSchemas);
	    reader->xsdSchemas = NULL;
	}
	return(0);
    }
    if (reader->mode != XML_TEXTREADER_MODE_INITIAL)
	return(-1);
    if (reader->xsdPlug != NULL) {
	xmlSchemaSAXUnplug(reader->xsdPlug);
	reader->xsdPlug = NULL;
    }
    if (reader->xsdValidCtxt != NULL) {
	if (! reader->xsdPreserveCtxt)
	    xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
	reader->xsdValidCtxt = NULL;
    }
    reader->xsdPreserveCtxt = 0;
    if (reader->xsdSchemas != NULL) {
	xmlSchemaFree(reader->xsdSchemas);
	reader->xsdSchemas = NULL;
    }
    reader->xsdValidCtxt = xmlSchemaNewValidCtxt(schema);
    if (reader->xsdValidCtxt == NULL) {
	xmlSchemaFree(reader->xsdSchemas);
	reader->xsdSchemas = NULL;
        return(-1);
    }
    reader->xsdPlug = xmlSchemaSAXPlug(reader->xsdValidCtxt,
                                       &(reader->ctxt->sax),
				       &(reader->ctxt->userData));
    if (reader->xsdPlug == NULL) {
	xmlSchemaFree(reader->xsdSchemas);
	reader->xsdSchemas = NULL;
	xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
	reader->xsdValidCtxt = NULL;
	return(-1);
    }
    xmlSchemaValidateSetLocator(reader->xsdValidCtxt,
                                xmlTextReaderLocator,
				(void *) reader);

    if (reader->errorFunc != NULL) {
	xmlSchemaSetValidErrors(reader->xsdValidCtxt,
			xmlTextReaderValidityErrorRelay,
			xmlTextReaderValidityWarningRelay,
			reader);
    }
	if (reader->sErrorFunc != NULL) {
		xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt,
			xmlTextReaderValidityStructuredRelay,
			reader);
    }
    reader->xsdValidErrors = 0;
    reader->validate = XML_TEXTREADER_VALIDATE_XSD;
    return(0);
}

/**
 * xmlTextReaderRelaxNGValidateInternal:
 * @reader:  the xmlTextReaderPtr used
 * @rng:  the path to a RelaxNG schema or NULL
 * @ctxt: the RelaxNG schema validation context or NULL
 * @options: options (not yet used)
 *
 * Use RelaxNG to validate the document as it is processed.
 * Activation is only possible before the first Read().
 * If both @rng and @ctxt are NULL, then RelaxNG validation is deactivated.
 *
 * Returns 0 in case the RelaxNG validation could be (de)activated and
 *	   -1 in case of error.
 */
static int
xmlTextReaderRelaxNGValidateInternal(xmlTextReaderPtr reader,
				     const char *rng,
				     xmlRelaxNGValidCtxtPtr ctxt,
				     int options ATTRIBUTE_UNUSED)
{
    if (reader == NULL)
	return(-1);

    if ((rng != NULL) && (ctxt != NULL))
	return (-1);

    if (((rng != NULL) || (ctxt != NULL)) &&
	((reader->mode != XML_TEXTREADER_MODE_INITIAL) ||
	 (reader->ctxt == NULL)))
	return(-1);

    /* Cleanup previous validation stuff. */
    if (reader->rngValidCtxt != NULL) {
	if ( !reader->rngPreserveCtxt)
	    xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);
	reader->rngValidCtxt = NULL;
    }
    reader->rngPreserveCtxt = 0;
    if (reader->rngSchemas != NULL) {
	xmlRelaxNGFree(reader->rngSchemas);
	reader->rngSchemas = NULL;
    }

    if ((rng == NULL) && (ctxt == NULL)) {
	/* We just want to deactivate the validation, so get out. */
	return(0);
    }


    if (rng != NULL) {
	xmlRelaxNGParserCtxtPtr pctxt;
	/* Parse the schema and create validation environment. */

	pctxt = xmlRelaxNGNewParserCtxt(rng);
	if (reader->errorFunc != NULL) {
	    xmlRelaxNGSetParserErrors(pctxt,
		xmlTextReaderValidityErrorRelay,
		xmlTextReaderValidityWarningRelay,
		reader);
	}
	if (reader->sErrorFunc != NULL) {
	    xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,
		xmlTextReaderValidityStructuredRelay,
		reader);
	}
	reader->rngSchemas = xmlRelaxNGParse(pctxt);
	xmlRelaxNGFreeParserCtxt(pctxt);
	if (reader->rngSchemas == NULL)
	    return(-1);
	reader->rngValidCtxt = xmlRelaxNGNewValidCtxt(reader->rngSchemas);
	if (reader->rngValidCtxt == NULL) {
	    xmlRelaxNGFree(reader->rngSchemas);
	    reader->rngSchemas = NULL;
	    return(-1);
	}
    } else {
	/* Use the given validation context. */
	reader->rngValidCtxt = ctxt;
	reader->rngPreserveCtxt = 1;
    }
    /*
    * Redirect the validation context's error channels to use
    * the reader channels.
    * TODO: In case the user provides the validation context we
    *	could make this redirection optional.
    */
    if (reader->errorFunc != NULL) {
	xmlRelaxNGSetValidErrors(reader->rngValidCtxt,
			 xmlTextReaderValidityErrorRelay,
			 xmlTextReaderValidityWarningRelay,
			 reader);
    }
	if (reader->sErrorFunc != NULL) {
		xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,
			xmlTextReaderValidityStructuredRelay,
			reader);
    }
    reader->rngValidErrors = 0;
    reader->rngFullNode = NULL;
    reader->validate = XML_TEXTREADER_VALIDATE_RNG;
    return(0);
}

/**
 * xmlTextReaderSchemaValidateInternal:
 * @reader:  the xmlTextReaderPtr used
 * @xsd:  the path to a W3C XSD schema or NULL
 * @ctxt: the XML Schema validation context or NULL
 * @options: options (not used yet)
 *
 * Validate the document as it is processed using XML Schema.
 * Activation is only possible before the first Read().
 * If both @xsd and @ctxt are NULL then XML Schema validation is deactivated.
 *
 * Returns 0 in case the schemas validation could be (de)activated and
 *         -1 in case of error.
 */
static int
xmlTextReaderSchemaValidateInternal(xmlTextReaderPtr reader,
				    const char *xsd,
				    xmlSchemaValidCtxtPtr ctxt,
				    int options ATTRIBUTE_UNUSED)
{
    if (reader == NULL)
        return(-1);

    if ((xsd != NULL) && (ctxt != NULL))
	return(-1);

    if (((xsd != NULL) || (ctxt != NULL)) &&
	((reader->mode != XML_TEXTREADER_MODE_INITIAL) ||
        (reader->ctxt == NULL)))
	return(-1);

    /* Cleanup previous validation stuff. */
    if (reader->xsdPlug != NULL) {
	xmlSchemaSAXUnplug(reader->xsdPlug);
	reader->xsdPlug = NULL;
    }
    if (reader->xsdValidCtxt != NULL) {
	if (! reader->xsdPreserveCtxt)
	    xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
	reader->xsdValidCtxt = NULL;
    }
    reader->xsdPreserveCtxt = 0;
    if (reader->xsdSchemas != NULL) {
	xmlSchemaFree(reader->xsdSchemas);
	reader->xsdSchemas = NULL;
    }

    if ((xsd == NULL) && (ctxt == NULL)) {
	/* We just want to deactivate the validation, so get out. */
	return(0);
    }

    if (xsd != NULL) {
	xmlSchemaParserCtxtPtr pctxt;
	/* Parse the schema and create validation environment. */
	pctxt = xmlSchemaNewParserCtxt(xsd);
	if (reader->errorFunc != NULL) {
	    xmlSchemaSetParserErrors(pctxt,
		xmlTextReaderValidityErrorRelay,
		xmlTextReaderValidityWarningRelay,
		reader);
	}
	reader->xsdSchemas = xmlSchemaParse(pctxt);
	xmlSchemaFreeParserCtxt(pctxt);
	if (reader->xsdSchemas == NULL)
	    return(-1);
	reader->xsdValidCtxt = xmlSchemaNewValidCtxt(reader->xsdSchemas);
	if (reader->xsdValidCtxt == NULL) {
	    xmlSchemaFree(reader->xsdSchemas);
	    reader->xsdSchemas = NULL;
	    return(-1);
	}
	reader->xsdPlug = xmlSchemaSAXPlug(reader->xsdValidCtxt,
	    &(reader->ctxt->sax),
	    &(reader->ctxt->userData));
	if (reader->xsdPlug == NULL) {
	    xmlSchemaFree(reader->xsdSchemas);
	    reader->xsdSchemas = NULL;
	    xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
	    reader->xsdValidCtxt = NULL;
	    return(-1);
	}
    } else {
	/* Use the given validation context. */
	reader->xsdValidCtxt = ctxt;
	reader->xsdPreserveCtxt = 1;
	reader->xsdPlug = xmlSchemaSAXPlug(reader->xsdValidCtxt,
	    &(reader->ctxt->sax),
	    &(reader->ctxt->userData));
	if (reader->xsdPlug == NULL) {
	    reader->xsdValidCtxt = NULL;
	    reader->xsdPreserveCtxt = 0;
	    return(-1);
	}
    }
    xmlSchemaValidateSetLocator(reader->xsdValidCtxt,
                                xmlTextReaderLocator,
				(void *) reader);
    /*
    * Redirect the validation context's error channels to use
    * the reader channels.
    * TODO: In case the user provides the validation context we
    *   could make this redirection optional.
    */
    if (reader->errorFunc != NULL) {
	xmlSchemaSetValidErrors(reader->xsdValidCtxt,
			 xmlTextReaderValidityErrorRelay,
			 xmlTextReaderValidityWarningRelay,
			 reader);
    }
	if (reader->sErrorFunc != NULL) {
		xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt,
			xmlTextReaderValidityStructuredRelay,
			reader);
    }
    reader->xsdValidErrors = 0;
    reader->validate = XML_TEXTREADER_VALIDATE_XSD;
    return(0);
}

/**
 * xmlTextReaderSchemaValidateCtxt:
 * @reader:  the xmlTextReaderPtr used
 * @ctxt: the XML Schema validation context or NULL
 * @options: options (not used yet)
 *
 * Use W3C XSD schema context to validate the document as it is processed.
 * Activation is only possible before the first Read().
 * If @ctxt is NULL, then XML Schema validation is deactivated.
 *
 * Returns 0 in case the schemas validation could be (de)activated and
 *         -1 in case of error.
 */
int
xmlTextReaderSchemaValidateCtxt(xmlTextReaderPtr reader,
				    xmlSchemaValidCtxtPtr ctxt,
				    int options)
{
    return(xmlTextReaderSchemaValidateInternal(reader, NULL, ctxt, options));
}

/**
 * xmlTextReaderSchemaValidate:
 * @reader:  the xmlTextReaderPtr used
 * @xsd:  the path to a W3C XSD schema or NULL
 *
 * Use W3C XSD schema to validate the document as it is processed.
 * Activation is only possible before the first Read().
 * If @xsd is NULL, then XML Schema validation is deactivated.
 *
 * Returns 0 in case the schemas validation could be (de)activated and
 *         -1 in case of error.
 */
int
xmlTextReaderSchemaValidate(xmlTextReaderPtr reader, const char *xsd)
{
    return(xmlTextReaderSchemaValidateInternal(reader, xsd, NULL, 0));
}

/**
 * xmlTextReaderRelaxNGValidateCtxt:
 * @reader:  the xmlTextReaderPtr used
 * @ctxt: the RelaxNG schema validation context or NULL
 * @options: options (not used yet)
 *
 * Use RelaxNG schema context to validate the document as it is processed.
 * Activation is only possible before the first Read().
 * If @ctxt is NULL, then RelaxNG schema validation is deactivated.
 *
 * Returns 0 in case the schemas validation could be (de)activated and
 *         -1 in case of error.
 */
int
xmlTextReaderRelaxNGValidateCtxt(xmlTextReaderPtr reader,
				 xmlRelaxNGValidCtxtPtr ctxt,
				 int options)
{
    return(xmlTextReaderRelaxNGValidateInternal(reader, NULL, ctxt, options));
}

/**
 * xmlTextReaderRelaxNGValidate:
 * @reader:  the xmlTextReaderPtr used
 * @rng:  the path to a RelaxNG schema or NULL
 *
 * Use RelaxNG schema to validate the document as it is processed.
 * Activation is only possible before the first Read().
 * If @rng is NULL, then RelaxNG schema validation is deactivated.
 *
 * Returns 0 in case the schemas validation could be (de)activated and
 *         -1 in case of error.
 */
int
xmlTextReaderRelaxNGValidate(xmlTextReaderPtr reader, const char *rng)
{
    return(xmlTextReaderRelaxNGValidateInternal(reader, rng, NULL, 0));
}

#endif

/**
 * xmlTextReaderIsNamespaceDecl:
 * @reader: the xmlTextReaderPtr used
 *
 * Determine whether the current node is a namespace declaration
 * rather than a regular attribute.
 *
 * Returns 1 if the current node is a namespace declaration, 0 if it
 * is a regular attribute or other type of node, or -1 in case of
 * error.
 */
int
xmlTextReaderIsNamespaceDecl(xmlTextReaderPtr reader) {
    xmlNodePtr node;
    if (reader == NULL)
	return(-1);
    if (reader->node == NULL)
	return(-1);
    if (reader->curnode != NULL)
	node = reader->curnode;
    else
	node = reader->node;

    if (XML_NAMESPACE_DECL == node->type)
	return(1);
    else
	return(0);
}

/**
 * xmlTextReaderConstXmlVersion:
 * @reader:  the xmlTextReaderPtr used
 *
 * Determine the XML version of the document being read.
 *
 * Returns a string containing the XML version of the document or NULL
 * in case of error.  The string is deallocated with the reader.
 */
const xmlChar *
xmlTextReaderConstXmlVersion(xmlTextReaderPtr reader) {
    xmlDocPtr doc = NULL;
    if (reader == NULL)
	return(NULL);
    if (reader->doc != NULL)
        doc = reader->doc;
    else if (reader->ctxt != NULL)
	doc = reader->ctxt->myDoc;
    if (doc == NULL)
	return(NULL);

    if (doc->version == NULL)
	return(NULL);
    else
      return(CONSTSTR(doc->version));
}

/**
 * xmlTextReaderStandalone:
 * @reader:  the xmlTextReaderPtr used
 *
 * Determine the standalone status of the document being read.
 *
 * Returns 1 if the document was declared to be standalone, 0 if it
 * was declared to be not standalone, or -1 if the document did not
 * specify its standalone status or in case of error.
 */
int
xmlTextReaderStandalone(xmlTextReaderPtr reader) {
    xmlDocPtr doc = NULL;
    if (reader == NULL)
	return(-1);
    if (reader->doc != NULL)
        doc = reader->doc;
    else if (reader->ctxt != NULL)
	doc = reader->ctxt->myDoc;
    if (doc == NULL)
	return(-1);

    return(doc->standalone);
}

/************************************************************************
 *									*
 *			Error Handling Extensions                       *
 *									*
 ************************************************************************/

/* helper to build a xmlMalloc'ed string from a format and va_list */
static char *
xmlTextReaderBuildMessage(const char *msg, va_list ap) {
    int size = 0;
    int chars;
    char *larger;
    char *str = NULL;
    va_list aq;

    while (1) {
        VA_COPY(aq, ap);
        chars = vsnprintf(str, size, msg, aq);
        va_end(aq);
        if (chars < 0) {
	    xmlGenericError(xmlGenericErrorContext, "vsnprintf failed !\n");
	    if (str)
		xmlFree(str);
	    return NULL;
	}
	if ((chars < size) || (size == MAX_ERR_MSG_SIZE))
            break;
        if (chars < MAX_ERR_MSG_SIZE)
	size = chars + 1;
	else
		size = MAX_ERR_MSG_SIZE;
        if ((larger = (char *) xmlRealloc(str, size)) == NULL) {
	    xmlGenericError(xmlGenericErrorContext, "xmlRealloc failed !\n");
	    if (str)
                xmlFree(str);
            return NULL;
        }
        str = larger;
    }

    return str;
}

/**
 * xmlTextReaderLocatorLineNumber:
 * @locator: the xmlTextReaderLocatorPtr used
 *
 * Obtain the line number for the given locator.
 *
 * Returns the line number or -1 in case of error.
 */
int
xmlTextReaderLocatorLineNumber(xmlTextReaderLocatorPtr locator) {
    /* we know that locator is a xmlParserCtxtPtr */
    xmlParserCtxtPtr ctx = (xmlParserCtxtPtr)locator;
    int ret = -1;

    if (locator == NULL)
        return(-1);
    if (ctx->node != NULL) {
	ret = xmlGetLineNo(ctx->node);
    }
    else {
	/* inspired from error.c */
	xmlParserInputPtr input;
	input = ctx->input;
	if ((input->filename == NULL) && (ctx->inputNr > 1))
	    input = ctx->inputTab[ctx->inputNr - 2];
	if (input != NULL) {
	    ret = input->line;
	}
	else {
	    ret = -1;
	}
    }

    return ret;
}

/**
 * xmlTextReaderLocatorBaseURI:
 * @locator: the xmlTextReaderLocatorPtr used
 *
 * Obtain the base URI for the given locator.
 *
 * Returns the base URI or NULL in case of error,
 *    if non NULL it need to be freed by the caller.
 */
xmlChar *
xmlTextReaderLocatorBaseURI(xmlTextReaderLocatorPtr locator) {
    /* we know that locator is a xmlParserCtxtPtr */
    xmlParserCtxtPtr ctx = (xmlParserCtxtPtr)locator;
    xmlChar *ret = NULL;

    if (locator == NULL)
        return(NULL);
    if (ctx->node != NULL) {
	ret = xmlNodeGetBase(NULL,ctx->node);
    }
    else {
	/* inspired from error.c */
	xmlParserInputPtr input;
	input = ctx->input;
	if ((input->filename == NULL) && (ctx->inputNr > 1))
	    input = ctx->inputTab[ctx->inputNr - 2];
	if (input != NULL) {
	    ret = xmlStrdup(BAD_CAST input->filename);
	}
	else {
	    ret = NULL;
	}
    }

    return ret;
}

static void
xmlTextReaderGenericError(void *ctxt, xmlParserSeverities severity,
                          char *str)
{
    xmlParserCtxtPtr ctx = (xmlParserCtxtPtr) ctxt;

    xmlTextReaderPtr reader = (xmlTextReaderPtr) ctx->_private;

    if (str != NULL) {
        if (reader->errorFunc)
            reader->errorFunc(reader->errorFuncArg, str, severity,
                              (xmlTextReaderLocatorPtr) ctx);
        xmlFree(str);
    }
}

static void
xmlTextReaderStructuredError(void *ctxt, const xmlError *error)
{
    xmlParserCtxtPtr ctx = (xmlParserCtxtPtr) ctxt;

    xmlTextReaderPtr reader = (xmlTextReaderPtr) ctx->_private;

    if (error && reader->sErrorFunc) {
        reader->sErrorFunc(reader->errorFuncArg, (xmlErrorPtr) error);
    }
}

static void LIBXML_ATTR_FORMAT(2,3)
xmlTextReaderError(void *ctxt, const char *msg, ...)
{
    va_list ap;

    va_start(ap, msg);
    xmlTextReaderGenericError(ctxt,
                              XML_PARSER_SEVERITY_ERROR,
                              xmlTextReaderBuildMessage(msg, ap));
    va_end(ap);

}

static void LIBXML_ATTR_FORMAT(2,3)
xmlTextReaderWarning(void *ctxt, const char *msg, ...)
{
    va_list ap;

    va_start(ap, msg);
    xmlTextReaderGenericError(ctxt,
                              XML_PARSER_SEVERITY_WARNING,
                              xmlTextReaderBuildMessage(msg, ap));
    va_end(ap);
}

static void
xmlTextReaderValidityError(void *ctxt, const char *msg, ...)
{
    va_list ap;

    int len = xmlStrlen((const xmlChar *) msg);

    if ((len > 1) && (msg[len - 2] != ':')) {
        /*
         * some callbacks only report locator information:
         * skip them (mimicking behaviour in error.c)
         */
        va_start(ap, msg);
        xmlTextReaderGenericError(ctxt,
                                  XML_PARSER_SEVERITY_VALIDITY_ERROR,
                                  xmlTextReaderBuildMessage(msg, ap));
        va_end(ap);
    }
}

static void
xmlTextReaderValidityWarning(void *ctxt, const char *msg, ...)
{
    va_list ap;

    int len = xmlStrlen((const xmlChar *) msg);

    if ((len != 0) && (msg[len - 1] != ':')) {
        /*
         * some callbacks only report locator information:
         * skip them (mimicking behaviour in error.c)
         */
        va_start(ap, msg);
        xmlTextReaderGenericError(ctxt,
                                  XML_PARSER_SEVERITY_VALIDITY_WARNING,
                                  xmlTextReaderBuildMessage(msg, ap));
        va_end(ap);
    }
}

/**
 * xmlTextReaderSetErrorHandler:
 * @reader:  the xmlTextReaderPtr used
 * @f:	the callback function to call on error and warnings
 * @arg:    a user argument to pass to the callback function
 *
 * Register a callback function that will be called on error and warnings.
 *
 * If @f is NULL, the default error and warning handlers are restored.
 */
void
xmlTextReaderSetErrorHandler(xmlTextReaderPtr reader,
                             xmlTextReaderErrorFunc f, void *arg)
{
    if (f != NULL) {
        reader->ctxt->sax->error = xmlTextReaderError;
        reader->ctxt->sax->serror = NULL;
        reader->ctxt->vctxt.error = xmlTextReaderValidityError;
        reader->ctxt->sax->warning = xmlTextReaderWarning;
        reader->ctxt->vctxt.warning = xmlTextReaderValidityWarning;
        reader->errorFunc = f;
        reader->sErrorFunc = NULL;
        reader->errorFuncArg = arg;
#ifdef LIBXML_SCHEMAS_ENABLED
        if (reader->rngValidCtxt) {
            xmlRelaxNGSetValidErrors(reader->rngValidCtxt,
                                     xmlTextReaderValidityErrorRelay,
                                     xmlTextReaderValidityWarningRelay,
                                     reader);
            xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt, NULL,
                                               reader);
        }
        if (reader->xsdValidCtxt) {
            xmlSchemaSetValidErrors(reader->xsdValidCtxt,
                                    xmlTextReaderValidityErrorRelay,
                                    xmlTextReaderValidityWarningRelay,
                                    reader);
            xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt, NULL,
                                              reader);
        }
#endif
    } else {
        /* restore defaults */
        reader->ctxt->sax->error = xmlParserError;
        reader->ctxt->vctxt.error = xmlParserValidityError;
        reader->ctxt->sax->warning = xmlParserWarning;
        reader->ctxt->vctxt.warning = xmlParserValidityWarning;
        reader->errorFunc = NULL;
        reader->sErrorFunc = NULL;
        reader->errorFuncArg = NULL;
#ifdef LIBXML_SCHEMAS_ENABLED
        if (reader->rngValidCtxt) {
            xmlRelaxNGSetValidErrors(reader->rngValidCtxt, NULL, NULL,
                                     reader);
            xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt, NULL,
                                               reader);
        }
        if (reader->xsdValidCtxt) {
            xmlSchemaSetValidErrors(reader->xsdValidCtxt, NULL, NULL,
                                    reader);
            xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt, NULL,
                                              reader);
        }
#endif
    }
}

/**
* xmlTextReaderSetStructuredErrorHandler:
 * @reader:  the xmlTextReaderPtr used
 * @f:	the callback function to call on error and warnings
 * @arg:    a user argument to pass to the callback function
 *
 * Register a callback function that will be called on error and warnings.
 *
 * If @f is NULL, the default error and warning handlers are restored.
 */
void
xmlTextReaderSetStructuredErrorHandler(xmlTextReaderPtr reader,
                                       xmlStructuredErrorFunc f, void *arg)
{
    if (f != NULL) {
        reader->ctxt->sax->error = NULL;
        reader->ctxt->sax->serror = xmlTextReaderStructuredError;
        reader->ctxt->vctxt.error = xmlTextReaderValidityError;
        reader->ctxt->sax->warning = xmlTextReaderWarning;
        reader->ctxt->vctxt.warning = xmlTextReaderValidityWarning;
        reader->sErrorFunc = f;
        reader->errorFunc = NULL;
        reader->errorFuncArg = arg;
#ifdef LIBXML_SCHEMAS_ENABLED
        if (reader->rngValidCtxt) {
            xmlRelaxNGSetValidErrors(reader->rngValidCtxt, NULL, NULL,
                                     reader);
            xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,
                                        xmlTextReaderValidityStructuredRelay,
                                               reader);
        }
        if (reader->xsdValidCtxt) {
            xmlSchemaSetValidErrors(reader->xsdValidCtxt, NULL, NULL,
                                    reader);
            xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt,
                                       xmlTextReaderValidityStructuredRelay,
                                              reader);
        }
#endif
    } else {
        /* restore defaults */
        reader->ctxt->sax->error = xmlParserError;
        reader->ctxt->sax->serror = NULL;
        reader->ctxt->vctxt.error = xmlParserValidityError;
        reader->ctxt->sax->warning = xmlParserWarning;
        reader->ctxt->vctxt.warning = xmlParserValidityWarning;
        reader->errorFunc = NULL;
        reader->sErrorFunc = NULL;
        reader->errorFuncArg = NULL;
#ifdef LIBXML_SCHEMAS_ENABLED
        if (reader->rngValidCtxt) {
            xmlRelaxNGSetValidErrors(reader->rngValidCtxt, NULL, NULL,
                                     reader);
            xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt, NULL,
                                               reader);
        }
        if (reader->xsdValidCtxt) {
            xmlSchemaSetValidErrors(reader->xsdValidCtxt, NULL, NULL,
                                    reader);
            xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt, NULL,
                                              reader);
        }
#endif
    }
}

/**
 * xmlTextReaderIsValid:
 * @reader:  the xmlTextReaderPtr used
 *
 * Retrieve the validity status from the parser context
 *
 * Returns the flag value 1 if valid, 0 if no, and -1 in case of error
 */
int
xmlTextReaderIsValid(xmlTextReaderPtr reader)
{
    if (reader == NULL)
        return (-1);
#ifdef LIBXML_SCHEMAS_ENABLED
    if (reader->validate == XML_TEXTREADER_VALIDATE_RNG)
        return (reader->rngValidErrors == 0);
    if (reader->validate == XML_TEXTREADER_VALIDATE_XSD)
        return (reader->xsdValidErrors == 0);
#endif
    if ((reader->ctxt != NULL) && (reader->ctxt->validate == 1))
        return (reader->ctxt->valid);
    return (0);
}

/**
 * xmlTextReaderGetErrorHandler:
 * @reader:  the xmlTextReaderPtr used
 * @f:	the callback function or NULL is no callback has been registered
 * @arg:    a user argument
 *
 * Retrieve the error callback function and user argument.
 */
void
xmlTextReaderGetErrorHandler(xmlTextReaderPtr reader,
                             xmlTextReaderErrorFunc * f, void **arg)
{
    if (f != NULL)
        *f = reader->errorFunc;
    if (arg != NULL)
        *arg = reader->errorFuncArg;
}
/************************************************************************
 *									*
 *	New set (2.6.0) of simpler and more flexible APIs		*
 *									*
 ************************************************************************/

/**
 * xmlTextReaderSetup:
 * @reader:  an XML reader
 * @input: xmlParserInputBufferPtr used to feed the reader, will
 *         be destroyed with it.
 * @URL:  the base URL to use for the document
 * @encoding:  the document encoding, or NULL
 * @options:  a combination of xmlParserOption
 *
 * Setup an XML reader with new options
 *
 * Returns 0 in case of success and -1 in case of error.
 */
int
xmlTextReaderSetup(xmlTextReaderPtr reader,
                   xmlParserInputBufferPtr input, const char *URL,
                   const char *encoding, int options)
{
    if (reader == NULL) {
        if (input != NULL)
	    xmlFreeParserInputBuffer(input);
        return (-1);
    }

    /*
     * we force the generation of compact text nodes on the reader
     * since usr applications should never modify the tree
     */
    options |= XML_PARSE_COMPACT;

    reader->doc = NULL;
    reader->entNr = 0;
    reader->parserFlags = options;
    reader->validate = XML_TEXTREADER_NOT_VALIDATE;
    if ((input != NULL) && (reader->input != NULL) &&
        (reader->allocs & XML_TEXTREADER_INPUT)) {
	xmlFreeParserInputBuffer(reader->input);
	reader->input = NULL;
	reader->allocs -= XML_TEXTREADER_INPUT;
    }
    if (input != NULL) {
	reader->input = input;
	reader->allocs |= XML_TEXTREADER_INPUT;
    }
    if (reader->buffer == NULL)
        reader->buffer = xmlBufCreateSize(100);
    if (reader->buffer == NULL) {
        xmlGenericError(xmlGenericErrorContext,
                        "xmlTextReaderSetup : malloc failed\n");
        return (-1);
    }
    /* no operation on a reader should require a huge buffer */
    xmlBufSetAllocationScheme(reader->buffer,
			      XML_BUFFER_ALLOC_DOUBLEIT);
    if (reader->sax == NULL)
	reader->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
    if (reader->sax == NULL) {
        xmlGenericError(xmlGenericErrorContext,
                        "xmlTextReaderSetup : malloc failed\n");
        return (-1);
    }
    xmlSAXVersion(reader->sax, 2);
    reader->startElement = reader->sax->startElement;
    reader->sax->startElement = xmlTextReaderStartElement;
    reader->endElement = reader->sax->endElement;
    reader->sax->endElement = xmlTextReaderEndElement;
#ifdef LIBXML_SAX1_ENABLED
    if (reader->sax->initialized == XML_SAX2_MAGIC) {
#endif /* LIBXML_SAX1_ENABLED */
        reader->startElementNs = reader->sax->startElementNs;
        reader->sax->startElementNs = xmlTextReaderStartElementNs;
        reader->endElementNs = reader->sax->endElementNs;
        reader->sax->endElementNs = xmlTextReaderEndElementNs;
#ifdef LIBXML_SAX1_ENABLED
    } else {
        reader->startElementNs = NULL;
        reader->endElementNs = NULL;
    }
#endif /* LIBXML_SAX1_ENABLED */
    reader->characters = reader->sax->characters;
    reader->sax->characters = xmlTextReaderCharacters;
    reader->sax->ignorableWhitespace = xmlTextReaderCharacters;
    reader->cdataBlock = reader->sax->cdataBlock;
    reader->sax->cdataBlock = xmlTextReaderCDataBlock;

    reader->mode = XML_TEXTREADER_MODE_INITIAL;
    reader->node = NULL;
    reader->curnode = NULL;
    if (input != NULL) {
        if (xmlBufUse(reader->input->buffer) < 4) {
            xmlParserInputBufferRead(input, 4);
        }
        if (reader->ctxt == NULL) {
            if (xmlBufUse(reader->input->buffer) >= 4) {
                reader->ctxt = xmlCreatePushParserCtxt(reader->sax, NULL,
		       (const char *) xmlBufContent(reader->input->buffer),
                                      4, URL);
                reader->base = 0;
                reader->cur = 4;
            } else {
                reader->ctxt =
                    xmlCreatePushParserCtxt(reader->sax, NULL, NULL, 0, URL);
                reader->base = 0;
                reader->cur = 0;
            }
        } else {
	    xmlParserInputPtr inputStream;
	    xmlParserInputBufferPtr buf;
	    xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;

	    xmlCtxtReset(reader->ctxt);
	    buf = xmlAllocParserInputBuffer(enc);
	    if (buf == NULL) return(-1);
	    inputStream = xmlNewInputStream(reader->ctxt);
	    if (inputStream == NULL) {
		xmlFreeParserInputBuffer(buf);
		return(-1);
	    }

	    if (URL == NULL)
		inputStream->filename = NULL;
	    else
		inputStream->filename = (char *)
		    xmlCanonicPath((const xmlChar *) URL);
	    inputStream->buf = buf;
            xmlBufResetInput(buf->buffer, inputStream);

	    inputPush(reader->ctxt, inputStream);
	    reader->cur = 0;
	}
        if (reader->ctxt == NULL) {
            xmlGenericError(xmlGenericErrorContext,
                            "xmlTextReaderSetup : malloc failed\n");
            return (-1);
        }
    }
    if (reader->dict != NULL) {
        if (reader->ctxt->dict != NULL) {
	    if (reader->dict != reader->ctxt->dict) {
		xmlDictFree(reader->dict);
		reader->dict = reader->ctxt->dict;
	    }
	} else {
	    reader->ctxt->dict = reader->dict;
	}
    } else {
	if (reader->ctxt->dict == NULL)
	    reader->ctxt->dict = xmlDictCreate();
        reader->dict = reader->ctxt->dict;
    }
    reader->ctxt->_private = reader;
    reader->ctxt->linenumbers = 1;
    reader->ctxt->dictNames = 1;
    /*
     * use the parser dictionary to allocate all elements and attributes names
     */
    reader->ctxt->docdict = 1;
    reader->ctxt->parseMode = XML_PARSE_READER;

#ifdef LIBXML_XINCLUDE_ENABLED
    if (reader->xincctxt != NULL) {
	xmlXIncludeFreeContext(reader->xincctxt);
	reader->xincctxt = NULL;
    }
    if (options & XML_PARSE_XINCLUDE) {
        reader->xinclude = 1;
	reader->xinclude_name = xmlDictLookup(reader->dict, XINCLUDE_NODE, -1);
	options -= XML_PARSE_XINCLUDE;
    } else
        reader->xinclude = 0;
    reader->in_xinclude = 0;
#endif
#ifdef LIBXML_PATTERN_ENABLED
    if (reader->patternTab == NULL) {
        reader->patternNr = 0;
	reader->patternMax = 0;
    }
    while (reader->patternNr > 0) {
        reader->patternNr--;
	if (reader->patternTab[reader->patternNr] != NULL) {
	    xmlFreePattern(reader->patternTab[reader->patternNr]);
            reader->patternTab[reader->patternNr] = NULL;
	}
    }
#endif

    if (options & XML_PARSE_DTDVALID)
        reader->validate = XML_TEXTREADER_VALIDATE_DTD;

    xmlCtxtUseOptions(reader->ctxt, options);
    if (encoding != NULL) {
        xmlCharEncodingHandlerPtr hdlr;

        hdlr = xmlFindCharEncodingHandler(encoding);
        if (hdlr != NULL)
            xmlSwitchToEncoding(reader->ctxt, hdlr);
    }
    if ((URL != NULL) && (reader->ctxt->input != NULL) &&
        (reader->ctxt->input->filename == NULL))
        reader->ctxt->input->filename = (char *)
            xmlStrdup((const xmlChar *) URL);

    reader->doc = NULL;

    return (0);
}

/**
 * xmlTextReaderSetMaxAmplification:
 * @reader: an XML reader
 * @maxAmpl:  maximum amplification factor
 *
 * Set the maximum amplification factor. See xmlCtxtSetMaxAmplification.
 */
void
xmlTextReaderSetMaxAmplification(xmlTextReaderPtr reader, unsigned maxAmpl)
{
    xmlCtxtSetMaxAmplification(reader->ctxt, maxAmpl);
}

/**
 * xmlTextReaderByteConsumed:
 * @reader: an XML reader
 *
 * This function provides the current index of the parser used
 * by the reader, relative to the start of the current entity.
 * This function actually just wraps a call to xmlBytesConsumed()
 * for the parser context associated with the reader.
 * See xmlBytesConsumed() for more information.
 *
 * Returns the index in bytes from the beginning of the entity or -1
 *         in case the index could not be computed.
 */
long
xmlTextReaderByteConsumed(xmlTextReaderPtr reader) {
    if ((reader == NULL) || (reader->ctxt == NULL))
        return(-1);
    return(xmlByteConsumed(reader->ctxt));
}


/**
 * xmlReaderWalker:
 * @doc:  a preparsed document
 *
 * Create an xmltextReader for a preparsed document.
 *
 * Returns the new reader or NULL in case of error.
 */
xmlTextReaderPtr
xmlReaderWalker(xmlDocPtr doc)
{
    xmlTextReaderPtr ret;

    if (doc == NULL)
        return(NULL);

    ret = xmlMalloc(sizeof(xmlTextReader));
    if (ret == NULL) {
        xmlGenericError(xmlGenericErrorContext,
		"xmlNewTextReader : malloc failed\n");
	return(NULL);
    }
    memset(ret, 0, sizeof(xmlTextReader));
    ret->entNr = 0;
    ret->input = NULL;
    ret->mode = XML_TEXTREADER_MODE_INITIAL;
    ret->node = NULL;
    ret->curnode = NULL;
    ret->base = 0;
    ret->cur = 0;
    ret->allocs = XML_TEXTREADER_CTXT;
    ret->doc = doc;
    ret->state = XML_TEXTREADER_START;
    ret->dict = xmlDictCreate();
    return(ret);
}

/**
 * xmlReaderForDoc:
 * @cur:  a pointer to a zero terminated string
 * @URL:  the base URL to use for the document
 * @encoding:  the document encoding, or NULL
 * @options:  a combination of xmlParserOption
 *
 * Create an xmltextReader for an XML in-memory document.
 * The parsing flags @options are a combination of xmlParserOption.
 *
 * Returns the new reader or NULL in case of error.
 */
xmlTextReaderPtr
xmlReaderForDoc(const xmlChar * cur, const char *URL, const char *encoding,
                int options)
{
    int len;

    if (cur == NULL)
        return (NULL);
    len = xmlStrlen(cur);

    return (xmlReaderForMemory
            ((const char *) cur, len, URL, encoding, options));
}

/**
 * xmlReaderForFile:
 * @filename:  a file or URL
 * @encoding:  the document encoding, or NULL
 * @options:  a combination of xmlParserOption
 *
 * parse an XML file from the filesystem or the network.
 * The parsing flags @options are a combination of xmlParserOption.
 *
 * Returns the new reader or NULL in case of error.
 */
xmlTextReaderPtr
xmlReaderForFile(const char *filename, const char *encoding, int options)
{
    xmlTextReaderPtr reader;

    reader = xmlNewTextReaderFilename(filename);
    if (reader == NULL)
        return (NULL);
    xmlTextReaderSetup(reader, NULL, NULL, encoding, options);
    return (reader);
}

/**
 * xmlReaderForMemory:
 * @buffer:  a pointer to a char array
 * @size:  the size of the array
 * @URL:  the base URL to use for the document
 * @encoding:  the document encoding, or NULL
 * @options:  a combination of xmlParserOption
 *
 * Create an xmltextReader for an XML in-memory document.
 * The parsing flags @options are a combination of xmlParserOption.
 *
 * Returns the new reader or NULL in case of error.
 */
xmlTextReaderPtr
xmlReaderForMemory(const char *buffer, int size, const char *URL,
                   const char *encoding, int options)
{
    xmlTextReaderPtr reader;
    xmlParserInputBufferPtr buf;

    buf = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
    if (buf == NULL) {
        return (NULL);
    }
    reader = xmlNewTextReader(buf, URL);
    if (reader == NULL) {
        xmlFreeParserInputBuffer(buf);
        return (NULL);
    }
    reader->allocs |= XML_TEXTREADER_INPUT;
    xmlTextReaderSetup(reader, NULL, URL, encoding, options);
    return (reader);
}

/**
 * xmlReaderForFd:
 * @fd:  an open file descriptor
 * @URL:  the base URL to use for the document
 * @encoding:  the document encoding, or NULL
 * @options:  a combination of xmlParserOption
 *
 * Create an xmltextReader for an XML from a file descriptor.
 * The parsing flags @options are a combination of xmlParserOption.
 * NOTE that the file descriptor will not be closed when the
 *      reader is closed or reset.
 *
 * Returns the new reader or NULL in case of error.
 */
xmlTextReaderPtr
xmlReaderForFd(int fd, const char *URL, const char *encoding, int options)
{
    xmlTextReaderPtr reader;
    xmlParserInputBufferPtr input;

    if (fd < 0)
        return (NULL);

    input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
    if (input == NULL)
        return (NULL);
    input->closecallback = NULL;
    reader = xmlNewTextReader(input, URL);
    if (reader == NULL) {
        xmlFreeParserInputBuffer(input);
        return (NULL);
    }
    reader->allocs |= XML_TEXTREADER_INPUT;
    xmlTextReaderSetup(reader, NULL, URL, encoding, options);
    return (reader);
}

/**
 * xmlReaderForIO:
 * @ioread:  an I/O read function
 * @ioclose:  an I/O close function
 * @ioctx:  an I/O handler
 * @URL:  the base URL to use for the document
 * @encoding:  the document encoding, or NULL
 * @options:  a combination of xmlParserOption
 *
 * Create an xmltextReader for an XML document from I/O functions and source.
 * The parsing flags @options are a combination of xmlParserOption.
 *
 * Returns the new reader or NULL in case of error.
 */
xmlTextReaderPtr
xmlReaderForIO(xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
               void *ioctx, const char *URL, const char *encoding,
               int options)
{
    xmlTextReaderPtr reader;
    xmlParserInputBufferPtr input;

    if (ioread == NULL)
        return (NULL);

    input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
                                         XML_CHAR_ENCODING_NONE);
    if (input == NULL) {
        if (ioclose != NULL)
            ioclose(ioctx);
        return (NULL);
    }
    reader = xmlNewTextReader(input, URL);
    if (reader == NULL) {
        xmlFreeParserInputBuffer(input);
        return (NULL);
    }
    reader->allocs |= XML_TEXTREADER_INPUT;
    xmlTextReaderSetup(reader, NULL, URL, encoding, options);
    return (reader);
}

/**
 * xmlReaderNewWalker:
 * @reader:  an XML reader
 * @doc:  a preparsed document
 *
 * Setup an xmltextReader to parse a preparsed XML document.
 * This reuses the existing @reader xmlTextReader.
 *
 * Returns 0 in case of success and -1 in case of error
 */
int
xmlReaderNewWalker(xmlTextReaderPtr reader, xmlDocPtr doc)
{
    if (doc == NULL)
        return (-1);
    if (reader == NULL)
        return (-1);

    if (reader->input != NULL) {
        xmlFreeParserInputBuffer(reader->input);
    }
    if (reader->ctxt != NULL) {
	xmlCtxtReset(reader->ctxt);
    }

    reader->entNr = 0;
    reader->input = NULL;
    reader->mode = XML_TEXTREADER_MODE_INITIAL;
    reader->node = NULL;
    reader->curnode = NULL;
    reader->base = 0;
    reader->cur = 0;
    reader->allocs = XML_TEXTREADER_CTXT;
    reader->doc = doc;
    reader->state = XML_TEXTREADER_START;
    if (reader->dict == NULL) {
        if ((reader->ctxt != NULL) && (reader->ctxt->dict != NULL))
	    reader->dict = reader->ctxt->dict;
	else
	    reader->dict = xmlDictCreate();
    }
    return(0);
}

/**
 * xmlReaderNewDoc:
 * @reader:  an XML reader
 * @cur:  a pointer to a zero terminated string
 * @URL:  the base URL to use for the document
 * @encoding:  the document encoding, or NULL
 * @options:  a combination of xmlParserOption
 *
 * Setup an xmltextReader to parse an XML in-memory document.
 * The parsing flags @options are a combination of xmlParserOption.
 * This reuses the existing @reader xmlTextReader.
 *
 * Returns 0 in case of success and -1 in case of error
 */
int
xmlReaderNewDoc(xmlTextReaderPtr reader, const xmlChar * cur,
                const char *URL, const char *encoding, int options)
{

    int len;

    if (cur == NULL)
        return (-1);
    if (reader == NULL)
        return (-1);

    len = xmlStrlen(cur);
    return (xmlReaderNewMemory(reader, (const char *)cur, len,
                               URL, encoding, options));
}

/**
 * xmlReaderNewFile:
 * @reader:  an XML reader
 * @filename:  a file or URL
 * @encoding:  the document encoding, or NULL
 * @options:  a combination of xmlParserOption
 *
 * parse an XML file from the filesystem or the network.
 * The parsing flags @options are a combination of xmlParserOption.
 * This reuses the existing @reader xmlTextReader.
 *
 * Returns 0 in case of success and -1 in case of error
 */
int
xmlReaderNewFile(xmlTextReaderPtr reader, const char *filename,
                 const char *encoding, int options)
{
    xmlParserInputBufferPtr input;

    if (filename == NULL)
        return (-1);
    if (reader == NULL)
        return (-1);

    input =
        xmlParserInputBufferCreateFilename(filename,
                                           XML_CHAR_ENCODING_NONE);
    if (input == NULL)
        return (-1);
    return (xmlTextReaderSetup(reader, input, filename, encoding, options));
}

/**
 * xmlReaderNewMemory:
 * @reader:  an XML reader
 * @buffer:  a pointer to a char array
 * @size:  the size of the array
 * @URL:  the base URL to use for the document
 * @encoding:  the document encoding, or NULL
 * @options:  a combination of xmlParserOption
 *
 * Setup an xmltextReader to parse an XML in-memory document.
 * The parsing flags @options are a combination of xmlParserOption.
 * This reuses the existing @reader xmlTextReader.
 *
 * Returns 0 in case of success and -1 in case of error
 */
int
xmlReaderNewMemory(xmlTextReaderPtr reader, const char *buffer, int size,
                   const char *URL, const char *encoding, int options)
{
    xmlParserInputBufferPtr input;

    if (reader == NULL)
        return (-1);
    if (buffer == NULL)
        return (-1);

    input = xmlParserInputBufferCreateMem(buffer, size,
                                      XML_CHAR_ENCODING_NONE);
    if (input == NULL) {
        return (-1);
    }
    return (xmlTextReaderSetup(reader, input, URL, encoding, options));
}

/**
 * xmlReaderNewFd:
 * @reader:  an XML reader
 * @fd:  an open file descriptor
 * @URL:  the base URL to use for the document
 * @encoding:  the document encoding, or NULL
 * @options:  a combination of xmlParserOption
 *
 * Setup an xmltextReader to parse an XML from a file descriptor.
 * NOTE that the file descriptor will not be closed when the
 *      reader is closed or reset.
 * The parsing flags @options are a combination of xmlParserOption.
 * This reuses the existing @reader xmlTextReader.
 *
 * Returns 0 in case of success and -1 in case of error
 */
int
xmlReaderNewFd(xmlTextReaderPtr reader, int fd,
               const char *URL, const char *encoding, int options)
{
    xmlParserInputBufferPtr input;

    if (fd < 0)
        return (-1);
    if (reader == NULL)
        return (-1);

    input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
    if (input == NULL)
        return (-1);
    input->closecallback = NULL;
    return (xmlTextReaderSetup(reader, input, URL, encoding, options));
}

/**
 * xmlReaderNewIO:
 * @reader:  an XML reader
 * @ioread:  an I/O read function
 * @ioclose:  an I/O close function
 * @ioctx:  an I/O handler
 * @URL:  the base URL to use for the document
 * @encoding:  the document encoding, or NULL
 * @options:  a combination of xmlParserOption
 *
 * Setup an xmltextReader to parse an XML document from I/O functions
 * and source.
 * The parsing flags @options are a combination of xmlParserOption.
 * This reuses the existing @reader xmlTextReader.
 *
 * Returns 0 in case of success and -1 in case of error
 */
int
xmlReaderNewIO(xmlTextReaderPtr reader, xmlInputReadCallback ioread,
               xmlInputCloseCallback ioclose, void *ioctx,
               const char *URL, const char *encoding, int options)
{
    xmlParserInputBufferPtr input;

    if (ioread == NULL)
        return (-1);
    if (reader == NULL)
        return (-1);

    input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
                                         XML_CHAR_ENCODING_NONE);
    if (input == NULL) {
        if (ioclose != NULL)
            ioclose(ioctx);
        return (-1);
    }
    return (xmlTextReaderSetup(reader, input, URL, encoding, options));
}

/************************************************************************
 *									*
 *			Utilities					*
 *									*
 ************************************************************************/
#ifdef NOT_USED_YET

/**
 * xmlBase64Decode:
 * @in:  the input buffer
 * @inlen:  the size of the input (in), the size read from it (out)
 * @to:  the output buffer
 * @tolen:  the size of the output (in), the size written to (out)
 *
 * Base64 decoder, reads from @in and save in @to
 * TODO: tell jody when this is actually exported
 *
 * Returns 0 if all the input was consumer, 1 if the Base64 end was reached,
 *         2 if there wasn't enough space on the output or -1 in case of error.
 */
static int
xmlBase64Decode(const unsigned char *in, unsigned long *inlen,
                unsigned char *to, unsigned long *tolen)
{
    unsigned long incur;        /* current index in in[] */

    unsigned long inblk;        /* last block index in in[] */

    unsigned long outcur;       /* current index in out[] */

    unsigned long inmax;        /* size of in[] */

    unsigned long outmax;       /* size of out[] */

    unsigned char cur;          /* the current value read from in[] */

    unsigned char intmp[4], outtmp[4];  /* temporary buffers for the convert */

    int nbintmp;                /* number of byte in intmp[] */

    int is_ignore;              /* cur should be ignored */

    int is_end = 0;             /* the end of the base64 was found */

    int retval = 1;

    int i;

    if ((in == NULL) || (inlen == NULL) || (to == NULL) || (tolen == NULL))
        return (-1);

    incur = 0;
    inblk = 0;
    outcur = 0;
    inmax = *inlen;
    outmax = *tolen;
    nbintmp = 0;

    while (1) {
        if (incur >= inmax)
            break;
        cur = in[incur++];
        is_ignore = 0;
        if ((cur >= 'A') && (cur <= 'Z'))
            cur = cur - 'A';
        else if ((cur >= 'a') && (cur <= 'z'))
            cur = cur - 'a' + 26;
        else if ((cur >= '0') && (cur <= '9'))
            cur = cur - '0' + 52;
        else if (cur == '+')
            cur = 62;
        else if (cur == '/')
            cur = 63;
        else if (cur == '.')
            cur = 0;
        else if (cur == '=')    /*no op , end of the base64 stream */
            is_end = 1;
        else {
            is_ignore = 1;
            if (nbintmp == 0)
                inblk = incur;
        }

        if (!is_ignore) {
            int nbouttmp = 3;

            int is_break = 0;

            if (is_end) {
                if (nbintmp == 0)
                    break;
                if ((nbintmp == 1) || (nbintmp == 2))
                    nbouttmp = 1;
                else
                    nbouttmp = 2;
                nbintmp = 3;
                is_break = 1;
            }
            intmp[nbintmp++] = cur;
            /*
             * if intmp is full, push the 4byte sequence as a 3 byte
             * sequence out
             */
            if (nbintmp == 4) {
                nbintmp = 0;
                outtmp[0] = (intmp[0] << 2) | ((intmp[1] & 0x30) >> 4);
                outtmp[1] =
                    ((intmp[1] & 0x0F) << 4) | ((intmp[2] & 0x3C) >> 2);
                outtmp[2] = ((intmp[2] & 0x03) << 6) | (intmp[3] & 0x3F);
                if (outcur + 3 >= outmax) {
                    retval = 2;
                    break;
                }

                for (i = 0; i < nbouttmp; i++)
                    to[outcur++] = outtmp[i];
                inblk = incur;
            }

            if (is_break) {
                retval = 0;
                break;
            }
        }
    }

    *tolen = outcur;
    *inlen = inblk;
    return (retval);
}

/*
 * Test routine for the xmlBase64Decode function
 */
#if 0
int
main(int argc, char **argv)
{
    char *input = "  VW4 gcGV0        \n      aXQgdGVzdCAuCg== ";

    char output[100];

    char output2[100];

    char output3[100];

    unsigned long inlen = strlen(input);

    unsigned long outlen = 100;

    int ret;

    unsigned long cons, tmp, tmp2, prod;

    /*
     * Direct
     */
    ret = xmlBase64Decode(input, &inlen, output, &outlen);

    output[outlen] = 0;
    printf("ret: %d, inlen: %ld , outlen: %ld, output: '%s'\n", ret, inlen,
           outlen, output)indent: Standard input:179: Error:Unmatched #endif
;

    /*
     * output chunking
     */
    cons = 0;
    prod = 0;
    while (cons < inlen) {
        tmp = 5;
        tmp2 = inlen - cons;

        printf("%ld %ld\n", cons, prod);
        ret = xmlBase64Decode(&input[cons], &tmp2, &output2[prod], &tmp);
        cons += tmp2;
        prod += tmp;
        printf("%ld %ld\n", cons, prod);
    }
    output2[outlen] = 0;
    printf("ret: %d, cons: %ld , prod: %ld, output: '%s'\n", ret, cons,
           prod, output2);

    /*
     * input chunking
     */
    cons = 0;
    prod = 0;
    while (cons < inlen) {
        tmp = 100 - prod;
        tmp2 = inlen - cons;
        if (tmp2 > 5)
            tmp2 = 5;

        printf("%ld %ld\n", cons, prod);
        ret = xmlBase64Decode(&input[cons], &tmp2, &output3[prod], &tmp);
        cons += tmp2;
        prod += tmp;
        printf("%ld %ld\n", cons, prod);
    }
    output3[outlen] = 0;
    printf("ret: %d, cons: %ld , prod: %ld, output: '%s'\n", ret, cons,
           prod, output3);
    return (0);

}
#endif
#endif /* NOT_USED_YET */

#endif /* LIBXML_READER_ENABLED */
