ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

xmlreader.c
Go to the documentation of this file.
00001 /*
00002  * xmlreader.c: implements the xmlTextReader streaming node API
00003  *
00004  * NOTE:
00005  *   XmlTextReader.Normalization Property won't be supported, since
00006  *     it makes the parser non compliant to the XML recommendation
00007  *
00008  * See Copyright for the status of this software.
00009  *
00010  * daniel@veillard.com
00011  */
00012 
00013 /*
00014  * TODOs:
00015  *   - XML Schemas validation
00016  */
00017 #define IN_LIBXML
00018 #include "libxml.h"
00019 
00020 #ifdef LIBXML_READER_ENABLED
00021 #include <string.h> /* for memset() only ! */
00022 #include <stdarg.h>
00023 
00024 #ifdef HAVE_CTYPE_H
00025 #include <ctype.h>
00026 #endif
00027 #ifdef HAVE_STDLIB_H
00028 #include <stdlib.h>
00029 #endif
00030 
00031 #include <libxml/xmlmemory.h>
00032 #include <libxml/xmlIO.h>
00033 #include <libxml/xmlreader.h>
00034 #include <libxml/parserInternals.h>
00035 #ifdef LIBXML_SCHEMAS_ENABLED
00036 #include <libxml/relaxng.h>
00037 #include <libxml/xmlschemas.h>
00038 #endif
00039 #include <libxml/uri.h>
00040 #ifdef LIBXML_XINCLUDE_ENABLED
00041 #include <libxml/xinclude.h>
00042 #endif
00043 #ifdef LIBXML_PATTERN_ENABLED
00044 #include <libxml/pattern.h>
00045 #endif
00046 
00047 #define MAX_ERR_MSG_SIZE 64000
00048 
00049 /*
00050  * The following VA_COPY was coded following an example in
00051  * the Samba project.  It may not be sufficient for some
00052  * esoteric implementations of va_list (i.e. it may need
00053  * something involving a memcpy) but (hopefully) will be
00054  * sufficient for libxml2.
00055  */
00056 #ifndef VA_COPY
00057   #ifdef HAVE_VA_COPY
00058     #define VA_COPY(dest, src) va_copy(dest, src)
00059   #else
00060     #ifdef HAVE___VA_COPY
00061       #define VA_COPY(dest,src) __va_copy(dest, src)
00062     #else
00063       #define VA_COPY(dest,src) (dest) = (src)
00064     #endif
00065   #endif
00066 #endif
00067 
00068 /* #define DEBUG_CALLBACKS */
00069 /* #define DEBUG_READER */
00070 
00076 #define TODO                                \
00077     xmlGenericError(xmlGenericErrorContext,             \
00078         "Unimplemented block at %s:%d\n",               \
00079             __FILE__, __LINE__);
00080 
00081 #ifdef DEBUG_READER
00082 #define DUMP_READER xmlTextReaderDebug(reader);
00083 #else
00084 #define DUMP_READER
00085 #endif
00086 
00087 #define CHUNK_SIZE 512
00088 /************************************************************************
00089  *                                  *
00090  *  The parser: maps the Text Reader API on top of the existing *
00091  *      parsing routines building a tree            *
00092  *                                  *
00093  ************************************************************************/
00094 
00095 #define XML_TEXTREADER_INPUT    1
00096 #define XML_TEXTREADER_CTXT 2
00097 
00098 typedef enum {
00099     XML_TEXTREADER_NONE = -1,
00100     XML_TEXTREADER_START= 0,
00101     XML_TEXTREADER_ELEMENT= 1,
00102     XML_TEXTREADER_END= 2,
00103     XML_TEXTREADER_EMPTY= 3,
00104     XML_TEXTREADER_BACKTRACK= 4,
00105     XML_TEXTREADER_DONE= 5,
00106     XML_TEXTREADER_ERROR= 6
00107 } xmlTextReaderState;
00108 
00109 typedef enum {
00110     XML_TEXTREADER_NOT_VALIDATE = 0,
00111     XML_TEXTREADER_VALIDATE_DTD = 1,
00112     XML_TEXTREADER_VALIDATE_RNG = 2,
00113     XML_TEXTREADER_VALIDATE_XSD = 4
00114 } xmlTextReaderValidate;
00115 
00116 struct _xmlTextReader {
00117     int             mode;   /* the parsing mode */
00118     xmlDocPtr           doc;    /* when walking an existing doc */
00119     xmlTextReaderValidate       validate;/* is there any validation */
00120     int             allocs; /* what structure were deallocated */
00121     xmlTextReaderState      state;
00122     xmlParserCtxtPtr        ctxt;   /* the parser context */
00123     xmlSAXHandlerPtr        sax;    /* the parser SAX callbacks */
00124     xmlParserInputBufferPtr input;  /* the input */
00125     startElementSAXFunc     startElement;/* initial SAX callbacks */
00126     endElementSAXFunc       endElement;  /* idem */
00127     startElementNsSAX2Func  startElementNs;/* idem */
00128     endElementNsSAX2Func    endElementNs;  /* idem */
00129     charactersSAXFunc       characters;
00130     cdataBlockSAXFunc       cdataBlock;
00131     unsigned int        base;   /* base of the segment in the input */
00132     unsigned int        cur;    /* current position in the input */
00133     xmlNodePtr          node;   /* current node */
00134     xmlNodePtr          curnode;/* current attribute node */
00135     int             depth;  /* depth of the current node */
00136     xmlNodePtr          faketext;/* fake xmlNs chld */
00137     int             preserve;/* preserve the resulting document */
00138     xmlBufferPtr        buffer; /* used to return const xmlChar * */
00139     xmlDictPtr          dict;   /* the context dictionnary */
00140 
00141     /* entity stack when traversing entities content */
00142     xmlNodePtr         ent;          /* Current Entity Ref Node */
00143     int                entNr;        /* Depth of the entities stack */
00144     int                entMax;       /* Max depth of the entities stack */
00145     xmlNodePtr        *entTab;       /* array of entities */
00146 
00147     /* error handling */
00148     xmlTextReaderErrorFunc errorFunc;    /* callback function */
00149     void                  *errorFuncArg; /* callback function user argument */
00150 
00151 #ifdef LIBXML_SCHEMAS_ENABLED
00152     /* Handling of RelaxNG validation */
00153     xmlRelaxNGPtr          rngSchemas;  /* The Relax NG schemas */
00154     xmlRelaxNGValidCtxtPtr rngValidCtxt;/* The Relax NG validation context */
00155     int                    rngValidErrors;/* The number of errors detected */
00156     xmlNodePtr             rngFullNode; /* the node if RNG not progressive */
00157     /* Handling of Schemas validation */
00158     xmlSchemaPtr          xsdSchemas;   /* The Schemas schemas */
00159     xmlSchemaValidCtxtPtr xsdValidCtxt;/* The Schemas validation context */
00160     int                   xsdPreserveCtxt; /* 1 if the context was provided by the user */
00161     int                   xsdValidErrors;/* The number of errors detected */
00162     xmlSchemaSAXPlugPtr   xsdPlug;  /* the schemas plug in SAX pipeline */
00163 #endif
00164 #ifdef LIBXML_XINCLUDE_ENABLED
00165     /* Handling of XInclude processing */
00166     int                xinclude;    /* is xinclude asked for */
00167     const xmlChar *    xinclude_name;   /* the xinclude name from dict */
00168     xmlXIncludeCtxtPtr xincctxt;    /* the xinclude context */
00169     int                in_xinclude; /* counts for xinclude */
00170 #endif
00171 #ifdef LIBXML_PATTERN_ENABLED
00172     int                patternNr;       /* number of preserve patterns */
00173     int                patternMax;      /* max preserve patterns */
00174     xmlPatternPtr     *patternTab;      /* array of preserve patterns */
00175 #endif
00176     int                preserves;   /* level of preserves */
00177     int                parserFlags; /* the set of options set */
00178     /* Structured error handling */
00179     xmlStructuredErrorFunc sErrorFunc;  /* callback function */
00180 };
00181 
00182 #define NODE_IS_EMPTY       0x1
00183 #define NODE_IS_PRESERVED   0x2
00184 #define NODE_IS_SPRESERVED  0x4
00185 
00191 #define CONSTSTR(str) xmlDictLookup(reader->dict, (str), -1)
00192 #define CONSTQSTR(p, str) xmlDictQLookup(reader->dict, (p), (str))
00193 
00194 static int xmlTextReaderReadTree(xmlTextReaderPtr reader);
00195 static int xmlTextReaderNextTree(xmlTextReaderPtr reader);
00196 
00197 /************************************************************************
00198  *                                  *
00199  *  Our own version of the freeing routines as we recycle nodes *
00200  *                                  *
00201  ************************************************************************/
00209 #define DICT_FREE(str)                      \
00210     if ((str) && ((!dict) ||                \
00211         (xmlDictOwns(dict, (const xmlChar *)(str)) == 0)))  \
00212         xmlFree((char *)(str));
00213 
00214 static void xmlTextReaderFreeNode(xmlTextReaderPtr reader, xmlNodePtr cur);
00215 static void xmlTextReaderFreeNodeList(xmlTextReaderPtr reader, xmlNodePtr cur);
00216 
00223 static void
00224 xmlFreeID(xmlIDPtr id) {
00225     xmlDictPtr dict = NULL;
00226 
00227     if (id == NULL) return;
00228 
00229     if (id->doc != NULL)
00230         dict = id->doc->dict;
00231 
00232     if (id->value != NULL)
00233     DICT_FREE(id->value)
00234     xmlFree(id);
00235 }
00236 
00246 static int
00247 xmlTextReaderRemoveID(xmlDocPtr doc, xmlAttrPtr attr) {
00248     xmlIDTablePtr table;
00249     xmlIDPtr id;
00250     xmlChar *ID;
00251 
00252     if (doc == NULL) return(-1);
00253     if (attr == NULL) return(-1);
00254     table = (xmlIDTablePtr) doc->ids;
00255     if (table == NULL)
00256         return(-1);
00257 
00258     ID = xmlNodeListGetString(doc, attr->children, 1);
00259     if (ID == NULL)
00260     return(-1);
00261     id = xmlHashLookup(table, ID);
00262     xmlFree(ID);
00263     if (id == NULL || id->attr != attr) {
00264     return(-1);
00265     }
00266     id->name = attr->name;
00267     id->attr = NULL;
00268     return(0);
00269 }
00270 
00278 static void
00279 xmlTextReaderFreeProp(xmlTextReaderPtr reader, xmlAttrPtr cur) {
00280     xmlDictPtr dict;
00281 
00282     dict = reader->ctxt->dict;
00283     if (cur == NULL) return;
00284 
00285     if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
00286     xmlDeregisterNodeDefaultValue((xmlNodePtr) cur);
00287 
00288     /* Check for ID removal -> leading to invalid references ! */
00289     if ((cur->parent != NULL) && (cur->parent->doc != NULL) &&
00290     ((cur->parent->doc->intSubset != NULL) ||
00291      (cur->parent->doc->extSubset != NULL))) {
00292         if (xmlIsID(cur->parent->doc, cur->parent, cur))
00293         xmlTextReaderRemoveID(cur->parent->doc, cur);
00294     }
00295     if (cur->children != NULL)
00296         xmlTextReaderFreeNodeList(reader, cur->children);
00297 
00298     DICT_FREE(cur->name);
00299     if ((reader != NULL) && (reader->ctxt != NULL) &&
00300         (reader->ctxt->freeAttrsNr < 100)) {
00301         cur->next = reader->ctxt->freeAttrs;
00302     reader->ctxt->freeAttrs = cur;
00303     reader->ctxt->freeAttrsNr++;
00304     } else {
00305     xmlFree(cur);
00306     }
00307 }
00308 
00316 static void
00317 xmlTextReaderFreePropList(xmlTextReaderPtr reader, xmlAttrPtr cur) {
00318     xmlAttrPtr next;
00319     if (cur == NULL) return;
00320     while (cur != NULL) {
00321         next = cur->next;
00322         xmlTextReaderFreeProp(reader, cur);
00323     cur = next;
00324     }
00325 }
00326 
00335 static void
00336 xmlTextReaderFreeNodeList(xmlTextReaderPtr reader, xmlNodePtr cur) {
00337     xmlNodePtr next;
00338     xmlDictPtr dict;
00339 
00340     dict = reader->ctxt->dict;
00341     if (cur == NULL) return;
00342     if (cur->type == XML_NAMESPACE_DECL) {
00343     xmlFreeNsList((xmlNsPtr) cur);
00344     return;
00345     }
00346     if ((cur->type == XML_DOCUMENT_NODE) ||
00347     (cur->type == XML_HTML_DOCUMENT_NODE)) {
00348     xmlFreeDoc((xmlDocPtr) cur);
00349     return;
00350     }
00351     while (cur != NULL) {
00352         next = cur->next;
00353     /* unroll to speed up freeing the document */
00354     if (cur->type != XML_DTD_NODE) {
00355 
00356         if ((cur->children != NULL) &&
00357         (cur->type != XML_ENTITY_REF_NODE)) {
00358         if (cur->children->parent == cur)
00359             xmlTextReaderFreeNodeList(reader, cur->children);
00360         cur->children = NULL;
00361         }
00362 
00363         if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
00364         xmlDeregisterNodeDefaultValue(cur);
00365 
00366         if (((cur->type == XML_ELEMENT_NODE) ||
00367          (cur->type == XML_XINCLUDE_START) ||
00368          (cur->type == XML_XINCLUDE_END)) &&
00369         (cur->properties != NULL))
00370         xmlTextReaderFreePropList(reader, cur->properties);
00371         if ((cur->content != (xmlChar *) &(cur->properties)) &&
00372             (cur->type != XML_ELEMENT_NODE) &&
00373         (cur->type != XML_XINCLUDE_START) &&
00374         (cur->type != XML_XINCLUDE_END) &&
00375         (cur->type != XML_ENTITY_REF_NODE)) {
00376         DICT_FREE(cur->content);
00377         }
00378         if (((cur->type == XML_ELEMENT_NODE) ||
00379              (cur->type == XML_XINCLUDE_START) ||
00380          (cur->type == XML_XINCLUDE_END)) &&
00381         (cur->nsDef != NULL))
00382         xmlFreeNsList(cur->nsDef);
00383 
00384         /*
00385          * we don't free element names here they are interned now
00386          */
00387         if ((cur->type != XML_TEXT_NODE) &&
00388         (cur->type != XML_COMMENT_NODE))
00389         DICT_FREE(cur->name);
00390         if (((cur->type == XML_ELEMENT_NODE) ||
00391          (cur->type == XML_TEXT_NODE)) &&
00392             (reader != NULL) && (reader->ctxt != NULL) &&
00393         (reader->ctxt->freeElemsNr < 100)) {
00394             cur->next = reader->ctxt->freeElems;
00395         reader->ctxt->freeElems = cur;
00396         reader->ctxt->freeElemsNr++;
00397         } else {
00398         xmlFree(cur);
00399         }
00400     }
00401     cur = next;
00402     }
00403 }
00404 
00413 static void
00414 xmlTextReaderFreeNode(xmlTextReaderPtr reader, xmlNodePtr cur) {
00415     xmlDictPtr dict;
00416 
00417     dict = reader->ctxt->dict;
00418     if (cur->type == XML_DTD_NODE) {
00419     xmlFreeDtd((xmlDtdPtr) cur);
00420     return;
00421     }
00422     if (cur->type == XML_NAMESPACE_DECL) {
00423     xmlFreeNs((xmlNsPtr) cur);
00424         return;
00425     }
00426     if (cur->type == XML_ATTRIBUTE_NODE) {
00427     xmlTextReaderFreeProp(reader, (xmlAttrPtr) cur);
00428     return;
00429     }
00430 
00431     if ((cur->children != NULL) &&
00432     (cur->type != XML_ENTITY_REF_NODE)) {
00433     if (cur->children->parent == cur)
00434         xmlTextReaderFreeNodeList(reader, cur->children);
00435     cur->children = NULL;
00436     }
00437 
00438     if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
00439     xmlDeregisterNodeDefaultValue(cur);
00440 
00441     if (((cur->type == XML_ELEMENT_NODE) ||
00442      (cur->type == XML_XINCLUDE_START) ||
00443      (cur->type == XML_XINCLUDE_END)) &&
00444     (cur->properties != NULL))
00445     xmlTextReaderFreePropList(reader, cur->properties);
00446     if ((cur->content != (xmlChar *) &(cur->properties)) &&
00447         (cur->type != XML_ELEMENT_NODE) &&
00448     (cur->type != XML_XINCLUDE_START) &&
00449     (cur->type != XML_XINCLUDE_END) &&
00450     (cur->type != XML_ENTITY_REF_NODE)) {
00451     DICT_FREE(cur->content);
00452     }
00453     if (((cur->type == XML_ELEMENT_NODE) ||
00454      (cur->type == XML_XINCLUDE_START) ||
00455      (cur->type == XML_XINCLUDE_END)) &&
00456     (cur->nsDef != NULL))
00457     xmlFreeNsList(cur->nsDef);
00458 
00459     /*
00460      * we don't free names here they are interned now
00461      */
00462     if ((cur->type != XML_TEXT_NODE) &&
00463         (cur->type != XML_COMMENT_NODE))
00464     DICT_FREE(cur->name);
00465 
00466     if (((cur->type == XML_ELEMENT_NODE) ||
00467      (cur->type == XML_TEXT_NODE)) &&
00468     (reader != NULL) && (reader->ctxt != NULL) &&
00469     (reader->ctxt->freeElemsNr < 100)) {
00470     cur->next = reader->ctxt->freeElems;
00471     reader->ctxt->freeElems = cur;
00472     reader->ctxt->freeElemsNr++;
00473     } else {
00474     xmlFree(cur);
00475     }
00476 }
00477 
00484 static void
00485 xmlTextReaderFreeIDTable(xmlIDTablePtr table) {
00486     xmlHashFree(table, (xmlHashDeallocator) xmlFreeID);
00487 }
00488 
00496 static void
00497 xmlTextReaderFreeDoc(xmlTextReaderPtr reader, xmlDocPtr cur) {
00498     xmlDtdPtr extSubset, intSubset;
00499 
00500     if (cur == NULL) return;
00501 
00502     if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
00503     xmlDeregisterNodeDefaultValue((xmlNodePtr) cur);
00504 
00505     /*
00506      * Do this before freeing the children list to avoid ID lookups
00507      */
00508     if (cur->ids != NULL) xmlTextReaderFreeIDTable((xmlIDTablePtr) cur->ids);
00509     cur->ids = NULL;
00510     if (cur->refs != NULL) xmlFreeRefTable((xmlRefTablePtr) cur->refs);
00511     cur->refs = NULL;
00512     extSubset = cur->extSubset;
00513     intSubset = cur->intSubset;
00514     if (intSubset == extSubset)
00515     extSubset = NULL;
00516     if (extSubset != NULL) {
00517     xmlUnlinkNode((xmlNodePtr) cur->extSubset);
00518     cur->extSubset = NULL;
00519     xmlFreeDtd(extSubset);
00520     }
00521     if (intSubset != NULL) {
00522     xmlUnlinkNode((xmlNodePtr) cur->intSubset);
00523     cur->intSubset = NULL;
00524     xmlFreeDtd(intSubset);
00525     }
00526 
00527     if (cur->children != NULL) xmlTextReaderFreeNodeList(reader, cur->children);
00528 
00529     if (cur->version != NULL) xmlFree((char *) cur->version);
00530     if (cur->name != NULL) xmlFree((char *) cur->name);
00531     if (cur->encoding != NULL) xmlFree((char *) cur->encoding);
00532     if (cur->oldNs != NULL) xmlFreeNsList(cur->oldNs);
00533     if (cur->URL != NULL) xmlFree((char *) cur->URL);
00534     if (cur->dict != NULL) xmlDictFree(cur->dict);
00535 
00536     xmlFree(cur);
00537 }
00538 
00539 /************************************************************************
00540  *                                  *
00541  *          The reader core parser              *
00542  *                                  *
00543  ************************************************************************/
00544 #ifdef DEBUG_READER
00545 static void
00546 xmlTextReaderDebug(xmlTextReaderPtr reader) {
00547     if ((reader == NULL) || (reader->ctxt == NULL)) {
00548     fprintf(stderr, "xmlTextReader NULL\n");
00549     return;
00550     }
00551     fprintf(stderr, "xmlTextReader: state %d depth %d ",
00552         reader->state, reader->depth);
00553     if (reader->node == NULL) {
00554     fprintf(stderr, "node = NULL\n");
00555     } else {
00556     fprintf(stderr, "node %s\n", reader->node->name);
00557     }
00558     fprintf(stderr, "  input: base %d, cur %d, depth %d: ",
00559         reader->base, reader->cur, reader->ctxt->nodeNr);
00560     if (reader->input->buffer == NULL) {
00561     fprintf(stderr, "buffer is NULL\n");
00562     } else {
00563 #ifdef LIBXML_DEBUG_ENABLED
00564     xmlDebugDumpString(stderr,
00565         &reader->input->buffer->content[reader->cur]);
00566 #endif
00567     fprintf(stderr, "\n");
00568     }
00569 }
00570 #endif
00571 
00581 static int
00582 xmlTextReaderEntPush(xmlTextReaderPtr reader, xmlNodePtr value)
00583 {
00584     if (reader->entMax <= 0) {
00585     reader->entMax = 10;
00586     reader->entTab = (xmlNodePtr *) xmlMalloc(reader->entMax *
00587                                           sizeof(reader->entTab[0]));
00588         if (reader->entTab == NULL) {
00589             xmlGenericError(xmlGenericErrorContext, "xmlMalloc failed !\n");
00590             return (0);
00591         }
00592     }
00593     if (reader->entNr >= reader->entMax) {
00594         reader->entMax *= 2;
00595         reader->entTab =
00596             (xmlNodePtr *) xmlRealloc(reader->entTab,
00597                                       reader->entMax *
00598                                       sizeof(reader->entTab[0]));
00599         if (reader->entTab == NULL) {
00600             xmlGenericError(xmlGenericErrorContext, "xmlRealloc failed !\n");
00601             return (0);
00602         }
00603     }
00604     reader->entTab[reader->entNr] = value;
00605     reader->ent = value;
00606     return (reader->entNr++);
00607 }
00608 
00617 static xmlNodePtr
00618 xmlTextReaderEntPop(xmlTextReaderPtr reader)
00619 {
00620     xmlNodePtr ret;
00621 
00622     if (reader->entNr <= 0)
00623         return (NULL);
00624     reader->entNr--;
00625     if (reader->entNr > 0)
00626         reader->ent = reader->entTab[reader->entNr - 1];
00627     else
00628         reader->ent = NULL;
00629     ret = reader->entTab[reader->entNr];
00630     reader->entTab[reader->entNr] = NULL;
00631     return (ret);
00632 }
00633 
00642 static void
00643 xmlTextReaderStartElement(void *ctx, const xmlChar *fullname,
00644                       const xmlChar **atts) {
00645     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
00646     xmlTextReaderPtr reader = ctxt->_private;
00647 
00648 #ifdef DEBUG_CALLBACKS
00649     printf("xmlTextReaderStartElement(%s)\n", fullname);
00650 #endif
00651     if ((reader != NULL) && (reader->startElement != NULL)) {
00652     reader->startElement(ctx, fullname, atts);
00653     if ((ctxt->node != NULL) && (ctxt->input != NULL) &&
00654         (ctxt->input->cur != NULL) && (ctxt->input->cur[0] == '/') &&
00655         (ctxt->input->cur[1] == '>'))
00656         ctxt->node->extra = NODE_IS_EMPTY;
00657     }
00658     if (reader != NULL)
00659     reader->state = XML_TEXTREADER_ELEMENT;
00660 }
00661 
00669 static void
00670 xmlTextReaderEndElement(void *ctx, const xmlChar *fullname) {
00671     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
00672     xmlTextReaderPtr reader = ctxt->_private;
00673 
00674 #ifdef DEBUG_CALLBACKS
00675     printf("xmlTextReaderEndElement(%s)\n", fullname);
00676 #endif
00677     if ((reader != NULL) && (reader->endElement != NULL)) {
00678     reader->endElement(ctx, fullname);
00679     }
00680 }
00681 
00697 static void
00698 xmlTextReaderStartElementNs(void *ctx,
00699                       const xmlChar *localname,
00700               const xmlChar *prefix,
00701               const xmlChar *URI,
00702               int nb_namespaces,
00703               const xmlChar **namespaces,
00704               int nb_attributes,
00705               int nb_defaulted,
00706               const xmlChar **attributes)
00707 {
00708     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
00709     xmlTextReaderPtr reader = ctxt->_private;
00710 
00711 #ifdef DEBUG_CALLBACKS
00712     printf("xmlTextReaderStartElementNs(%s)\n", localname);
00713 #endif
00714     if ((reader != NULL) && (reader->startElementNs != NULL)) {
00715     reader->startElementNs(ctx, localname, prefix, URI, nb_namespaces,
00716                            namespaces, nb_attributes, nb_defaulted,
00717                    attributes);
00718     if ((ctxt->node != NULL) && (ctxt->input != NULL) &&
00719         (ctxt->input->cur != NULL) && (ctxt->input->cur[0] == '/') &&
00720         (ctxt->input->cur[1] == '>'))
00721         ctxt->node->extra = NODE_IS_EMPTY;
00722     }
00723     if (reader != NULL)
00724     reader->state = XML_TEXTREADER_ELEMENT;
00725 }
00726 
00736 static void
00737 xmlTextReaderEndElementNs(void *ctx,
00738                           const xmlChar * localname,
00739                           const xmlChar * prefix,
00740                   const xmlChar * URI)
00741 {
00742     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
00743     xmlTextReaderPtr reader = ctxt->_private;
00744 
00745 #ifdef DEBUG_CALLBACKS
00746     printf("xmlTextReaderEndElementNs(%s)\n", localname);
00747 #endif
00748     if ((reader != NULL) && (reader->endElementNs != NULL)) {
00749     reader->endElementNs(ctx, localname, prefix, URI);
00750     }
00751 }
00752 
00753 
00762 static void
00763 xmlTextReaderCharacters(void *ctx, const xmlChar *ch, int len)
00764 {
00765     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
00766     xmlTextReaderPtr reader = ctxt->_private;
00767 
00768 #ifdef DEBUG_CALLBACKS
00769     printf("xmlTextReaderCharacters()\n");
00770 #endif
00771     if ((reader != NULL) && (reader->characters != NULL)) {
00772     reader->characters(ctx, ch, len);
00773     }
00774 }
00775 
00784 static void
00785 xmlTextReaderCDataBlock(void *ctx, const xmlChar *ch, int len)
00786 {
00787     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
00788     xmlTextReaderPtr reader = ctxt->_private;
00789 
00790 #ifdef DEBUG_CALLBACKS
00791     printf("xmlTextReaderCDataBlock()\n");
00792 #endif
00793     if ((reader != NULL) && (reader->cdataBlock != NULL)) {
00794     reader->cdataBlock(ctx, ch, len);
00795     }
00796 }
00797 
00807 static int
00808 xmlTextReaderPushData(xmlTextReaderPtr reader) {
00809     xmlBufferPtr inbuf;
00810     int val, s;
00811     xmlTextReaderState oldstate;
00812 
00813     if ((reader->input == NULL) || (reader->input->buffer == NULL))
00814     return(-1);
00815 
00816     oldstate = reader->state;
00817     reader->state = XML_TEXTREADER_NONE;
00818     inbuf = reader->input->buffer;
00819 
00820     while (reader->state == XML_TEXTREADER_NONE) {
00821     if (inbuf->use < reader->cur + CHUNK_SIZE) {
00822         /*
00823          * Refill the buffer unless we are at the end of the stream
00824          */
00825         if (reader->mode != XML_TEXTREADER_MODE_EOF) {
00826         val = xmlParserInputBufferRead(reader->input, 4096);
00827         if ((val == 0) &&
00828             (inbuf->alloc == XML_BUFFER_ALLOC_IMMUTABLE)) {
00829             if (inbuf->use == reader->cur) {
00830             reader->mode = XML_TEXTREADER_MODE_EOF;
00831             reader->state = oldstate;
00832             }
00833         } else if (val < 0) {
00834             reader->mode = XML_TEXTREADER_MODE_EOF;
00835             reader->state = oldstate;
00836             if ((oldstate != XML_TEXTREADER_START) ||
00837             (reader->ctxt->myDoc != NULL))
00838             return(val);
00839         } else if (val == 0) {
00840             /* mark the end of the stream and process the remains */
00841             reader->mode = XML_TEXTREADER_MODE_EOF;
00842             break;
00843         }
00844 
00845         } else
00846         break;
00847     }
00848     /*
00849      * parse by block of CHUNK_SIZE bytes, various tests show that
00850      * it's the best tradeoff at least on a 1.2GH Duron
00851      */
00852     if (inbuf->use >= reader->cur + CHUNK_SIZE) {
00853         val = xmlParseChunk(reader->ctxt,
00854                   (const char *) &inbuf->content[reader->cur],
00855               CHUNK_SIZE, 0);
00856         reader->cur += CHUNK_SIZE;
00857         if ((val != 0) || (reader->ctxt->wellFormed == 0))
00858         return(-1);
00859     } else {
00860         s = inbuf->use - reader->cur;
00861         val = xmlParseChunk(reader->ctxt,
00862                   (const char *) &inbuf->content[reader->cur],
00863               s, 0);
00864         reader->cur += s;
00865         if ((val != 0) || (reader->ctxt->wellFormed == 0))
00866         return(-1);
00867         break;
00868     }
00869     }
00870 
00871     /*
00872      * Discard the consumed input when needed and possible
00873      */
00874     if (reader->mode == XML_TEXTREADER_MODE_INTERACTIVE) {
00875         if (inbuf->alloc != XML_BUFFER_ALLOC_IMMUTABLE) {
00876         if ((reader->cur >= 4096) &&
00877         (inbuf->use - reader->cur <= CHUNK_SIZE)) {
00878         val = xmlBufferShrink(inbuf, reader->cur);
00879         if (val >= 0) {
00880             reader->cur -= val;
00881         }
00882         }
00883     }
00884     }
00885 
00886     /*
00887      * At the end of the stream signal that the work is done to the Push
00888      * parser.
00889      */
00890     else if (reader->mode == XML_TEXTREADER_MODE_EOF) {
00891     if (reader->state != XML_TEXTREADER_DONE) {
00892         s = inbuf->use - reader->cur;
00893         val = xmlParseChunk(reader->ctxt,
00894             (const char *) &inbuf->content[reader->cur],
00895             s, 1);
00896         reader->cur = inbuf->use;
00897         reader->state  = XML_TEXTREADER_DONE;
00898         if ((val != 0) || (reader->ctxt->wellFormed == 0))
00899             return(-1);
00900     }
00901     }
00902     reader->state = oldstate;
00903     return(0);
00904 }
00905 
00906 #ifdef LIBXML_REGEXP_ENABLED
00907 
00913 static void
00914 xmlTextReaderValidatePush(xmlTextReaderPtr reader ATTRIBUTE_UNUSED) {
00915     xmlNodePtr node = reader->node;
00916 
00917 #ifdef LIBXML_VALID_ENABLED
00918     if ((reader->validate == XML_TEXTREADER_VALIDATE_DTD) &&
00919         (reader->ctxt != NULL) && (reader->ctxt->validate == 1)) {
00920     if ((node->ns == NULL) || (node->ns->prefix == NULL)) {
00921         reader->ctxt->valid &= xmlValidatePushElement(&reader->ctxt->vctxt,
00922                     reader->ctxt->myDoc, node, node->name);
00923     } else {
00924         /* TODO use the BuildQName interface */
00925         xmlChar *qname;
00926 
00927         qname = xmlStrdup(node->ns->prefix);
00928         qname = xmlStrcat(qname, BAD_CAST ":");
00929         qname = xmlStrcat(qname, node->name);
00930         reader->ctxt->valid &= xmlValidatePushElement(&reader->ctxt->vctxt,
00931                     reader->ctxt->myDoc, node, qname);
00932         if (qname != NULL)
00933         xmlFree(qname);
00934     }
00935     }
00936 #endif /* LIBXML_VALID_ENABLED */
00937 #ifdef LIBXML_SCHEMAS_ENABLED
00938     if ((reader->validate == XML_TEXTREADER_VALIDATE_RNG) &&
00939                (reader->rngValidCtxt != NULL)) {
00940     int ret;
00941 
00942     if (reader->rngFullNode != NULL) return;
00943     ret = xmlRelaxNGValidatePushElement(reader->rngValidCtxt,
00944                                         reader->ctxt->myDoc,
00945                         node);
00946     if (ret == 0) {
00947         /*
00948          * this element requires a full tree
00949          */
00950         node = xmlTextReaderExpand(reader);
00951         if (node == NULL) {
00952 printf("Expand failed !\n");
00953             ret = -1;
00954         } else {
00955         ret = xmlRelaxNGValidateFullElement(reader->rngValidCtxt,
00956                             reader->ctxt->myDoc,
00957                             node);
00958         reader->rngFullNode = node;
00959         }
00960     }
00961     if (ret != 1)
00962         reader->rngValidErrors++;
00963     }
00964 #endif
00965 }
00966 
00975 static void
00976 xmlTextReaderValidateCData(xmlTextReaderPtr reader,
00977                            const xmlChar *data, int len) {
00978 #ifdef LIBXML_VALID_ENABLED
00979     if ((reader->validate == XML_TEXTREADER_VALIDATE_DTD) &&
00980         (reader->ctxt != NULL) && (reader->ctxt->validate == 1)) {
00981     reader->ctxt->valid &= xmlValidatePushCData(&reader->ctxt->vctxt,
00982                                                 data, len);
00983     }
00984 #endif /* LIBXML_VALID_ENABLED */
00985 #ifdef LIBXML_SCHEMAS_ENABLED
00986     if ((reader->validate == XML_TEXTREADER_VALIDATE_RNG) &&
00987                (reader->rngValidCtxt != NULL)) {
00988     int ret;
00989 
00990     if (reader->rngFullNode != NULL) return;
00991     ret = xmlRelaxNGValidatePushCData(reader->rngValidCtxt, data, len);
00992     if (ret != 1)
00993         reader->rngValidErrors++;
00994     }
00995 #endif
00996 }
00997 
01004 static void
01005 xmlTextReaderValidatePop(xmlTextReaderPtr reader) {
01006     xmlNodePtr node = reader->node;
01007 
01008 #ifdef LIBXML_VALID_ENABLED
01009     if ((reader->validate == XML_TEXTREADER_VALIDATE_DTD) &&
01010         (reader->ctxt != NULL) && (reader->ctxt->validate == 1)) {
01011     if ((node->ns == NULL) || (node->ns->prefix == NULL)) {
01012         reader->ctxt->valid &= xmlValidatePopElement(&reader->ctxt->vctxt,
01013                     reader->ctxt->myDoc, node, node->name);
01014     } else {
01015         /* TODO use the BuildQName interface */
01016         xmlChar *qname;
01017 
01018         qname = xmlStrdup(node->ns->prefix);
01019         qname = xmlStrcat(qname, BAD_CAST ":");
01020         qname = xmlStrcat(qname, node->name);
01021         reader->ctxt->valid &= xmlValidatePopElement(&reader->ctxt->vctxt,
01022                     reader->ctxt->myDoc, node, qname);
01023         if (qname != NULL)
01024         xmlFree(qname);
01025     }
01026     }
01027 #endif /* LIBXML_VALID_ENABLED */
01028 #ifdef LIBXML_SCHEMAS_ENABLED
01029     if ((reader->validate == XML_TEXTREADER_VALIDATE_RNG) &&
01030                (reader->rngValidCtxt != NULL)) {
01031     int ret;
01032 
01033     if (reader->rngFullNode != NULL) {
01034         if (node == reader->rngFullNode)
01035             reader->rngFullNode = NULL;
01036         return;
01037     }
01038     ret = xmlRelaxNGValidatePopElement(reader->rngValidCtxt,
01039                                        reader->ctxt->myDoc,
01040                        node);
01041     if (ret != 1)
01042         reader->rngValidErrors++;
01043     }
01044 #endif
01045 }
01046 
01055 static void
01056 xmlTextReaderValidateEntity(xmlTextReaderPtr reader) {
01057     xmlNodePtr oldnode = reader->node;
01058     xmlNodePtr node = reader->node;
01059     xmlParserCtxtPtr ctxt = reader->ctxt;
01060 
01061     do {
01062     if (node->type == XML_ENTITY_REF_NODE) {
01063         /*
01064          * Case where the underlying tree is not availble, lookup the entity
01065          * and walk it.
01066          */
01067         if ((node->children == NULL) && (ctxt->sax != NULL) &&
01068         (ctxt->sax->getEntity != NULL)) {
01069         node->children = (xmlNodePtr)
01070             ctxt->sax->getEntity(ctxt, node->name);
01071         }
01072 
01073         if ((node->children != NULL) &&
01074         (node->children->type == XML_ENTITY_DECL) &&
01075         (node->children->children != NULL)) {
01076         xmlTextReaderEntPush(reader, node);
01077         node = node->children->children;
01078         continue;
01079         } else {
01080         /*
01081          * The error has probably be raised already.
01082          */
01083         if (node == oldnode)
01084             break;
01085         node = node->next;
01086         }
01087 #ifdef LIBXML_REGEXP_ENABLED
01088     } else if (node->type == XML_ELEMENT_NODE) {
01089         reader->node = node;
01090         xmlTextReaderValidatePush(reader);
01091     } else if ((node->type == XML_TEXT_NODE) ||
01092            (node->type == XML_CDATA_SECTION_NODE)) {
01093             xmlTextReaderValidateCData(reader, node->content,
01094                                    xmlStrlen(node->content));
01095 #endif
01096     }
01097 
01098     /*
01099      * go to next node
01100      */
01101     if (node->children != NULL) {
01102         node = node->children;
01103         continue;
01104     } else if (node->type == XML_ELEMENT_NODE) {
01105         xmlTextReaderValidatePop(reader);
01106     }
01107     if (node->next != NULL) {
01108         node = node->next;
01109         continue;
01110     }
01111     do {
01112         node = node->parent;
01113         if (node->type == XML_ELEMENT_NODE) {
01114             xmlNodePtr tmp;
01115         if (reader->entNr == 0) {
01116             while ((tmp = node->last) != NULL) {
01117             if ((tmp->extra & NODE_IS_PRESERVED) == 0) {
01118                 xmlUnlinkNode(tmp);
01119                 xmlTextReaderFreeNode(reader, tmp);
01120             } else
01121                 break;
01122             }
01123         }
01124         reader->node = node;
01125         xmlTextReaderValidatePop(reader);
01126         }
01127         if ((node->type == XML_ENTITY_DECL) &&
01128         (reader->ent != NULL) && (reader->ent->children == node)) {
01129         node = xmlTextReaderEntPop(reader);
01130         }
01131         if (node == oldnode)
01132         break;
01133         if (node->next != NULL) {
01134         node = node->next;
01135         break;
01136         }
01137     } while ((node != NULL) && (node != oldnode));
01138     } while ((node != NULL) && (node != oldnode));
01139     reader->node = oldnode;
01140 }
01141 #endif /* LIBXML_REGEXP_ENABLED */
01142 
01143 
01152 static xmlNodePtr
01153 xmlTextReaderGetSuccessor(xmlNodePtr cur) {
01154     if (cur == NULL) return(NULL) ; /* ERROR */
01155     if (cur->next != NULL) return(cur->next) ;
01156     do {
01157         cur = cur->parent;
01158         if (cur == NULL) break;
01159         if (cur->next != NULL) return(cur->next);
01160     } while (cur != NULL);
01161     return(cur);
01162 }
01163 
01175 static int
01176 xmlTextReaderDoExpand(xmlTextReaderPtr reader) {
01177     int val;
01178 
01179     if ((reader == NULL) || (reader->node == NULL) || (reader->ctxt == NULL))
01180         return(-1);
01181     do {
01182     if (reader->ctxt->instate == XML_PARSER_EOF) return(1);
01183 
01184         if (xmlTextReaderGetSuccessor(reader->node) != NULL)
01185         return(1);
01186     if (reader->ctxt->nodeNr < reader->depth)
01187         return(1);
01188     if (reader->mode == XML_TEXTREADER_MODE_EOF)
01189         return(1);
01190     val = xmlTextReaderPushData(reader);
01191     if (val < 0){
01192         reader->mode = XML_TEXTREADER_MODE_ERROR;
01193         return(-1);
01194     }
01195     } while(reader->mode != XML_TEXTREADER_MODE_EOF);
01196     return(1);
01197 }
01198 
01209 static xmlChar *
01210 xmlTextReaderCollectSiblings(xmlNodePtr node)
01211 {
01212     xmlBufferPtr buffer;
01213     xmlChar *ret;
01214 
01215     buffer = xmlBufferCreate();
01216     if (buffer == NULL)
01217        return NULL;
01218 
01219     for ( ; node != NULL; node = node->next) {
01220        switch (node->type) {
01221        case XML_TEXT_NODE:
01222        case XML_CDATA_SECTION_NODE:
01223            xmlBufferCat(buffer, node->content);
01224            break;
01225        case XML_ELEMENT_NODE: {
01226            xmlChar *tmp;
01227 
01228        tmp = xmlTextReaderCollectSiblings(node->children);
01229            xmlBufferCat(buffer, tmp);
01230        xmlFree(tmp);
01231        break;
01232        }
01233        default:
01234            break;
01235        }
01236     }
01237     ret = buffer->content;
01238     buffer->content = NULL;
01239     xmlBufferFree(buffer);
01240     return(ret);
01241 }
01242 
01253 int
01254 xmlTextReaderRead(xmlTextReaderPtr reader) {
01255     int val, olddepth = 0;
01256     xmlTextReaderState oldstate = XML_TEXTREADER_START;
01257     xmlNodePtr oldnode = NULL;
01258 
01259 
01260     if (reader == NULL)
01261     return(-1);
01262     reader->curnode = NULL;
01263     if (reader->doc != NULL)
01264         return(xmlTextReaderReadTree(reader));
01265     if (reader->ctxt == NULL)
01266     return(-1);
01267     if (reader->ctxt->wellFormed != 1)
01268     return(-1);
01269 
01270 #ifdef DEBUG_READER
01271     fprintf(stderr, "\nREAD ");
01272     DUMP_READER
01273 #endif
01274     if (reader->mode == XML_TEXTREADER_MODE_INITIAL) {
01275     reader->mode = XML_TEXTREADER_MODE_INTERACTIVE;
01276     /*
01277      * Initial state
01278      */
01279     do {
01280         val = xmlTextReaderPushData(reader);
01281         if (val < 0){
01282             reader->mode = XML_TEXTREADER_MODE_ERROR;
01283             reader->state = XML_TEXTREADER_ERROR;
01284         return(-1);
01285         }
01286     } while ((reader->ctxt->node == NULL) &&
01287          ((reader->mode != XML_TEXTREADER_MODE_EOF) &&
01288           (reader->state != XML_TEXTREADER_DONE)));
01289     if (reader->ctxt->node == NULL) {
01290         if (reader->ctxt->myDoc != NULL) {
01291         reader->node = reader->ctxt->myDoc->children;
01292         }
01293         if (reader->node == NULL){
01294             reader->mode = XML_TEXTREADER_MODE_ERROR;
01295             reader->state = XML_TEXTREADER_ERROR;
01296         return(-1);
01297         }
01298         reader->state = XML_TEXTREADER_ELEMENT;
01299     } else {
01300         if (reader->ctxt->myDoc != NULL) {
01301         reader->node = reader->ctxt->myDoc->children;
01302         }
01303         if (reader->node == NULL)
01304         reader->node = reader->ctxt->nodeTab[0];
01305         reader->state = XML_TEXTREADER_ELEMENT;
01306     }
01307     reader->depth = 0;
01308     reader->ctxt->parseMode = XML_PARSE_READER;
01309     goto node_found;
01310     }
01311     oldstate = reader->state;
01312     olddepth = reader->ctxt->nodeNr;
01313     oldnode = reader->node;
01314 
01315 get_next_node:
01316     if (reader->node == NULL) {
01317     if (reader->mode == XML_TEXTREADER_MODE_EOF)
01318         return(0);
01319     else
01320         return(-1);
01321     }
01322 
01323     /*
01324      * If we are not backtracking on ancestors or examined nodes,
01325      * that the parser didn't finished or that we arent at the end
01326      * of stream, continue processing.
01327      */
01328     while ((reader->node != NULL) && (reader->node->next == NULL) &&
01329        (reader->ctxt->nodeNr == olddepth) &&
01330            ((oldstate == XML_TEXTREADER_BACKTRACK) ||
01331             (reader->node->children == NULL) ||
01332         (reader->node->type == XML_ENTITY_REF_NODE) ||
01333         ((reader->node->children != NULL) &&
01334          (reader->node->children->type == XML_TEXT_NODE) &&
01335          (reader->node->children->next == NULL)) ||
01336         (reader->node->type == XML_DTD_NODE) ||
01337         (reader->node->type == XML_DOCUMENT_NODE) ||
01338         (reader->node->type == XML_HTML_DOCUMENT_NODE)) &&
01339        ((reader->ctxt->node == NULL) ||
01340         (reader->ctxt->node == reader->node) ||
01341         (reader->ctxt->node == reader->node->parent)) &&
01342        (reader->ctxt->instate != XML_PARSER_EOF)) {
01343     val = xmlTextReaderPushData(reader);
01344     if (val < 0){
01345         reader->mode = XML_TEXTREADER_MODE_ERROR;
01346         reader->state = XML_TEXTREADER_ERROR;
01347         return(-1);
01348     }
01349     if (reader->node == NULL)
01350         goto node_end;
01351     }
01352     if (oldstate != XML_TEXTREADER_BACKTRACK) {
01353     if ((reader->node->children != NULL) &&
01354         (reader->node->type != XML_ENTITY_REF_NODE) &&
01355         (reader->node->type != XML_XINCLUDE_START) &&
01356         (reader->node->type != XML_DTD_NODE)) {
01357         reader->node = reader->node->children;
01358         reader->depth++;
01359         reader->state = XML_TEXTREADER_ELEMENT;
01360         goto node_found;
01361     }
01362     }
01363     if (reader->node->next != NULL) {
01364     if ((oldstate == XML_TEXTREADER_ELEMENT) &&
01365             (reader->node->type == XML_ELEMENT_NODE) &&
01366         (reader->node->children == NULL) &&
01367         ((reader->node->extra & NODE_IS_EMPTY) == 0)
01368 #ifdef LIBXML_XINCLUDE_ENABLED
01369         && (reader->in_xinclude <= 0)
01370 #endif
01371         ) {
01372         reader->state = XML_TEXTREADER_END;
01373         goto node_found;
01374     }
01375 #ifdef LIBXML_REGEXP_ENABLED
01376     if ((reader->validate) &&
01377         (reader->node->type == XML_ELEMENT_NODE))
01378         xmlTextReaderValidatePop(reader);
01379 #endif /* LIBXML_REGEXP_ENABLED */
01380         if ((reader->preserves > 0) &&
01381         (reader->node->extra & NODE_IS_SPRESERVED))
01382         reader->preserves--;
01383     reader->node = reader->node->next;
01384     reader->state = XML_TEXTREADER_ELEMENT;
01385 
01386     /*
01387      * Cleanup of the old node
01388      */
01389     if ((reader->preserves == 0) &&
01390 #ifdef LIBXML_XINCLUDE_ENABLED
01391         (reader->in_xinclude == 0) &&
01392 #endif
01393         (reader->entNr == 0) &&
01394         (reader->node->prev != NULL) &&
01395             (reader->node->prev->type != XML_DTD_NODE) &&
01396         (reader->entNr == 0)) {
01397         xmlNodePtr tmp = reader->node->prev;
01398         if ((tmp->extra & NODE_IS_PRESERVED) == 0) {
01399         xmlUnlinkNode(tmp);
01400         xmlTextReaderFreeNode(reader, tmp);
01401         }
01402     }
01403 
01404     goto node_found;
01405     }
01406     if ((oldstate == XML_TEXTREADER_ELEMENT) &&
01407     (reader->node->type == XML_ELEMENT_NODE) &&
01408     (reader->node->children == NULL) &&
01409     ((reader->node->extra & NODE_IS_EMPTY) == 0)) {;
01410     reader->state = XML_TEXTREADER_END;
01411     goto node_found;
01412     }
01413 #ifdef LIBXML_REGEXP_ENABLED
01414     if ((reader->validate) && (reader->node->type == XML_ELEMENT_NODE))
01415     xmlTextReaderValidatePop(reader);
01416 #endif /* LIBXML_REGEXP_ENABLED */
01417     if ((reader->preserves > 0) &&
01418     (reader->node->extra & NODE_IS_SPRESERVED))
01419     reader->preserves--;
01420     reader->node = reader->node->parent;
01421     if ((reader->node == NULL) ||
01422     (reader->node->type == XML_DOCUMENT_NODE) ||
01423 #ifdef LIBXML_DOCB_ENABLED
01424     (reader->node->type == XML_DOCB_DOCUMENT_NODE) ||
01425 #endif
01426     (reader->node->type == XML_HTML_DOCUMENT_NODE)) {
01427     if (reader->mode != XML_TEXTREADER_MODE_EOF) {
01428         val = xmlParseChunk(reader->ctxt, "", 0, 1);
01429         reader->state = XML_TEXTREADER_DONE;
01430         if (val != 0)
01431             return(-1);
01432     }
01433     reader->node = NULL;
01434     reader->depth = -1;
01435 
01436     /*
01437      * Cleanup of the old node
01438      */
01439     if ((oldnode != NULL) && (reader->preserves == 0) &&
01440 #ifdef LIBXML_XINCLUDE_ENABLED
01441         (reader->in_xinclude == 0) &&
01442 #endif
01443         (reader->entNr == 0) &&
01444         (oldnode->type != XML_DTD_NODE) &&
01445         ((oldnode->extra & NODE_IS_PRESERVED) == 0) &&
01446         (reader->entNr == 0)) {
01447         xmlUnlinkNode(oldnode);
01448         xmlTextReaderFreeNode(reader, oldnode);
01449     }
01450 
01451     goto node_end;
01452     }
01453     if ((reader->preserves == 0) &&
01454 #ifdef LIBXML_XINCLUDE_ENABLED
01455         (reader->in_xinclude == 0) &&
01456 #endif
01457     (reader->entNr == 0) &&
01458         (reader->node->last != NULL) &&
01459         ((reader->node->last->extra & NODE_IS_PRESERVED) == 0)) {
01460     xmlNodePtr tmp = reader->node->last;
01461     xmlUnlinkNode(tmp);
01462     xmlTextReaderFreeNode(reader, tmp);
01463     }
01464     reader->depth--;
01465     reader->state = XML_TEXTREADER_BACKTRACK;
01466 
01467 node_found:
01468     DUMP_READER
01469 
01470     /*
01471      * If we are in the middle of a piece of CDATA make sure it's finished
01472      */
01473     if ((reader->node != NULL) &&
01474         (reader->node->next == NULL) &&
01475         ((reader->node->type == XML_TEXT_NODE) ||
01476      (reader->node->type == XML_CDATA_SECTION_NODE))) {
01477             if (xmlTextReaderExpand(reader) == NULL)
01478             return -1;
01479     }
01480 
01481 #ifdef LIBXML_XINCLUDE_ENABLED
01482     /*
01483      * Handle XInclude if asked for
01484      */
01485     if ((reader->xinclude) && (reader->node != NULL) &&
01486     (reader->node->type == XML_ELEMENT_NODE) &&
01487     (reader->node->ns != NULL) &&
01488     ((xmlStrEqual(reader->node->ns->href, XINCLUDE_NS)) ||
01489      (xmlStrEqual(reader->node->ns->href, XINCLUDE_OLD_NS)))) {
01490     if (reader->xincctxt == NULL) {
01491         reader->xincctxt = xmlXIncludeNewContext(reader->ctxt->myDoc);
01492         xmlXIncludeSetFlags(reader->xincctxt,
01493                             reader->parserFlags & (~XML_PARSE_NOXINCNODE));
01494     }
01495     /*
01496      * expand that node and process it
01497      */
01498     if (xmlTextReaderExpand(reader) == NULL)
01499         return -1;
01500     xmlXIncludeProcessNode(reader->xincctxt, reader->node);
01501     }
01502     if ((reader->node != NULL) && (reader->node->type == XML_XINCLUDE_START)) {
01503         reader->in_xinclude++;
01504     goto get_next_node;
01505     }
01506     if ((reader->node != NULL) && (reader->node->type == XML_XINCLUDE_END)) {
01507         reader->in_xinclude--;
01508     goto get_next_node;
01509     }
01510 #endif
01511     /*
01512      * Handle entities enter and exit when in entity replacement mode
01513      */
01514     if ((reader->node != NULL) &&
01515     (reader->node->type == XML_ENTITY_REF_NODE) &&
01516     (reader->ctxt != NULL) && (reader->ctxt->replaceEntities == 1)) {
01517     /*
01518      * Case where the underlying tree is not availble, lookup the entity
01519      * and walk it.
01520      */
01521     if ((reader->node->children == NULL) && (reader->ctxt->sax != NULL) &&
01522         (reader->ctxt->sax->getEntity != NULL)) {
01523         reader->node->children = (xmlNodePtr)
01524         reader->ctxt->sax->getEntity(reader->ctxt, reader->node->name);
01525     }
01526 
01527     if ((reader->node->children != NULL) &&
01528         (reader->node->children->type == XML_ENTITY_DECL) &&
01529         (reader->node->children->children != NULL)) {
01530         xmlTextReaderEntPush(reader, reader->node);
01531         reader->node = reader->node->children->children;
01532     }
01533 #ifdef LIBXML_REGEXP_ENABLED
01534     } else if ((reader->node != NULL) &&
01535            (reader->node->type == XML_ENTITY_REF_NODE) &&
01536            (reader->ctxt != NULL) && (reader->validate)) {
01537     xmlTextReaderValidateEntity(reader);
01538 #endif /* LIBXML_REGEXP_ENABLED */
01539     }
01540     if ((reader->node != NULL) &&
01541     (reader->node->type == XML_ENTITY_DECL) &&
01542     (reader->ent != NULL) && (reader->ent->children == reader->node)) {
01543     reader->node = xmlTextReaderEntPop(reader);
01544     reader->depth++;
01545         goto get_next_node;
01546     }
01547 #ifdef LIBXML_REGEXP_ENABLED
01548     if ((reader->validate) && (reader->node != NULL)) {
01549     xmlNodePtr node = reader->node;
01550 
01551     if ((node->type == XML_ELEMENT_NODE) &&
01552             ((reader->state != XML_TEXTREADER_END) &&
01553          (reader->state != XML_TEXTREADER_BACKTRACK))) {
01554         xmlTextReaderValidatePush(reader);
01555     } else if ((node->type == XML_TEXT_NODE) ||
01556            (node->type == XML_CDATA_SECTION_NODE)) {
01557             xmlTextReaderValidateCData(reader, node->content,
01558                                    xmlStrlen(node->content));
01559     }
01560     }
01561 #endif /* LIBXML_REGEXP_ENABLED */
01562 #ifdef LIBXML_PATTERN_ENABLED
01563     if ((reader->patternNr > 0) && (reader->state != XML_TEXTREADER_END) &&
01564         (reader->state != XML_TEXTREADER_BACKTRACK)) {
01565         int i;
01566     for (i = 0;i < reader->patternNr;i++) {
01567          if (xmlPatternMatch(reader->patternTab[i], reader->node) == 1) {
01568              xmlTextReaderPreserve(reader);
01569          break;
01570              }
01571     }
01572     }
01573 #endif /* LIBXML_PATTERN_ENABLED */
01574 #ifdef LIBXML_SCHEMAS_ENABLED
01575     if ((reader->validate == XML_TEXTREADER_VALIDATE_XSD) &&
01576         (reader->xsdValidErrors == 0) &&
01577     (reader->xsdValidCtxt != NULL)) {
01578     reader->xsdValidErrors = !xmlSchemaIsValid(reader->xsdValidCtxt);
01579     }
01580 #endif /* LIBXML_PATTERN_ENABLED */
01581     return(1);
01582 node_end:
01583     reader->state = XML_TEXTREADER_DONE;
01584     return(0);
01585 }
01586 
01595 int
01596 xmlTextReaderReadState(xmlTextReaderPtr reader) {
01597     if (reader == NULL)
01598     return(-1);
01599     return(reader->mode);
01600 }
01601 
01612 xmlNodePtr
01613 xmlTextReaderExpand(xmlTextReaderPtr reader) {
01614     if ((reader == NULL) || (reader->node == NULL))
01615         return(NULL);
01616     if (reader->doc != NULL)
01617         return(reader->node);
01618     if (reader->ctxt == NULL)
01619         return(NULL);
01620     if (xmlTextReaderDoExpand(reader) < 0)
01621         return(NULL);
01622     return(reader->node);
01623 }
01624 
01635 int
01636 xmlTextReaderNext(xmlTextReaderPtr reader) {
01637     int ret;
01638     xmlNodePtr cur;
01639 
01640     if (reader == NULL)
01641     return(-1);
01642     if (reader->doc != NULL)
01643         return(xmlTextReaderNextTree(reader));
01644     cur = reader->node;
01645     if ((cur == NULL) || (cur->type != XML_ELEMENT_NODE))
01646         return(xmlTextReaderRead(reader));
01647     if (reader->state == XML_TEXTREADER_END || reader->state == XML_TEXTREADER_BACKTRACK)
01648         return(xmlTextReaderRead(reader));
01649     if (cur->extra & NODE_IS_EMPTY)
01650         return(xmlTextReaderRead(reader));
01651     do {
01652         ret = xmlTextReaderRead(reader);
01653     if (ret != 1)
01654         return(ret);
01655     } while (reader->node != cur);
01656     return(xmlTextReaderRead(reader));
01657 }
01658 
01659 #ifdef LIBXML_WRITER_ENABLED
01660 
01670 xmlChar *
01671 xmlTextReaderReadInnerXml(xmlTextReaderPtr reader ATTRIBUTE_UNUSED)
01672 {
01673     xmlChar *resbuf;
01674     xmlNodePtr node, cur_node;
01675     xmlBufferPtr buff, buff2;
01676     xmlDocPtr doc;
01677 
01678     if (xmlTextReaderExpand(reader) == NULL) {
01679         return NULL;
01680     }
01681     doc = reader->doc;
01682     buff = xmlBufferCreate();
01683     for (cur_node = reader->node->children; cur_node != NULL;
01684          cur_node = cur_node->next) {
01685         node = xmlDocCopyNode(cur_node, doc, 1);
01686         buff2 = xmlBufferCreate();
01687         if (xmlNodeDump(buff2, doc, node, 0, 0) == -1) {
01688             xmlFreeNode(node);
01689             xmlBufferFree(buff2);
01690             xmlBufferFree(buff);
01691             return NULL;
01692         }
01693         xmlBufferCat(buff, buff2->content);
01694         xmlFreeNode(node);
01695         xmlBufferFree(buff2);
01696     }
01697     resbuf = buff->content;
01698     buff->content = NULL;
01699 
01700     xmlBufferFree(buff);
01701     return resbuf;
01702 }
01703 #endif
01704 
01705 #ifdef LIBXML_WRITER_ENABLED
01706 
01716 xmlChar *
01717 xmlTextReaderReadOuterXml(xmlTextReaderPtr reader ATTRIBUTE_UNUSED)
01718 {
01719     xmlChar *resbuf;
01720     xmlNodePtr node;
01721     xmlBufferPtr buff;
01722     xmlDocPtr doc;
01723 
01724     node = reader->node;
01725     doc = reader->doc;
01726     if (xmlTextReaderExpand(reader) == NULL) {
01727         return NULL;
01728     }
01729     if (node->type == XML_DTD_NODE) {
01730         node = (xmlNodePtr) xmlCopyDtd((xmlDtdPtr) node);
01731     } else {
01732         node = xmlDocCopyNode(node, doc, 1);
01733     }
01734     buff = xmlBufferCreate();
01735     if (xmlNodeDump(buff, doc, node, 0, 0) == -1) {
01736         xmlFreeNode(node);
01737         xmlBufferFree(buff);
01738         return NULL;
01739     }
01740 
01741     resbuf = buff->content;
01742     buff->content = NULL;
01743 
01744     xmlFreeNode(node);
01745     xmlBufferFree(buff);
01746     return resbuf;
01747 }
01748 #endif
01749 
01760 xmlChar *
01761 xmlTextReaderReadString(xmlTextReaderPtr reader)
01762 {
01763     xmlNodePtr node;
01764 
01765     if ((reader == NULL) || (reader->node == NULL))
01766        return(NULL);
01767 
01768     node = (reader->curnode != NULL) ? reader->curnode : reader->node;
01769     switch (node->type) {
01770     case XML_TEXT_NODE:
01771        if (node->content != NULL)
01772            return(xmlStrdup(node->content));
01773        break;
01774     case XML_ELEMENT_NODE:
01775     if (xmlTextReaderDoExpand(reader) != -1) {
01776         return xmlTextReaderCollectSiblings(node->children);
01777     }
01778     case XML_ATTRIBUTE_NODE:
01779     TODO
01780     break;
01781     default:
01782        break;
01783     }
01784     return(NULL);
01785 }
01786 
01787 #if 0
01788 
01802 int
01803 xmlTextReaderReadBase64(xmlTextReaderPtr reader,
01804                         unsigned char *array ATTRIBUTE_UNUSED,
01805                     int offset ATTRIBUTE_UNUSED,
01806             int len ATTRIBUTE_UNUSED) {
01807     if ((reader == NULL) || (reader->ctxt == NULL))
01808     return(-1);
01809     if (reader->ctxt->wellFormed != 1)
01810     return(-1);
01811 
01812     if ((reader->node == NULL) || (reader->node->type == XML_ELEMENT_NODE))
01813     return(0);
01814     TODO
01815     return(0);
01816 }
01817 
01832 int
01833 xmlTextReaderReadBinHex(xmlTextReaderPtr reader,
01834                         unsigned char *array ATTRIBUTE_UNUSED,
01835                     int offset ATTRIBUTE_UNUSED,
01836             int len ATTRIBUTE_UNUSED) {
01837     if ((reader == NULL) || (reader->ctxt == NULL))
01838     return(-1);
01839     if (reader->ctxt->wellFormed != 1)
01840     return(-1);
01841 
01842     if ((reader->node == NULL) || (reader->node->type == XML_ELEMENT_NODE))
01843     return(0);
01844     TODO
01845     return(0);
01846 }
01847 #endif
01848 
01849 /************************************************************************
01850  *                                  *
01851  *          Operating on a preparsed tree           *
01852  *                                  *
01853  ************************************************************************/
01854 static int
01855 xmlTextReaderNextTree(xmlTextReaderPtr reader)
01856 {
01857     if (reader == NULL)
01858         return(-1);
01859 
01860     if (reader->state == XML_TEXTREADER_END)
01861         return(0);
01862 
01863     if (reader->node == NULL) {
01864         if (reader->doc->children == NULL) {
01865             reader->state = XML_TEXTREADER_END;
01866             return(0);
01867         }
01868 
01869         reader->node = reader->doc->children;
01870         reader->state = XML_TEXTREADER_START;
01871         return(1);
01872     }
01873 
01874     if (reader->state != XML_TEXTREADER_BACKTRACK) {
01875     /* Here removed traversal to child, because we want to skip the subtree,
01876     replace with traversal to sibling to skip subtree */
01877         if (reader->node->next != 0) {
01878         /* Move to sibling if present,skipping sub-tree */
01879             reader->node = reader->node->next;
01880             reader->state = XML_TEXTREADER_START;
01881             return(1);
01882         }
01883 
01884     /* if reader->node->next is NULL mean no subtree for current node,
01885     so need to move to sibling of parent node if present */
01886         if ((reader->node->type == XML_ELEMENT_NODE) ||
01887             (reader->node->type == XML_ATTRIBUTE_NODE)) {
01888             reader->state = XML_TEXTREADER_BACKTRACK;
01889         /* This will move to parent if present */
01890             xmlTextReaderRead(reader);
01891         }
01892     }
01893 
01894     if (reader->node->next != 0) {
01895         reader->node = reader->node->next;
01896         reader->state = XML_TEXTREADER_START;
01897         return(1);
01898     }
01899 
01900     if (reader->node->parent != 0) {
01901         if (reader->node->parent->type == XML_DOCUMENT_NODE) {
01902             reader->state = XML_TEXTREADER_END;
01903             return(0);
01904         }
01905 
01906         reader->node = reader->node->parent;
01907         reader->depth--;
01908         reader->state = XML_TEXTREADER_BACKTRACK;
01909     /* Repeat process to move to sibling of parent node if present */
01910         xmlTextReaderNextTree(reader);
01911     }
01912 
01913     reader->state = XML_TEXTREADER_END;
01914 
01915     return(1);
01916 }
01917 
01928 static int
01929 xmlTextReaderReadTree(xmlTextReaderPtr reader) {
01930     if (reader->state == XML_TEXTREADER_END)
01931         return(0);
01932 
01933 next_node:
01934     if (reader->node == NULL) {
01935         if (reader->doc->children == NULL) {
01936             reader->state = XML_TEXTREADER_END;
01937             return(0);
01938         }
01939 
01940         reader->node = reader->doc->children;
01941         reader->state = XML_TEXTREADER_START;
01942         goto found_node;
01943     }
01944 
01945     if ((reader->state != XML_TEXTREADER_BACKTRACK) &&
01946         (reader->node->type != XML_DTD_NODE) &&
01947         (reader->node->type != XML_XINCLUDE_START) &&
01948     (reader->node->type != XML_ENTITY_REF_NODE)) {
01949         if (reader->node->children != NULL) {
01950             reader->node = reader->node->children;
01951             reader->depth++;
01952             reader->state = XML_TEXTREADER_START;
01953             goto found_node;
01954         }
01955 
01956         if (reader->node->type == XML_ATTRIBUTE_NODE) {
01957             reader->state = XML_TEXTREADER_BACKTRACK;
01958             goto found_node;
01959         }
01960     }
01961 
01962     if (reader->node->next != NULL) {
01963         reader->node = reader->node->next;
01964         reader->state = XML_TEXTREADER_START;
01965         goto found_node;
01966     }
01967 
01968     if (reader->node->parent != NULL) {
01969         if ((reader->node->parent->type == XML_DOCUMENT_NODE) ||
01970         (reader->node->parent->type == XML_HTML_DOCUMENT_NODE)) {
01971             reader->state = XML_TEXTREADER_END;
01972             return(0);
01973         }
01974 
01975         reader->node = reader->node->parent;
01976         reader->depth--;
01977         reader->state = XML_TEXTREADER_BACKTRACK;
01978         goto found_node;
01979     }
01980 
01981     reader->state = XML_TEXTREADER_END;
01982 
01983 found_node:
01984     if ((reader->node->type == XML_XINCLUDE_START) ||
01985         (reader->node->type == XML_XINCLUDE_END))
01986     goto next_node;
01987 
01988     return(1);
01989 }
01990 
02002 int
02003 xmlTextReaderNextSibling(xmlTextReaderPtr reader) {
02004     if (reader == NULL)
02005         return(-1);
02006     if (reader->doc == NULL) {
02007         /* TODO */
02008     return(-1);
02009     }
02010 
02011     if (reader->state == XML_TEXTREADER_END)
02012         return(0);
02013 
02014     if (reader->node == NULL)
02015         return(xmlTextReaderNextTree(reader));
02016 
02017     if (reader->node->next != NULL) {
02018         reader->node = reader->node->next;
02019         reader->state = XML_TEXTREADER_START;
02020         return(1);
02021     }
02022 
02023     return(0);
02024 }
02025 
02026 /************************************************************************
02027  *                                  *
02028  *          Constructor and destructors         *
02029  *                                  *
02030  ************************************************************************/
02040 xmlTextReaderPtr
02041 xmlNewTextReader(xmlParserInputBufferPtr input, const char *URI) {
02042     xmlTextReaderPtr ret;
02043 
02044     if (input == NULL)
02045     return(NULL);
02046     ret = xmlMalloc(sizeof(xmlTextReader));
02047     if (ret == NULL) {
02048         xmlGenericError(xmlGenericErrorContext,
02049         "xmlNewTextReader : malloc failed\n");
02050     return(NULL);
02051     }
02052     memset(ret, 0, sizeof(xmlTextReader));
02053     ret->doc = NULL;
02054     ret->entTab = NULL;
02055     ret->entMax = 0;
02056     ret->entNr = 0;
02057     ret->input = input;
02058     ret->buffer = xmlBufferCreateSize(100);
02059     if (ret->buffer == NULL) {
02060         xmlFree(ret);
02061         xmlGenericError(xmlGenericErrorContext,
02062         "xmlNewTextReader : malloc failed\n");
02063     return(NULL);
02064     }
02065     ret->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
02066     if (ret->sax == NULL) {
02067     xmlBufferFree(ret->buffer);
02068     xmlFree(ret);
02069         xmlGenericError(xmlGenericErrorContext,
02070         "xmlNewTextReader : malloc failed\n");
02071     return(NULL);
02072     }
02073     xmlSAXVersion(ret->sax, 2);
02074     ret->startElement = ret->sax->startElement;
02075     ret->sax->startElement = xmlTextReaderStartElement;
02076     ret->endElement = ret->sax->endElement;
02077     ret->sax->endElement = xmlTextReaderEndElement;
02078 #ifdef LIBXML_SAX1_ENABLED
02079     if (ret->sax->initialized == XML_SAX2_MAGIC) {
02080 #endif /* LIBXML_SAX1_ENABLED */
02081     ret->startElementNs = ret->sax->startElementNs;
02082     ret->sax->startElementNs = xmlTextReaderStartElementNs;
02083     ret->endElementNs = ret->sax->endElementNs;
02084     ret->sax->endElementNs = xmlTextReaderEndElementNs;
02085 #ifdef LIBXML_SAX1_ENABLED
02086     } else {
02087     ret->startElementNs = NULL;
02088     ret->endElementNs = NULL;
02089     }
02090 #endif /* LIBXML_SAX1_ENABLED */
02091     ret->characters = ret->sax->characters;
02092     ret->sax->characters = xmlTextReaderCharacters;
02093     ret->sax->ignorableWhitespace = xmlTextReaderCharacters;
02094     ret->cdataBlock = ret->sax->cdataBlock;
02095     ret->sax->cdataBlock = xmlTextReaderCDataBlock;
02096 
02097     ret->mode = XML_TEXTREADER_MODE_INITIAL;
02098     ret->node = NULL;
02099     ret->curnode = NULL;
02100     if (ret->input->buffer->use < 4) {
02101     xmlParserInputBufferRead(input, 4);
02102     }
02103     if (ret->input->buffer->use >= 4) {
02104     ret->ctxt = xmlCreatePushParserCtxt(ret->sax, NULL,
02105             (const char *) ret->input->buffer->content, 4, URI);
02106     ret->base = 0;
02107     ret->cur = 4;
02108     } else {
02109     ret->ctxt = xmlCreatePushParserCtxt(ret->sax, NULL, NULL, 0, URI);
02110     ret->base = 0;
02111     ret->cur = 0;
02112     }
02113 
02114     if (ret->ctxt == NULL) {
02115         xmlGenericError(xmlGenericErrorContext,
02116         "xmlNewTextReader : malloc failed\n");
02117     xmlBufferFree(ret->buffer);
02118     xmlFree(ret->sax);
02119     xmlFree(ret);
02120     return(NULL);
02121     }
02122     ret->ctxt->parseMode = XML_PARSE_READER;
02123     ret->ctxt->_private = ret;
02124     ret->ctxt->linenumbers = 1;
02125     ret->ctxt->dictNames = 1;
02126     ret->allocs = XML_TEXTREADER_CTXT;
02127     /*
02128      * use the parser dictionnary to allocate all elements and attributes names
02129      */
02130     ret->ctxt->docdict = 1;
02131     ret->dict = ret->ctxt->dict;
02132 #ifdef LIBXML_XINCLUDE_ENABLED
02133     ret->xinclude = 0;
02134 #endif
02135 #ifdef LIBXML_PATTERN_ENABLED
02136     ret->patternMax = 0;
02137     ret->patternTab = NULL;
02138 #endif
02139     return(ret);
02140 }
02141 
02150 xmlTextReaderPtr
02151 xmlNewTextReaderFilename(const char *URI) {
02152     xmlParserInputBufferPtr input;
02153     xmlTextReaderPtr ret;
02154     char *directory = NULL;
02155 
02156     input = xmlParserInputBufferCreateFilename(URI, XML_CHAR_ENCODING_NONE);
02157     if (input == NULL)
02158     return(NULL);
02159     ret = xmlNewTextReader(input, URI);
02160     if (ret == NULL) {
02161     xmlFreeParserInputBuffer(input);
02162     return(NULL);
02163     }
02164     ret->allocs |= XML_TEXTREADER_INPUT;
02165     if (ret->ctxt->directory == NULL)
02166         directory = xmlParserGetDirectory(URI);
02167     if ((ret->ctxt->directory == NULL) && (directory != NULL))
02168         ret->ctxt->directory = (char *) xmlStrdup((xmlChar *) directory);
02169     if (directory != NULL)
02170     xmlFree(directory);
02171     return(ret);
02172 }
02173 
02180 void
02181 xmlFreeTextReader(xmlTextReaderPtr reader) {
02182     if (reader == NULL)
02183     return;
02184 #ifdef LIBXML_SCHEMAS_ENABLED
02185     if (reader->rngSchemas != NULL) {
02186     xmlRelaxNGFree(reader->rngSchemas);
02187     reader->rngSchemas = NULL;
02188     }
02189     if (reader->rngValidCtxt != NULL) {
02190     xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);
02191     reader->rngValidCtxt = NULL;
02192     }
02193     if (reader->xsdPlug != NULL) {
02194     xmlSchemaSAXUnplug(reader->xsdPlug);
02195     reader->xsdPlug = NULL;
02196     }
02197     if (reader->xsdValidCtxt != NULL) {
02198     if (! reader->xsdPreserveCtxt)
02199         xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
02200     reader->xsdValidCtxt = NULL;
02201     }
02202     if (reader->xsdSchemas != NULL) {
02203     xmlSchemaFree(reader->xsdSchemas);
02204     reader->xsdSchemas = NULL;
02205     }
02206 #endif
02207 #ifdef LIBXML_XINCLUDE_ENABLED
02208     if (reader->xincctxt != NULL)
02209     xmlXIncludeFreeContext(reader->xincctxt);
02210 #endif
02211 #ifdef LIBXML_PATTERN_ENABLED
02212     if (reader->patternTab != NULL) {
02213         int i;
02214     for (i = 0;i < reader->patternNr;i++) {
02215         if (reader->patternTab[i] != NULL)
02216             xmlFreePattern(reader->patternTab[i]);
02217     }
02218     xmlFree(reader->patternTab);
02219     }
02220 #endif
02221     if (reader->faketext != NULL) {
02222     xmlFreeNode(reader->faketext);
02223     }
02224     if (reader->ctxt != NULL) {
02225         if (reader->dict == reader->ctxt->dict)
02226         reader->dict = NULL;
02227     if (reader->ctxt->myDoc != NULL) {
02228         if (reader->preserve == 0)
02229         xmlTextReaderFreeDoc(reader, reader->ctxt->myDoc);
02230         reader->ctxt->myDoc = NULL;
02231     }
02232     if ((reader->ctxt->vctxt.vstateTab != NULL) &&
02233         (reader->ctxt->vctxt.vstateMax > 0)){
02234         xmlFree(reader->ctxt->vctxt.vstateTab);
02235         reader->ctxt->vctxt.vstateTab = NULL;
02236         reader->ctxt->vctxt.vstateMax = 0;
02237     }
02238     if (reader->allocs & XML_TEXTREADER_CTXT)
02239         xmlFreeParserCtxt(reader->ctxt);
02240     }
02241     if (reader->sax != NULL)
02242     xmlFree(reader->sax);
02243     if ((reader->input != NULL)  && (reader->allocs & XML_TEXTREADER_INPUT))
02244     xmlFreeParserInputBuffer(reader->input);
02245     if (reader->buffer != NULL)
02246         xmlBufferFree(reader->buffer);
02247     if (reader->entTab != NULL)
02248     xmlFree(reader->entTab);
02249     if (reader->dict != NULL)
02250         xmlDictFree(reader->dict);
02251     xmlFree(reader);
02252 }
02253 
02254 /************************************************************************
02255  *                                  *
02256  *          Methods for XmlTextReader           *
02257  *                                  *
02258  ************************************************************************/
02268 int
02269 xmlTextReaderClose(xmlTextReaderPtr reader) {
02270     if (reader == NULL)
02271     return(-1);
02272     reader->node = NULL;
02273     reader->curnode = NULL;
02274     reader->mode = XML_TEXTREADER_MODE_CLOSED;
02275     if (reader->ctxt != NULL) {
02276     xmlStopParser(reader->ctxt);
02277     if (reader->ctxt->myDoc != NULL) {
02278         if (reader->preserve == 0)
02279         xmlTextReaderFreeDoc(reader, reader->ctxt->myDoc);
02280         reader->ctxt->myDoc = NULL;
02281     }
02282     }
02283     if ((reader->input != NULL)  && (reader->allocs & XML_TEXTREADER_INPUT)) {
02284     xmlFreeParserInputBuffer(reader->input);
02285     reader->allocs -= XML_TEXTREADER_INPUT;
02286     }
02287     return(0);
02288 }
02289 
02301 xmlChar *
02302 xmlTextReaderGetAttributeNo(xmlTextReaderPtr reader, int no) {
02303     xmlChar *ret;
02304     int i;
02305     xmlAttrPtr cur;
02306     xmlNsPtr ns;
02307 
02308     if (reader == NULL)
02309     return(NULL);
02310     if (reader->node == NULL)
02311     return(NULL);
02312     if (reader->curnode != NULL)
02313     return(NULL);
02314     /* TODO: handle the xmlDecl */
02315     if (reader->node->type != XML_ELEMENT_NODE)
02316     return(NULL);
02317 
02318     ns = reader->node->nsDef;
02319     for (i = 0;(i < no) && (ns != NULL);i++) {
02320     ns = ns->next;
02321     }
02322     if (ns != NULL)
02323     return(xmlStrdup(ns->href));
02324 
02325     cur = reader->node->properties;
02326     if (cur == NULL)
02327     return(NULL);
02328     for (;i < no;i++) {
02329     cur = cur->next;
02330     if (cur == NULL)
02331         return(NULL);
02332     }
02333     /* TODO walk the DTD if present */
02334 
02335     ret = xmlNodeListGetString(reader->node->doc, cur->children, 1);
02336     if (ret == NULL) return(xmlStrdup((xmlChar *)""));
02337     return(ret);
02338 }
02339 
02350 xmlChar *
02351 xmlTextReaderGetAttribute(xmlTextReaderPtr reader, const xmlChar *name) {
02352     xmlChar *prefix = NULL;
02353     xmlChar *localname;
02354     xmlNsPtr ns;
02355     xmlChar *ret = NULL;
02356 
02357     if ((reader == NULL) || (name == NULL))
02358     return(NULL);
02359     if (reader->node == NULL)
02360     return(NULL);
02361     if (reader->curnode != NULL)
02362     return(NULL);
02363 
02364     /* TODO: handle the xmlDecl */
02365     if (reader->node->type != XML_ELEMENT_NODE)
02366     return(NULL);
02367 
02368     localname = xmlSplitQName2(name, &prefix);
02369     if (localname == NULL) {
02370         /*
02371          * Namespace default decl
02372          */
02373         if (xmlStrEqual(name, BAD_CAST "xmlns")) {
02374             ns = reader->node->nsDef;
02375             while (ns != NULL) {
02376                 if (ns->prefix == NULL) {
02377                     return(xmlStrdup(ns->href));
02378                 }
02379                 ns = ns->next;
02380             }
02381             return NULL;
02382         }
02383         return(xmlGetNoNsProp(reader->node, name));
02384     }
02385 
02386     /*
02387      * Namespace default decl
02388      */
02389     if (xmlStrEqual(prefix, BAD_CAST "xmlns")) {
02390         ns = reader->node->nsDef;
02391         while (ns != NULL) {
02392             if ((ns->prefix != NULL) && (xmlStrEqual(ns->prefix, localname))) {
02393                 ret = xmlStrdup(ns->href);
02394                 break;
02395             }
02396             ns = ns->next;
02397         }
02398     } else {
02399         ns = xmlSearchNs(reader->node->doc, reader->node, prefix);
02400         if (ns != NULL)
02401             ret = xmlGetNsProp(reader->node, localname, ns->href);
02402     }
02403 
02404     xmlFree(localname);
02405     if (prefix != NULL)
02406         xmlFree(prefix);
02407     return(ret);
02408 }
02409 
02410 
02422 xmlChar *
02423 xmlTextReaderGetAttributeNs(xmlTextReaderPtr reader, const xmlChar *localName,
02424                 const xmlChar *namespaceURI) {
02425     xmlChar *prefix = NULL;
02426     xmlNsPtr ns;
02427 
02428     if ((reader == NULL) || (localName == NULL))
02429     return(NULL);
02430     if (reader->node == NULL)
02431     return(NULL);
02432     if (reader->curnode != NULL)
02433     return(NULL);
02434 
02435     /* TODO: handle the xmlDecl */
02436     if (reader->node->type != XML_ELEMENT_NODE)
02437     return(NULL);
02438 
02439     if (xmlStrEqual(namespaceURI, BAD_CAST "http://www.w3.org/2000/xmlns/")) {
02440         if (! xmlStrEqual(localName, BAD_CAST "xmlns")) {
02441             prefix = BAD_CAST localName;
02442         }
02443         ns = reader->node->nsDef;
02444         while (ns != NULL) {
02445             if ((prefix == NULL && ns->prefix == NULL) ||
02446                 ((ns->prefix != NULL) && (xmlStrEqual(ns->prefix, localName)))) {
02447                 return xmlStrdup(ns->href);
02448             }
02449             ns = ns->next;
02450         }
02451         return NULL;
02452     }
02453 
02454     return(xmlGetNsProp(reader->node, localName, namespaceURI));
02455 }
02456 
02472 xmlParserInputBufferPtr
02473 xmlTextReaderGetRemainder(xmlTextReaderPtr reader) {
02474     xmlParserInputBufferPtr ret = NULL;
02475 
02476     if (reader == NULL)
02477     return(NULL);
02478     if (reader->node == NULL)
02479     return(NULL);
02480 
02481     reader->node = NULL;
02482     reader->curnode = NULL;
02483     reader->mode = XML_TEXTREADER_MODE_EOF;
02484     if (reader->ctxt != NULL) {
02485     xmlStopParser(reader->ctxt);
02486     if (reader->ctxt->myDoc != NULL) {
02487         if (reader->preserve == 0)
02488         xmlTextReaderFreeDoc(reader, reader->ctxt->myDoc);
02489         reader->ctxt->myDoc = NULL;
02490     }
02491     }
02492     if (reader->allocs & XML_TEXTREADER_INPUT) {
02493     ret = reader->input;
02494     reader->input = NULL;
02495     reader->allocs -= XML_TEXTREADER_INPUT;
02496     } else {
02497     /*
02498      * Hum, one may need to duplicate the data structure because
02499      * without reference counting the input may be freed twice:
02500      *   - by the layer which allocated it.
02501      *   - by the layer to which would have been returned to.
02502      */
02503     TODO
02504     return(NULL);
02505     }
02506     return(ret);
02507 }
02508 
02520 xmlChar *
02521 xmlTextReaderLookupNamespace(xmlTextReaderPtr reader, const xmlChar *prefix) {
02522     xmlNsPtr ns;
02523 
02524     if (reader == NULL)
02525     return(NULL);
02526     if (reader->node == NULL)
02527     return(NULL);
02528 
02529     ns = xmlSearchNs(reader->node->doc, reader->node, prefix);
02530     if (ns == NULL)
02531     return(NULL);
02532     return(xmlStrdup(ns->href));
02533 }
02534 
02546 int
02547 xmlTextReaderMoveToAttributeNo(xmlTextReaderPtr reader, int no) {
02548     int i;
02549     xmlAttrPtr cur;
02550     xmlNsPtr ns;
02551 
02552     if (reader == NULL)
02553     return(-1);
02554     if (reader->node == NULL)
02555     return(-1);
02556     /* TODO: handle the xmlDecl */
02557     if (reader->node->type != XML_ELEMENT_NODE)
02558     return(-1);
02559 
02560     reader->curnode = NULL;
02561 
02562     ns = reader->node->nsDef;
02563     for (i = 0;(i < no) && (ns != NULL);i++) {
02564     ns = ns->next;
02565     }
02566     if (ns != NULL) {
02567     reader->curnode = (xmlNodePtr) ns;
02568     return(1);
02569     }
02570 
02571     cur = reader->node->properties;
02572     if (cur == NULL)
02573     return(0);
02574     for (;i < no;i++) {
02575     cur = cur->next;
02576     if (cur == NULL)
02577         return(0);
02578     }
02579     /* TODO walk the DTD if present */
02580 
02581     reader->curnode = (xmlNodePtr) cur;
02582     return(1);
02583 }
02584 
02595 int
02596 xmlTextReaderMoveToAttribute(xmlTextReaderPtr reader, const xmlChar *name) {
02597     xmlChar *prefix = NULL;
02598     xmlChar *localname;
02599     xmlNsPtr ns;
02600     xmlAttrPtr prop;
02601 
02602     if ((reader == NULL) || (name == NULL))
02603     return(-1);
02604     if (reader->node == NULL)
02605     return(-1);
02606 
02607     /* TODO: handle the xmlDecl */
02608     if (reader->node->type != XML_ELEMENT_NODE)
02609     return(0);
02610 
02611     localname = xmlSplitQName2(name, &prefix);
02612     if (localname == NULL) {
02613     /*
02614      * Namespace default decl
02615      */
02616     if (xmlStrEqual(name, BAD_CAST "xmlns")) {
02617         ns = reader->node->nsDef;
02618         while (ns != NULL) {
02619         if (ns->prefix == NULL) {
02620             reader->curnode = (xmlNodePtr) ns;
02621             return(1);
02622         }
02623         ns = ns->next;
02624         }
02625         return(0);
02626     }
02627 
02628     prop = reader->node->properties;
02629     while (prop != NULL) {
02630         /*
02631          * One need to have
02632          *   - same attribute names
02633          *   - and the attribute carrying that namespace
02634          */
02635         if ((xmlStrEqual(prop->name, name)) &&
02636         ((prop->ns == NULL) || (prop->ns->prefix == NULL))) {
02637         reader->curnode = (xmlNodePtr) prop;
02638         return(1);
02639         }
02640         prop = prop->next;
02641     }
02642     return(0);
02643     }
02644 
02645     /*
02646      * Namespace default decl
02647      */
02648     if (xmlStrEqual(prefix, BAD_CAST "xmlns")) {
02649     ns = reader->node->nsDef;
02650     while (ns != NULL) {
02651         if ((ns->prefix != NULL) && (xmlStrEqual(ns->prefix, localname))) {
02652         reader->curnode = (xmlNodePtr) ns;
02653         goto found;
02654         }
02655         ns = ns->next;
02656     }
02657     goto not_found;
02658     }
02659     prop = reader->node->properties;
02660     while (prop != NULL) {
02661     /*
02662      * One need to have
02663      *   - same attribute names
02664      *   - and the attribute carrying that namespace
02665      */
02666     if ((xmlStrEqual(prop->name, localname)) &&
02667         (prop->ns != NULL) && (xmlStrEqual(prop->ns->prefix, prefix))) {
02668         reader->curnode = (xmlNodePtr) prop;
02669         goto found;
02670     }
02671     prop = prop->next;
02672     }
02673 not_found:
02674     if (localname != NULL)
02675         xmlFree(localname);
02676     if (prefix != NULL)
02677         xmlFree(prefix);
02678     return(0);
02679 
02680 found:
02681     if (localname != NULL)
02682         xmlFree(localname);
02683     if (prefix != NULL)
02684         xmlFree(prefix);
02685     return(1);
02686 }
02687 
02699 int
02700 xmlTextReaderMoveToAttributeNs(xmlTextReaderPtr reader,
02701     const xmlChar *localName, const xmlChar *namespaceURI) {
02702     xmlAttrPtr prop;
02703     xmlNodePtr node;
02704     xmlNsPtr ns;
02705     xmlChar *prefix = NULL;
02706 
02707     if ((reader == NULL) || (localName == NULL) || (namespaceURI == NULL))
02708     return(-1);
02709     if (reader->node == NULL)
02710     return(-1);
02711     if (reader->node->type != XML_ELEMENT_NODE)
02712     return(0);
02713     node = reader->node;
02714 
02715     if (xmlStrEqual(namespaceURI, BAD_CAST "http://www.w3.org/2000/xmlns/")) {
02716         if (! xmlStrEqual(localName, BAD_CAST "xmlns")) {
02717             prefix = BAD_CAST localName;
02718         }
02719         ns = reader->node->nsDef;
02720         while (ns != NULL) {
02721             if ((prefix == NULL && ns->prefix == NULL) ||
02722                 ((ns->prefix != NULL) && (xmlStrEqual(ns->prefix, localName)))) {
02723                 reader->curnode = (xmlNodePtr) ns;
02724                 return(1);
02725             }
02726             ns = ns->next;
02727         }
02728         return(0);
02729     }
02730 
02731     prop = node->properties;
02732     while (prop != NULL) {
02733     /*
02734      * One need to have
02735      *   - same attribute names
02736      *   - and the attribute carrying that namespace
02737      */
02738         if (xmlStrEqual(prop->name, localName) &&
02739         ((prop->ns != NULL) &&
02740          (xmlStrEqual(prop->ns->href, namespaceURI)))) {
02741         reader->curnode = (xmlNodePtr) prop;
02742         return(1);
02743         }
02744     prop = prop->next;
02745     }
02746     return(0);
02747 }
02748 
02758 int
02759 xmlTextReaderMoveToFirstAttribute(xmlTextReaderPtr reader) {
02760     if (reader == NULL)
02761     return(-1);
02762     if (reader->node == NULL)
02763     return(-1);
02764     if (reader->node->type != XML_ELEMENT_NODE)
02765     return(0);
02766 
02767     if (reader->node->nsDef != NULL) {
02768     reader->curnode = (xmlNodePtr) reader->node->nsDef;
02769     return(1);
02770     }
02771     if (reader->node->properties != NULL) {
02772     reader->curnode = (xmlNodePtr) reader->node->properties;
02773     return(1);
02774     }
02775     return(0);
02776 }
02777 
02787 int
02788 xmlTextReaderMoveToNextAttribute(xmlTextReaderPtr reader) {
02789     if (reader == NULL)
02790     return(-1);
02791     if (reader->node == NULL)
02792     return(-1);
02793     if (reader->node->type != XML_ELEMENT_NODE)
02794     return(0);
02795     if (reader->curnode == NULL)
02796     return(xmlTextReaderMoveToFirstAttribute(reader));
02797 
02798     if (reader->curnode->type == XML_NAMESPACE_DECL) {
02799     xmlNsPtr ns = (xmlNsPtr) reader->curnode;
02800     if (ns->next != NULL) {
02801         reader->curnode = (xmlNodePtr) ns->next;
02802         return(1);
02803     }
02804     if (reader->node->properties != NULL) {
02805         reader->curnode = (xmlNodePtr) reader->node->properties;
02806         return(1);
02807     }
02808     return(0);
02809     } else if ((reader->curnode->type == XML_ATTRIBUTE_NODE) &&
02810            (reader->curnode->next != NULL)) {
02811     reader->curnode = reader->curnode->next;
02812     return(1);
02813     }
02814     return(0);
02815 }
02816 
02826 int
02827 xmlTextReaderMoveToElement(xmlTextReaderPtr reader) {
02828     if (reader == NULL)
02829     return(-1);
02830     if (reader->node == NULL)
02831     return(-1);
02832     if (reader->node->type != XML_ELEMENT_NODE)
02833     return(0);
02834     if (reader->curnode != NULL) {
02835     reader->curnode = NULL;
02836     return(1);
02837     }
02838     return(0);
02839 }
02840 
02851 int
02852 xmlTextReaderReadAttributeValue(xmlTextReaderPtr reader) {
02853     if (reader == NULL)
02854     return(-1);
02855     if (reader->node == NULL)
02856     return(-1);
02857     if (reader->curnode == NULL)
02858     return(0);
02859     if (reader->curnode->type == XML_ATTRIBUTE_NODE) {
02860     if (reader->curnode->children == NULL)
02861         return(0);
02862     reader->curnode = reader->curnode->children;
02863     } else if (reader->curnode->type == XML_NAMESPACE_DECL) {
02864     xmlNsPtr ns = (xmlNsPtr) reader->curnode;
02865 
02866     if (reader->faketext == NULL) {
02867         reader->faketext = xmlNewDocText(reader->node->doc,
02868                                      ns->href);
02869     } else {
02870             if ((reader->faketext->content != NULL) &&
02871             (reader->faketext->content !=
02872          (xmlChar *) &(reader->faketext->properties)))
02873         xmlFree(reader->faketext->content);
02874         reader->faketext->content = xmlStrdup(ns->href);
02875     }
02876     reader->curnode = reader->faketext;
02877     } else {
02878     if (reader->curnode->next == NULL)
02879         return(0);
02880     reader->curnode = reader->curnode->next;
02881     }
02882     return(1);
02883 }
02884 
02894 const xmlChar *
02895 xmlTextReaderConstEncoding(xmlTextReaderPtr reader) {
02896     xmlDocPtr doc = NULL;
02897     if (reader == NULL)
02898     return(NULL);
02899     if (reader->doc != NULL)
02900         doc = reader->doc;
02901     else if (reader->ctxt != NULL)
02902     doc = reader->ctxt->myDoc;
02903     if (doc == NULL)
02904     return(NULL);
02905 
02906     if (doc->encoding == NULL)
02907     return(NULL);
02908     else
02909       return(CONSTSTR(doc->encoding));
02910 }
02911 
02912 
02913 /************************************************************************
02914  *                                  *
02915  *          Acces API to the current node           *
02916  *                                  *
02917  ************************************************************************/
02926 int
02927 xmlTextReaderAttributeCount(xmlTextReaderPtr reader) {
02928     int ret;
02929     xmlAttrPtr attr;
02930     xmlNsPtr ns;
02931     xmlNodePtr node;
02932 
02933     if (reader == NULL)
02934     return(-1);
02935     if (reader->node == NULL)
02936     return(0);
02937 
02938     if (reader->curnode != NULL)
02939     node = reader->curnode;
02940     else
02941     node = reader->node;
02942 
02943     if (node->type != XML_ELEMENT_NODE)
02944     return(0);
02945     if ((reader->state == XML_TEXTREADER_END) ||
02946     (reader->state == XML_TEXTREADER_BACKTRACK))
02947     return(0);
02948     ret = 0;
02949     attr = node->properties;
02950     while (attr != NULL) {
02951     ret++;
02952     attr = attr->next;
02953     }
02954     ns = node->nsDef;
02955     while (ns != NULL) {
02956     ret++;
02957     ns = ns->next;
02958     }
02959     return(ret);
02960 }
02961 
02972 int
02973 xmlTextReaderNodeType(xmlTextReaderPtr reader) {
02974     xmlNodePtr node;
02975 
02976     if (reader == NULL)
02977     return(-1);
02978     if (reader->node == NULL)
02979     return(XML_READER_TYPE_NONE);
02980     if (reader->curnode != NULL)
02981     node = reader->curnode;
02982     else
02983     node = reader->node;
02984     switch (node->type) {
02985         case XML_ELEMENT_NODE:
02986         if ((reader->state == XML_TEXTREADER_END) ||
02987         (reader->state == XML_TEXTREADER_BACKTRACK))
02988         return(XML_READER_TYPE_END_ELEMENT);
02989         return(XML_READER_TYPE_ELEMENT);
02990         case XML_NAMESPACE_DECL:
02991         case XML_ATTRIBUTE_NODE:
02992         return(XML_READER_TYPE_ATTRIBUTE);
02993         case XML_TEXT_NODE:
02994         if (xmlIsBlankNode(reader->node)) {
02995         if (xmlNodeGetSpacePreserve(reader->node))
02996             return(XML_READER_TYPE_SIGNIFICANT_WHITESPACE);
02997         else
02998             return(XML_READER_TYPE_WHITESPACE);
02999         } else {
03000         return(XML_READER_TYPE_TEXT);
03001         }
03002         case XML_CDATA_SECTION_NODE:
03003         return(XML_READER_TYPE_CDATA);
03004         case XML_ENTITY_REF_NODE:
03005         return(XML_READER_TYPE_ENTITY_REFERENCE);
03006         case XML_ENTITY_NODE:
03007         return(XML_READER_TYPE_ENTITY);
03008         case XML_PI_NODE:
03009         return(XML_READER_TYPE_PROCESSING_INSTRUCTION);
03010         case XML_COMMENT_NODE:
03011         return(XML_READER_TYPE_COMMENT);
03012         case XML_DOCUMENT_NODE:
03013         case XML_HTML_DOCUMENT_NODE:
03014 #ifdef LIBXML_DOCB_ENABLED
03015         case XML_DOCB_DOCUMENT_NODE:
03016 #endif
03017         return(XML_READER_TYPE_DOCUMENT);
03018         case XML_DOCUMENT_FRAG_NODE:
03019         return(XML_READER_TYPE_DOCUMENT_FRAGMENT);
03020         case XML_NOTATION_NODE:
03021         return(XML_READER_TYPE_NOTATION);
03022         case XML_DOCUMENT_TYPE_NODE:
03023         case XML_DTD_NODE:
03024         return(XML_READER_TYPE_DOCUMENT_TYPE);
03025 
03026         case XML_ELEMENT_DECL:
03027         case XML_ATTRIBUTE_DECL:
03028         case XML_ENTITY_DECL:
03029         case XML_XINCLUDE_START:
03030         case XML_XINCLUDE_END:
03031         return(XML_READER_TYPE_NONE);
03032     }
03033     return(-1);
03034 }
03035 
03044 int
03045 xmlTextReaderIsEmptyElement(xmlTextReaderPtr reader) {
03046     if ((reader == NULL) || (reader->node == NULL))
03047     return(-1);
03048     if (reader->node->type != XML_ELEMENT_NODE)
03049     return(0);
03050     if (reader->curnode != NULL)
03051     return(0);
03052     if (reader->node->children != NULL)
03053     return(0);
03054     if (reader->state == XML_TEXTREADER_END)
03055     return(0);
03056     if (reader->doc != NULL)
03057         return(1);
03058 #ifdef LIBXML_XINCLUDE_ENABLED
03059     if (reader->in_xinclude > 0)
03060         return(1);
03061 #endif
03062     return((reader->node->extra & NODE_IS_EMPTY) != 0);
03063 }
03064 
03074 xmlChar *
03075 xmlTextReaderLocalName(xmlTextReaderPtr reader) {
03076     xmlNodePtr node;
03077     if ((reader == NULL) || (reader->node == NULL))
03078     return(NULL);
03079     if (reader->curnode != NULL)
03080     node = reader->curnode;
03081     else
03082     node = reader->node;
03083     if (node->type == XML_NAMESPACE_DECL) {
03084     xmlNsPtr ns = (xmlNsPtr) node;
03085     if (ns->prefix == NULL)
03086         return(xmlStrdup(BAD_CAST "xmlns"));
03087     else
03088         return(xmlStrdup(ns->prefix));
03089     }
03090     if ((node->type != XML_ELEMENT_NODE) &&
03091     (node->type != XML_ATTRIBUTE_NODE))
03092     return(xmlTextReaderName(reader));
03093     return(xmlStrdup(node->name));
03094 }
03095 
03105 const xmlChar *
03106 xmlTextReaderConstLocalName(xmlTextReaderPtr reader) {
03107     xmlNodePtr node;
03108     if ((reader == NULL) || (reader->node == NULL))
03109     return(NULL);
03110     if (reader->curnode != NULL)
03111     node = reader->curnode;
03112     else
03113     node = reader->node;
03114     if (node->type == XML_NAMESPACE_DECL) {
03115     xmlNsPtr ns = (xmlNsPtr) node;
03116     if (ns->prefix == NULL)
03117         return(CONSTSTR(BAD_CAST "xmlns"));
03118     else
03119         return(ns->prefix);
03120     }
03121     if ((node->type != XML_ELEMENT_NODE) &&
03122     (node->type != XML_ATTRIBUTE_NODE))
03123     return(xmlTextReaderConstName(reader));
03124     return(node->name);
03125 }
03126 
03136 xmlChar *
03137 xmlTextReaderName(xmlTextReaderPtr reader) {
03138     xmlNodePtr node;
03139     xmlChar *ret;
03140 
03141     if ((reader == NULL) || (reader->node == NULL))
03142     return(NULL);
03143     if (reader->curnode != NULL)
03144     node = reader->curnode;
03145     else
03146     node = reader->node;
03147     switch (node->type) {
03148         case XML_ELEMENT_NODE:
03149         case XML_ATTRIBUTE_NODE:
03150         if ((node->ns == NULL) ||
03151         (node->ns->prefix == NULL))
03152         return(xmlStrdup(node->name));
03153 
03154         ret = xmlStrdup(node->ns->prefix);
03155         ret = xmlStrcat(ret, BAD_CAST ":");
03156         ret = xmlStrcat(ret, node->name);
03157         return(ret);
03158         case XML_TEXT_NODE:
03159         return(xmlStrdup(BAD_CAST "#text"));
03160         case XML_CDATA_SECTION_NODE:
03161         return(xmlStrdup(BAD_CAST "#cdata-section"));
03162         case XML_ENTITY_NODE:
03163         case XML_ENTITY_REF_NODE:
03164         return(xmlStrdup(node->name));
03165         case XML_PI_NODE:
03166         return(xmlStrdup(node->name));
03167         case XML_COMMENT_NODE:
03168         return(xmlStrdup(BAD_CAST "#comment"));
03169         case XML_DOCUMENT_NODE:
03170         case XML_HTML_DOCUMENT_NODE:
03171 #ifdef LIBXML_DOCB_ENABLED
03172         case XML_DOCB_DOCUMENT_NODE:
03173 #endif
03174         return(xmlStrdup(BAD_CAST "#document"));
03175         case XML_DOCUMENT_FRAG_NODE:
03176         return(xmlStrdup(BAD_CAST "#document-fragment"));
03177         case XML_NOTATION_NODE:
03178         return(xmlStrdup(node->name));
03179         case XML_DOCUMENT_TYPE_NODE:
03180         case XML_DTD_NODE:
03181         return(xmlStrdup(node->name));
03182         case XML_NAMESPACE_DECL: {
03183         xmlNsPtr ns = (xmlNsPtr) node;
03184 
03185         ret = xmlStrdup(BAD_CAST "xmlns");
03186         if (ns->prefix == NULL)
03187         return(ret);
03188         ret = xmlStrcat(ret, BAD_CAST ":");
03189         ret = xmlStrcat(ret, ns->prefix);
03190         return(ret);
03191     }
03192 
03193         case XML_ELEMENT_DECL:
03194         case XML_ATTRIBUTE_DECL:
03195         case XML_ENTITY_DECL:
03196         case XML_XINCLUDE_START:
03197         case XML_XINCLUDE_END:
03198         return(NULL);
03199     }
03200     return(NULL);
03201 }
03202 
03212 const xmlChar *
03213 xmlTextReaderConstName(xmlTextReaderPtr reader) {
03214     xmlNodePtr node;
03215 
03216     if ((reader == NULL) || (reader->node == NULL))
03217     return(NULL);
03218     if (reader->curnode != NULL)
03219     node = reader->curnode;
03220     else
03221     node = reader->node;
03222     switch (node->type) {
03223         case XML_ELEMENT_NODE:
03224         case XML_ATTRIBUTE_NODE:
03225         if ((node->ns == NULL) ||
03226         (node->ns->prefix == NULL))
03227         return(node->name);
03228         return(CONSTQSTR(node->ns->prefix, node->name));
03229         case XML_TEXT_NODE:
03230         return(CONSTSTR(BAD_CAST "#text"));
03231         case XML_CDATA_SECTION_NODE:
03232         return(CONSTSTR(BAD_CAST "#cdata-section"));
03233         case XML_ENTITY_NODE:
03234         case XML_ENTITY_REF_NODE:
03235         return(CONSTSTR(node->name));
03236         case XML_PI_NODE:
03237         return(CONSTSTR(node->name));
03238         case XML_COMMENT_NODE:
03239         return(CONSTSTR(BAD_CAST "#comment"));
03240         case XML_DOCUMENT_NODE:
03241         case XML_HTML_DOCUMENT_NODE:
03242 #ifdef LIBXML_DOCB_ENABLED
03243         case XML_DOCB_DOCUMENT_NODE:
03244 #endif
03245         return(CONSTSTR(BAD_CAST "#document"));
03246         case XML_DOCUMENT_FRAG_NODE:
03247         return(CONSTSTR(BAD_CAST "#document-fragment"));
03248         case XML_NOTATION_NODE:
03249         return(CONSTSTR(node->name));
03250         case XML_DOCUMENT_TYPE_NODE:
03251         case XML_DTD_NODE:
03252         return(CONSTSTR(node->name));
03253         case XML_NAMESPACE_DECL: {
03254         xmlNsPtr ns = (xmlNsPtr) node;
03255 
03256         if (ns->prefix == NULL)
03257         return(CONSTSTR(BAD_CAST "xmlns"));
03258         return(CONSTQSTR(BAD_CAST "xmlns", ns->prefix));
03259     }
03260 
03261         case XML_ELEMENT_DECL:
03262         case XML_ATTRIBUTE_DECL:
03263         case XML_ENTITY_DECL:
03264         case XML_XINCLUDE_START:
03265         case XML_XINCLUDE_END:
03266         return(NULL);
03267     }
03268     return(NULL);
03269 }
03270 
03280 xmlChar *
03281 xmlTextReaderPrefix(xmlTextReaderPtr reader) {
03282     xmlNodePtr node;
03283     if ((reader == NULL) || (reader->node == NULL))
03284     return(NULL);
03285     if (reader->curnode != NULL)
03286     node = reader->curnode;
03287     else
03288     node = reader->node;
03289     if (node->type == XML_NAMESPACE_DECL) {
03290     xmlNsPtr ns = (xmlNsPtr) node;
03291     if (ns->prefix == NULL)
03292         return(NULL);
03293     return(xmlStrdup(BAD_CAST "xmlns"));
03294     }
03295     if ((node->type != XML_ELEMENT_NODE) &&
03296     (node->type != XML_ATTRIBUTE_NODE))
03297     return(NULL);
03298     if ((node->ns != NULL) && (node->ns->prefix != NULL))
03299     return(xmlStrdup(node->ns->prefix));
03300     return(NULL);
03301 }
03302 
03312 const xmlChar *
03313 xmlTextReaderConstPrefix(xmlTextReaderPtr reader) {
03314     xmlNodePtr node;
03315     if ((reader == NULL) || (reader->node == NULL))
03316     return(NULL);
03317     if (reader->curnode != NULL)
03318     node = reader->curnode;
03319     else
03320     node = reader->node;
03321     if (node->type == XML_NAMESPACE_DECL) {
03322     xmlNsPtr ns = (xmlNsPtr) node;
03323     if (ns->prefix == NULL)
03324         return(NULL);
03325     return(CONSTSTR(BAD_CAST "xmlns"));
03326     }
03327     if ((node->type != XML_ELEMENT_NODE) &&
03328     (node->type != XML_ATTRIBUTE_NODE))
03329     return(NULL);
03330     if ((node->ns != NULL) && (node->ns->prefix != NULL))
03331     return(CONSTSTR(node->ns->prefix));
03332     return(NULL);
03333 }
03334 
03344 xmlChar *
03345 xmlTextReaderNamespaceUri(xmlTextReaderPtr reader) {
03346     xmlNodePtr node;
03347     if ((reader == NULL) || (reader->node == NULL))
03348     return(NULL);
03349     if (reader->curnode != NULL)
03350     node = reader->curnode;
03351     else
03352     node = reader->node;
03353     if (node->type == XML_NAMESPACE_DECL)
03354     return(xmlStrdup(BAD_CAST "http://www.w3.org/2000/xmlns/"));
03355     if ((node->type != XML_ELEMENT_NODE) &&
03356     (node->type != XML_ATTRIBUTE_NODE))
03357     return(NULL);
03358     if (node->ns != NULL)
03359     return(xmlStrdup(node->ns->href));
03360     return(NULL);
03361 }
03362 
03372 const xmlChar *
03373 xmlTextReaderConstNamespaceUri(xmlTextReaderPtr reader) {
03374     xmlNodePtr node;
03375     if ((reader == NULL) || (reader->node == NULL))
03376     return(NULL);
03377     if (reader->curnode != NULL)
03378     node = reader->curnode;
03379     else
03380     node = reader->node;
03381     if (node->type == XML_NAMESPACE_DECL)
03382     return(CONSTSTR(BAD_CAST "http://www.w3.org/2000/xmlns/"));
03383     if ((node->type != XML_ELEMENT_NODE) &&
03384     (node->type != XML_ATTRIBUTE_NODE))
03385     return(NULL);
03386     if (node->ns != NULL)
03387     return(CONSTSTR(node->ns->href));
03388     return(NULL);
03389 }
03390 
03400 xmlChar *
03401 xmlTextReaderBaseUri(xmlTextReaderPtr reader) {
03402     if ((reader == NULL) || (reader->node == NULL))
03403     return(NULL);
03404     return(xmlNodeGetBase(NULL, reader->node));
03405 }
03406 
03416 const xmlChar *
03417 xmlTextReaderConstBaseUri(xmlTextReaderPtr reader) {
03418     xmlChar *tmp;
03419     const xmlChar *ret;
03420 
03421     if ((reader == NULL) || (reader->node == NULL))
03422     return(NULL);
03423     tmp = xmlNodeGetBase(NULL, reader->node);
03424     if (tmp == NULL)
03425         return(NULL);
03426     ret = CONSTSTR(tmp);
03427     xmlFree(tmp);
03428     return(ret);
03429 }
03430 
03439 int
03440 xmlTextReaderDepth(xmlTextReaderPtr reader) {
03441     if (reader == NULL)
03442     return(-1);
03443     if (reader->node == NULL)
03444     return(0);
03445 
03446     if (reader->curnode != NULL) {
03447     if ((reader->curnode->type == XML_ATTRIBUTE_NODE) ||
03448         (reader->curnode->type == XML_NAMESPACE_DECL))
03449         return(reader->depth + 1);
03450     return(reader->depth + 2);
03451     }
03452     return(reader->depth);
03453 }
03454 
03463 int
03464 xmlTextReaderHasAttributes(xmlTextReaderPtr reader) {
03465     xmlNodePtr node;
03466     if (reader == NULL)
03467     return(-1);
03468     if (reader->node == NULL)
03469     return(0);
03470     if (reader->curnode != NULL)
03471     node = reader->curnode;
03472     else
03473     node = reader->node;
03474 
03475     if ((node->type == XML_ELEMENT_NODE) &&
03476     ((node->properties != NULL) || (node->nsDef != NULL)))
03477     return(1);
03478     /* TODO: handle the xmlDecl */
03479     return(0);
03480 }
03481 
03490 int
03491 xmlTextReaderHasValue(xmlTextReaderPtr reader) {
03492     xmlNodePtr node;
03493     if (reader == NULL)
03494     return(-1);
03495     if (reader->node == NULL)
03496     return(0);
03497     if (reader->curnode != NULL)
03498     node = reader->curnode;
03499     else
03500     node = reader->node;
03501 
03502     switch (node->type) {
03503         case XML_ATTRIBUTE_NODE:
03504         case XML_TEXT_NODE:
03505         case XML_CDATA_SECTION_NODE:
03506         case XML_PI_NODE:
03507         case XML_COMMENT_NODE:
03508         case XML_NAMESPACE_DECL:
03509         return(1);
03510     default:
03511         break;
03512     }
03513     return(0);
03514 }
03515 
03525 xmlChar *
03526 xmlTextReaderValue(xmlTextReaderPtr reader) {
03527     xmlNodePtr node;
03528     if (reader == NULL)
03529     return(NULL);
03530     if (reader->node == NULL)
03531     return(NULL);
03532     if (reader->curnode != NULL)
03533     node = reader->curnode;
03534     else
03535     node = reader->node;
03536 
03537     switch (node->type) {
03538         case XML_NAMESPACE_DECL:
03539         return(xmlStrdup(((xmlNsPtr) node)->href));
03540         case XML_ATTRIBUTE_NODE:{
03541         xmlAttrPtr attr = (xmlAttrPtr) node;
03542 
03543         if (attr->parent != NULL)
03544         return (xmlNodeListGetString
03545             (attr->parent->doc, attr->children, 1));
03546         else
03547         return (xmlNodeListGetString(NULL, attr->children, 1));
03548         break;
03549     }
03550         case XML_TEXT_NODE:
03551         case XML_CDATA_SECTION_NODE:
03552         case XML_PI_NODE:
03553         case XML_COMMENT_NODE:
03554             if (node->content != NULL)
03555                 return (xmlStrdup(node->content));
03556     default:
03557         break;
03558     }
03559     return(NULL);
03560 }
03561 
03571 const xmlChar *
03572 xmlTextReaderConstValue(xmlTextReaderPtr reader) {
03573     xmlNodePtr node;
03574     if (reader == NULL)
03575     return(NULL);
03576     if (reader->node == NULL)
03577     return(NULL);
03578     if (reader->curnode != NULL)
03579     node = reader->curnode;
03580     else
03581     node = reader->node;
03582 
03583     switch (node->type) {
03584         case XML_NAMESPACE_DECL:
03585         return(((xmlNsPtr) node)->href);
03586         case XML_ATTRIBUTE_NODE:{
03587         xmlAttrPtr attr = (xmlAttrPtr) node;
03588 
03589         if ((attr->children != NULL) &&
03590             (attr->children->type == XML_TEXT_NODE) &&
03591         (attr->children->next == NULL))
03592         return(attr->children->content);
03593         else {
03594         if (reader->buffer == NULL)
03595             reader->buffer = xmlBufferCreateSize(100);
03596         if (reader->buffer == NULL) {
03597             xmlGenericError(xmlGenericErrorContext,
03598                     "xmlTextReaderSetup : malloc failed\n");
03599             return (NULL);
03600         }
03601             reader->buffer->use = 0;
03602             xmlNodeBufGetContent(reader->buffer, node);
03603         return(reader->buffer->content);
03604         }
03605         break;
03606     }
03607         case XML_TEXT_NODE:
03608         case XML_CDATA_SECTION_NODE:
03609         case XML_PI_NODE:
03610         case XML_COMMENT_NODE:
03611         return(node->content);
03612     default:
03613         break;
03614     }
03615     return(NULL);
03616 }
03617 
03627 int
03628 xmlTextReaderIsDefault(xmlTextReaderPtr reader) {
03629     if (reader == NULL)
03630     return(-1);
03631     return(0);
03632 }
03633 
03642 int
03643 xmlTextReaderQuoteChar(xmlTextReaderPtr reader) {
03644     if (reader == NULL)
03645     return(-1);
03646     /* TODO maybe lookup the attribute value for " first */
03647     return((int) '"');
03648 }
03649 
03659 xmlChar *
03660 xmlTextReaderXmlLang(xmlTextReaderPtr reader) {
03661     if (reader == NULL)
03662     return(NULL);
03663     if (reader->node == NULL)
03664     return(NULL);
03665     return(xmlNodeGetLang(reader->node));
03666 }
03667 
03676 const xmlChar *
03677 xmlTextReaderConstXmlLang(xmlTextReaderPtr reader) {
03678     xmlChar *tmp;
03679     const xmlChar *ret;
03680 
03681     if (reader == NULL)
03682     return(NULL);
03683     if (reader->node == NULL)
03684     return(NULL);
03685     tmp = xmlNodeGetLang(reader->node);
03686     if (tmp == NULL)
03687         return(NULL);
03688     ret = CONSTSTR(tmp);
03689     xmlFree(tmp);
03690     return(ret);
03691 }
03692 
03704 const xmlChar *
03705 xmlTextReaderConstString(xmlTextReaderPtr reader, const xmlChar *str) {
03706     if (reader == NULL)
03707     return(NULL);
03708     return(CONSTSTR(str));
03709 }
03710 
03723 int
03724 xmlTextReaderNormalization(xmlTextReaderPtr reader) {
03725     if (reader == NULL)
03726     return(-1);
03727     return(1);
03728 }
03729 
03730 /************************************************************************
03731  *                                  *
03732  *          Extensions to the base APIs         *
03733  *                                  *
03734  ************************************************************************/
03735 
03748 int
03749 xmlTextReaderSetParserProp(xmlTextReaderPtr reader, int prop, int value) {
03750     xmlParserProperties p = (xmlParserProperties) prop;
03751     xmlParserCtxtPtr ctxt;
03752 
03753     if ((reader == NULL) || (reader->ctxt == NULL))
03754     return(-1);
03755     ctxt = reader->ctxt;
03756 
03757     switch (p) {
03758         case XML_PARSER_LOADDTD:
03759         if (value != 0) {
03760         if (ctxt->loadsubset == 0) {
03761             if (reader->mode != XML_TEXTREADER_MODE_INITIAL)
03762             return(-1);
03763             ctxt->loadsubset = XML_DETECT_IDS;
03764         }
03765         } else {
03766         ctxt->loadsubset = 0;
03767         }
03768         return(0);
03769         case XML_PARSER_DEFAULTATTRS:
03770         if (value != 0) {
03771         ctxt->loadsubset |= XML_COMPLETE_ATTRS;
03772         } else {
03773         if (ctxt->loadsubset & XML_COMPLETE_ATTRS)
03774             ctxt->loadsubset -= XML_COMPLETE_ATTRS;
03775         }
03776         return(0);
03777         case XML_PARSER_VALIDATE:
03778         if (value != 0) {
03779         ctxt->validate = 1;
03780         reader->validate = XML_TEXTREADER_VALIDATE_DTD;
03781         } else {
03782         ctxt->validate = 0;
03783         }
03784         return(0);
03785         case XML_PARSER_SUBST_ENTITIES:
03786         if (value != 0) {
03787         ctxt->replaceEntities = 1;
03788         } else {
03789         ctxt->replaceEntities = 0;
03790         }
03791         return(0);
03792     }
03793     return(-1);
03794 }
03795 
03805 int
03806 xmlTextReaderGetParserProp(xmlTextReaderPtr reader, int prop) {
03807     xmlParserProperties p = (xmlParserProperties) prop;
03808     xmlParserCtxtPtr ctxt;
03809 
03810     if ((reader == NULL) || (reader->ctxt == NULL))
03811     return(-1);
03812     ctxt = reader->ctxt;
03813 
03814     switch (p) {
03815         case XML_PARSER_LOADDTD:
03816         if ((ctxt->loadsubset != 0) || (ctxt->validate != 0))
03817         return(1);
03818         return(0);
03819         case XML_PARSER_DEFAULTATTRS:
03820         if (ctxt->loadsubset & XML_COMPLETE_ATTRS)
03821         return(1);
03822         return(0);
03823         case XML_PARSER_VALIDATE:
03824         return(reader->validate);
03825     case XML_PARSER_SUBST_ENTITIES:
03826         return(ctxt->replaceEntities);
03827     }
03828     return(-1);
03829 }
03830 
03831 
03840 int
03841 xmlTextReaderGetParserLineNumber(xmlTextReaderPtr reader)
03842 {
03843     if ((reader == NULL) || (reader->ctxt == NULL) ||
03844         (reader->ctxt->input == NULL)) {
03845         return (0);
03846     }
03847     return (reader->ctxt->input->line);
03848 }
03849 
03858 int
03859 xmlTextReaderGetParserColumnNumber(xmlTextReaderPtr reader)
03860 {
03861     if ((reader == NULL) || (reader->ctxt == NULL) ||
03862         (reader->ctxt->input == NULL)) {
03863         return (0);
03864     }
03865     return (reader->ctxt->input->col);
03866 }
03867 
03878 xmlNodePtr
03879 xmlTextReaderCurrentNode(xmlTextReaderPtr reader) {
03880     if (reader == NULL)
03881     return(NULL);
03882 
03883     if (reader->curnode != NULL)
03884     return(reader->curnode);
03885     return(reader->node);
03886 }
03887 
03898 xmlNodePtr
03899 xmlTextReaderPreserve(xmlTextReaderPtr reader) {
03900     xmlNodePtr cur, parent;
03901 
03902     if (reader == NULL)
03903     return(NULL);
03904 
03905     if (reader->curnode != NULL)
03906         cur = reader->curnode;
03907     else
03908         cur = reader->node;
03909     if (cur == NULL)
03910         return(NULL);
03911 
03912     if ((cur->type != XML_DOCUMENT_NODE) && (cur->type != XML_DTD_NODE)) {
03913     cur->extra |= NODE_IS_PRESERVED;
03914     cur->extra |= NODE_IS_SPRESERVED;
03915     }
03916     reader->preserves++;
03917 
03918     parent = cur->parent;;
03919     while (parent != NULL) {
03920         if (parent->type == XML_ELEMENT_NODE)
03921         parent->extra |= NODE_IS_PRESERVED;
03922     parent = parent->parent;
03923     }
03924     return(cur);
03925 }
03926 
03927 #ifdef LIBXML_PATTERN_ENABLED
03928 
03940 int
03941 xmlTextReaderPreservePattern(xmlTextReaderPtr reader, const xmlChar *pattern,
03942                              const xmlChar **namespaces)
03943 {
03944     xmlPatternPtr comp;
03945 
03946     if ((reader == NULL) || (pattern == NULL))
03947     return(-1);
03948 
03949     comp = xmlPatterncompile(pattern, reader->dict, 0, namespaces);
03950     if (comp == NULL)
03951         return(-1);
03952 
03953     if (reader->patternMax <= 0) {
03954     reader->patternMax = 4;
03955     reader->patternTab = (xmlPatternPtr *) xmlMalloc(reader->patternMax *
03956                           sizeof(reader->patternTab[0]));
03957         if (reader->patternTab == NULL) {
03958             xmlGenericError(xmlGenericErrorContext, "xmlMalloc failed !\n");
03959             return (-1);
03960         }
03961     }
03962     if (reader->patternNr >= reader->patternMax) {
03963         xmlPatternPtr *tmp;
03964         reader->patternMax *= 2;
03965     tmp = (xmlPatternPtr *) xmlRealloc(reader->patternTab,
03966                                       reader->patternMax *
03967                                       sizeof(reader->patternTab[0]));
03968         if (tmp == NULL) {
03969             xmlGenericError(xmlGenericErrorContext, "xmlRealloc failed !\n");
03970         reader->patternMax /= 2;
03971             return (-1);
03972         }
03973     reader->patternTab = tmp;
03974     }
03975     reader->patternTab[reader->patternNr] = comp;
03976     return(reader->patternNr++);
03977 }
03978 #endif
03979 
03992 xmlDocPtr
03993 xmlTextReaderCurrentDoc(xmlTextReaderPtr reader) {
03994     if (reader == NULL)
03995     return(NULL);
03996     if (reader->doc != NULL)
03997         return(reader->doc);
03998     if ((reader->ctxt == NULL) || (reader->ctxt->myDoc == NULL))
03999     return(NULL);
04000 
04001     reader->preserve = 1;
04002     return(reader->ctxt->myDoc);
04003 }
04004 
04005 #ifdef LIBXML_SCHEMAS_ENABLED
04006 static char *xmlTextReaderBuildMessage(const char *msg, va_list ap);
04007 
04008 static void XMLCDECL
04009 xmlTextReaderValidityError(void *ctxt, const char *msg, ...);
04010 
04011 static void XMLCDECL
04012 xmlTextReaderValidityWarning(void *ctxt, const char *msg, ...);
04013 
04014 static void XMLCDECL
04015 xmlTextReaderValidityErrorRelay(void *ctx, const char *msg, ...)
04016 {
04017     xmlTextReaderPtr reader = (xmlTextReaderPtr) ctx;
04018 
04019     char *str;
04020 
04021     va_list ap;
04022 
04023     va_start(ap, msg);
04024     str = xmlTextReaderBuildMessage(msg, ap);
04025     if (!reader->errorFunc) {
04026         xmlTextReaderValidityError(ctx, "%s", str);
04027     } else {
04028         reader->errorFunc(reader->errorFuncArg, str,
04029                           XML_PARSER_SEVERITY_VALIDITY_ERROR,
04030                           NULL /* locator */ );
04031     }
04032     if (str != NULL)
04033         xmlFree(str);
04034     va_end(ap);
04035 }
04036 
04037 static void XMLCDECL
04038 xmlTextReaderValidityWarningRelay(void *ctx, const char *msg, ...)
04039 {
04040     xmlTextReaderPtr reader = (xmlTextReaderPtr) ctx;
04041 
04042     char *str;
04043 
04044     va_list ap;
04045 
04046     va_start(ap, msg);
04047     str = xmlTextReaderBuildMessage(msg, ap);
04048     if (!reader->errorFunc) {
04049         xmlTextReaderValidityWarning(ctx, "%s", str);
04050     } else {
04051         reader->errorFunc(reader->errorFuncArg, str,
04052                           XML_PARSER_SEVERITY_VALIDITY_WARNING,
04053                           NULL /* locator */ );
04054     }
04055     if (str != NULL)
04056         xmlFree(str);
04057     va_end(ap);
04058 }
04059 
04060 static void
04061   xmlTextReaderStructuredError(void *ctxt, xmlErrorPtr error);
04062 
04063 static void
04064 xmlTextReaderValidityStructuredRelay(void *userData, xmlErrorPtr error)
04065 {
04066     xmlTextReaderPtr reader = (xmlTextReaderPtr) userData;
04067 
04068     if (reader->sErrorFunc) {
04069         reader->sErrorFunc(reader->errorFuncArg, error);
04070     } else {
04071         xmlTextReaderStructuredError(reader, error);
04072     }
04073 }
04088 int
04089 xmlTextReaderRelaxNGSetSchema(xmlTextReaderPtr reader, xmlRelaxNGPtr schema) {
04090     if (reader == NULL)
04091         return(-1);
04092     if (schema == NULL) {
04093         if (reader->rngSchemas != NULL) {
04094         xmlRelaxNGFree(reader->rngSchemas);
04095         reader->rngSchemas = NULL;
04096     }
04097         if (reader->rngValidCtxt != NULL) {
04098         xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);
04099         reader->rngValidCtxt = NULL;
04100         }
04101     return(0);
04102     }
04103     if (reader->mode != XML_TEXTREADER_MODE_INITIAL)
04104     return(-1);
04105     if (reader->rngSchemas != NULL) {
04106     xmlRelaxNGFree(reader->rngSchemas);
04107     reader->rngSchemas = NULL;
04108     }
04109     if (reader->rngValidCtxt != NULL) {
04110     xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);
04111     reader->rngValidCtxt = NULL;
04112     }
04113     reader->rngValidCtxt = xmlRelaxNGNewValidCtxt(schema);
04114     if (reader->rngValidCtxt == NULL)
04115         return(-1);
04116     if (reader->errorFunc != NULL) {
04117     xmlRelaxNGSetValidErrors(reader->rngValidCtxt,
04118             xmlTextReaderValidityErrorRelay,
04119             xmlTextReaderValidityWarningRelay,
04120             reader);
04121     }
04122     if (reader->sErrorFunc != NULL) {
04123         xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,
04124             xmlTextReaderValidityStructuredRelay,
04125             reader);
04126     }
04127     reader->rngValidErrors = 0;
04128     reader->rngFullNode = NULL;
04129     reader->validate = XML_TEXTREADER_VALIDATE_RNG;
04130     return(0);
04131 }
04132 
04147 int
04148 xmlTextReaderSetSchema(xmlTextReaderPtr reader, xmlSchemaPtr schema) {
04149     if (reader == NULL)
04150         return(-1);
04151     if (schema == NULL) {
04152     if (reader->xsdPlug != NULL) {
04153         xmlSchemaSAXUnplug(reader->xsdPlug);
04154         reader->xsdPlug = NULL;
04155     }
04156         if (reader->xsdValidCtxt != NULL) {
04157         if (! reader->xsdPreserveCtxt)
04158         xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
04159         reader->xsdValidCtxt = NULL;
04160         }
04161     reader->xsdPreserveCtxt = 0;
04162         if (reader->xsdSchemas != NULL) {
04163         xmlSchemaFree(reader->xsdSchemas);
04164         reader->xsdSchemas = NULL;
04165     }
04166     return(0);
04167     }
04168     if (reader->mode != XML_TEXTREADER_MODE_INITIAL)
04169     return(-1);
04170     if (reader->xsdPlug != NULL) {
04171     xmlSchemaSAXUnplug(reader->xsdPlug);
04172     reader->xsdPlug = NULL;
04173     }
04174     if (reader->xsdValidCtxt != NULL) {
04175     if (! reader->xsdPreserveCtxt)
04176         xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
04177     reader->xsdValidCtxt = NULL;
04178     }
04179     reader->xsdPreserveCtxt = 0;
04180     if (reader->xsdSchemas != NULL) {
04181     xmlSchemaFree(reader->xsdSchemas);
04182     reader->xsdSchemas = NULL;
04183     }
04184     reader->xsdValidCtxt = xmlSchemaNewValidCtxt(schema);
04185     if (reader->xsdValidCtxt == NULL) {
04186     xmlSchemaFree(reader->xsdSchemas);
04187     reader->xsdSchemas = NULL;
04188         return(-1);
04189     }
04190     reader->xsdPlug = xmlSchemaSAXPlug(reader->xsdValidCtxt,
04191                                        &(reader->ctxt->sax),
04192                        &(reader->ctxt->userData));
04193     if (reader->xsdPlug == NULL) {
04194     xmlSchemaFree(reader->xsdSchemas);
04195     reader->xsdSchemas = NULL;
04196     xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
04197     reader->xsdValidCtxt = NULL;
04198     return(-1);
04199     }
04200     if (reader->errorFunc != NULL) {
04201     xmlSchemaSetValidErrors(reader->xsdValidCtxt,
04202             xmlTextReaderValidityErrorRelay,
04203             xmlTextReaderValidityWarningRelay,
04204             reader);
04205     }
04206     if (reader->sErrorFunc != NULL) {
04207         xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt,
04208             xmlTextReaderValidityStructuredRelay,
04209             reader);
04210     }
04211     reader->xsdValidErrors = 0;
04212     reader->validate = XML_TEXTREADER_VALIDATE_XSD;
04213     return(0);
04214 }
04215 
04228 int
04229 xmlTextReaderRelaxNGValidate(xmlTextReaderPtr reader, const char *rng) {
04230     xmlRelaxNGParserCtxtPtr ctxt;
04231 
04232     if (reader == NULL)
04233         return(-1);
04234 
04235     if (rng == NULL) {
04236         if (reader->rngValidCtxt != NULL) {
04237         xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);
04238         reader->rngValidCtxt = NULL;
04239         }
04240         if (reader->rngSchemas != NULL) {
04241         xmlRelaxNGFree(reader->rngSchemas);
04242         reader->rngSchemas = NULL;
04243     }
04244     return(0);
04245     }
04246     if (reader->mode != XML_TEXTREADER_MODE_INITIAL)
04247     return(-1);
04248     if (reader->rngSchemas != NULL) {
04249     xmlRelaxNGFree(reader->rngSchemas);
04250     reader->rngSchemas = NULL;
04251     }
04252     if (reader->rngValidCtxt != NULL) {
04253     xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);
04254     reader->rngValidCtxt = NULL;
04255     }
04256     ctxt = xmlRelaxNGNewParserCtxt(rng);
04257     if (reader->errorFunc != NULL) {
04258     xmlRelaxNGSetParserErrors(ctxt,
04259              xmlTextReaderValidityErrorRelay,
04260              xmlTextReaderValidityWarningRelay,
04261              reader);
04262     }
04263     if (reader->sErrorFunc != NULL) {
04264     xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,
04265             xmlTextReaderValidityStructuredRelay,
04266             reader);
04267     }
04268     reader->rngSchemas = xmlRelaxNGParse(ctxt);
04269     xmlRelaxNGFreeParserCtxt(ctxt);
04270     if (reader->rngSchemas == NULL)
04271         return(-1);
04272     reader->rngValidCtxt = xmlRelaxNGNewValidCtxt(reader->rngSchemas);
04273     if (reader->rngValidCtxt == NULL) {
04274     xmlRelaxNGFree(reader->rngSchemas);
04275     reader->rngSchemas = NULL;
04276         return(-1);
04277     }
04278     if (reader->errorFunc != NULL) {
04279     xmlRelaxNGSetValidErrors(reader->rngValidCtxt,
04280              xmlTextReaderValidityErrorRelay,
04281              xmlTextReaderValidityWarningRelay,
04282              reader);
04283     }
04284     if (reader->sErrorFunc != NULL) {
04285         xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,
04286             xmlTextReaderValidityStructuredRelay,
04287             reader);
04288     }
04289     reader->rngValidErrors = 0;
04290     reader->rngFullNode = NULL;
04291     reader->validate = XML_TEXTREADER_VALIDATE_RNG;
04292     return(0);
04293 }
04294 
04309 static int
04310 xmlTextReaderSchemaValidateInternal(xmlTextReaderPtr reader,
04311                     const char *xsd,
04312                     xmlSchemaValidCtxtPtr ctxt,
04313                     int options ATTRIBUTE_UNUSED)
04314 {
04315     if (reader == NULL)
04316         return(-1);
04317 
04318     if ((xsd != NULL) && (ctxt != NULL))
04319     return(-1);
04320 
04321     if (((xsd != NULL) || (ctxt != NULL)) &&
04322     ((reader->mode != XML_TEXTREADER_MODE_INITIAL) ||
04323         (reader->ctxt == NULL)))
04324     return(-1);
04325 
04326     /* Cleanup previous validation stuff. */
04327     if (reader->xsdPlug != NULL) {
04328     xmlSchemaSAXUnplug(reader->xsdPlug);
04329     reader->xsdPlug = NULL;
04330     }
04331     if (reader->xsdValidCtxt != NULL) {
04332     if (! reader->xsdPreserveCtxt)
04333         xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
04334     reader->xsdValidCtxt = NULL;
04335     }
04336     reader->xsdPreserveCtxt = 0;
04337     if (reader->xsdSchemas != NULL) {
04338     xmlSchemaFree(reader->xsdSchemas);
04339     reader->xsdSchemas = NULL;
04340     }
04341 
04342     if ((xsd == NULL) && (ctxt == NULL)) {
04343     /* We just want to deactivate the validation, so get out. */
04344     return(0);
04345     }
04346 
04347     if (xsd != NULL) {
04348     xmlSchemaParserCtxtPtr pctxt;
04349     /* Parse the schema and create validation environment. */
04350     pctxt = xmlSchemaNewParserCtxt(xsd);
04351     if (reader->errorFunc != NULL) {
04352         xmlSchemaSetParserErrors(pctxt,
04353         xmlTextReaderValidityErrorRelay,
04354         xmlTextReaderValidityWarningRelay,
04355         reader);
04356     }
04357     reader->xsdSchemas = xmlSchemaParse(pctxt);
04358     xmlSchemaFreeParserCtxt(pctxt);
04359     if (reader->xsdSchemas == NULL)
04360         return(-1);
04361     reader->xsdValidCtxt = xmlSchemaNewValidCtxt(reader->xsdSchemas);
04362     if (reader->xsdValidCtxt == NULL) {
04363         xmlSchemaFree(reader->xsdSchemas);
04364         reader->xsdSchemas = NULL;
04365         return(-1);
04366     }
04367     reader->xsdPlug = xmlSchemaSAXPlug(reader->xsdValidCtxt,
04368         &(reader->ctxt->sax),
04369         &(reader->ctxt->userData));
04370     if (reader->xsdPlug == NULL) {
04371         xmlSchemaFree(reader->xsdSchemas);
04372         reader->xsdSchemas = NULL;
04373         xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
04374         reader->xsdValidCtxt = NULL;
04375         return(-1);
04376     }
04377     } else {
04378     /* Use the given validation context. */
04379     reader->xsdValidCtxt = ctxt;
04380     reader->xsdPreserveCtxt = 1;
04381     reader->xsdPlug = xmlSchemaSAXPlug(reader->xsdValidCtxt,
04382         &(reader->ctxt->sax),
04383         &(reader->ctxt->userData));
04384     if (reader->xsdPlug == NULL) {
04385         reader->xsdValidCtxt = NULL;
04386         reader->xsdPreserveCtxt = 0;
04387         return(-1);
04388     }
04389     }
04390     /*
04391     * Redirect the validation context's error channels to use
04392     * the reader channels.
04393     * TODO: In case the user provides the validation context we
04394     *   could make this redirection optional.
04395     */
04396     if (reader->errorFunc != NULL) {
04397     xmlSchemaSetValidErrors(reader->xsdValidCtxt,
04398              xmlTextReaderValidityErrorRelay,
04399              xmlTextReaderValidityWarningRelay,
04400              reader);
04401     }
04402     if (reader->sErrorFunc != NULL) {
04403         xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt,
04404             xmlTextReaderValidityStructuredRelay,
04405             reader);
04406     }
04407     reader->xsdValidErrors = 0;
04408     reader->validate = XML_TEXTREADER_VALIDATE_XSD;
04409     return(0);
04410 }
04411 
04425 int
04426 xmlTextReaderSchemaValidateCtxt(xmlTextReaderPtr reader,
04427                     xmlSchemaValidCtxtPtr ctxt,
04428                     int options)
04429 {
04430     return(xmlTextReaderSchemaValidateInternal(reader, NULL, ctxt, options));
04431 }
04432 
04445 int
04446 xmlTextReaderSchemaValidate(xmlTextReaderPtr reader, const char *xsd)
04447 {
04448     return(xmlTextReaderSchemaValidateInternal(reader, xsd, NULL, 0));
04449 }
04450 #endif
04451 
04463 int
04464 xmlTextReaderIsNamespaceDecl(xmlTextReaderPtr reader) {
04465     xmlNodePtr node;
04466     if (reader == NULL)
04467     return(-1);
04468     if (reader->node == NULL)
04469     return(-1);
04470     if (reader->curnode != NULL)
04471     node = reader->curnode;
04472     else
04473     node = reader->node;
04474 
04475     if (XML_NAMESPACE_DECL == node->type)
04476     return(1);
04477     else
04478     return(0);
04479 }
04480 
04490 const xmlChar *
04491 xmlTextReaderConstXmlVersion(xmlTextReaderPtr reader) {
04492     xmlDocPtr doc = NULL;
04493     if (reader == NULL)
04494     return(NULL);
04495     if (reader->doc != NULL)
04496         doc = reader->doc;
04497     else if (reader->ctxt != NULL)
04498     doc = reader->ctxt->myDoc;
04499     if (doc == NULL)
04500     return(NULL);
04501 
04502     if (doc->version == NULL)
04503     return(NULL);
04504     else
04505       return(CONSTSTR(doc->version));
04506 }
04507 
04518 int
04519 xmlTextReaderStandalone(xmlTextReaderPtr reader) {
04520     xmlDocPtr doc = NULL;
04521     if (reader == NULL)
04522     return(-1);
04523     if (reader->doc != NULL)
04524         doc = reader->doc;
04525     else if (reader->ctxt != NULL)
04526     doc = reader->ctxt->myDoc;
04527     if (doc == NULL)
04528     return(-1);
04529 
04530     return(doc->standalone);
04531 }
04532 
04533 /************************************************************************
04534  *                                  *
04535  *          Error Handling Extensions                       *
04536  *                                  *
04537  ************************************************************************/
04538 
04539 /* helper to build a xmlMalloc'ed string from a format and va_list */
04540 static char *
04541 xmlTextReaderBuildMessage(const char *msg, va_list ap) {
04542     int size = 0;
04543     int chars;
04544     char *larger;
04545     char *str = NULL;
04546     va_list aq;
04547 
04548     while (1) {
04549         VA_COPY(aq, ap);
04550         chars = vsnprintf(str, size, msg, aq);
04551         va_end(aq);
04552         if (chars < 0) {
04553         xmlGenericError(xmlGenericErrorContext, "vsnprintf failed !\n");
04554         if (str)
04555         xmlFree(str);
04556         return NULL;
04557     }
04558     if ((chars < size) || (size == MAX_ERR_MSG_SIZE))
04559             break;
04560         if (chars < MAX_ERR_MSG_SIZE)
04561     size = chars + 1;
04562     else
04563         size = MAX_ERR_MSG_SIZE;
04564         if ((larger = (char *) xmlRealloc(str, size)) == NULL) {
04565         xmlGenericError(xmlGenericErrorContext, "xmlRealloc failed !\n");
04566         if (str)
04567                 xmlFree(str);
04568             return NULL;
04569         }
04570         str = larger;
04571     }
04572 
04573     return str;
04574 }
04575 
04584 int
04585 xmlTextReaderLocatorLineNumber(xmlTextReaderLocatorPtr locator) {
04586     /* we know that locator is a xmlParserCtxtPtr */
04587     xmlParserCtxtPtr ctx = (xmlParserCtxtPtr)locator;
04588     int ret = -1;
04589 
04590     if (locator == NULL)
04591         return(-1);
04592     if (ctx->node != NULL) {
04593     ret = xmlGetLineNo(ctx->node);
04594     }
04595     else {
04596     /* inspired from error.c */
04597     xmlParserInputPtr input;
04598     input = ctx->input;
04599     if ((input->filename == NULL) && (ctx->inputNr > 1))
04600         input = ctx->inputTab[ctx->inputNr - 2];
04601     if (input != NULL) {
04602         ret = input->line;
04603     }
04604     else {
04605         ret = -1;
04606     }
04607     }
04608 
04609     return ret;
04610 }
04611 
04621 xmlChar *
04622 xmlTextReaderLocatorBaseURI(xmlTextReaderLocatorPtr locator) {
04623     /* we know that locator is a xmlParserCtxtPtr */
04624     xmlParserCtxtPtr ctx = (xmlParserCtxtPtr)locator;
04625     xmlChar *ret = NULL;
04626 
04627     if (locator == NULL)
04628         return(NULL);
04629     if (ctx->node != NULL) {
04630     ret = xmlNodeGetBase(NULL,ctx->node);
04631     }
04632     else {
04633     /* inspired from error.c */
04634     xmlParserInputPtr input;
04635     input = ctx->input;
04636     if ((input->filename == NULL) && (ctx->inputNr > 1))
04637         input = ctx->inputTab[ctx->inputNr - 2];
04638     if (input != NULL) {
04639         ret = xmlStrdup(BAD_CAST input->filename);
04640     }
04641     else {
04642         ret = NULL;
04643     }
04644     }
04645 
04646     return ret;
04647 }
04648 
04649 static void
04650 xmlTextReaderGenericError(void *ctxt, xmlParserSeverities severity,
04651                           char *str)
04652 {
04653     xmlParserCtxtPtr ctx = (xmlParserCtxtPtr) ctxt;
04654 
04655     xmlTextReaderPtr reader = (xmlTextReaderPtr) ctx->_private;
04656 
04657     if (str != NULL) {
04658         if (reader->errorFunc)
04659             reader->errorFunc(reader->errorFuncArg, str, severity,
04660                               (xmlTextReaderLocatorPtr) ctx);
04661         xmlFree(str);
04662     }
04663 }
04664 
04665 static void
04666 xmlTextReaderStructuredError(void *ctxt, xmlErrorPtr error)
04667 {
04668     xmlParserCtxtPtr ctx = (xmlParserCtxtPtr) ctxt;
04669 
04670     xmlTextReaderPtr reader = (xmlTextReaderPtr) ctx->_private;
04671 
04672     if (error && reader->sErrorFunc) {
04673         reader->sErrorFunc(reader->errorFuncArg, (xmlErrorPtr) error);
04674     }
04675 }
04676 
04677 static void XMLCDECL
04678 xmlTextReaderError(void *ctxt, const char *msg, ...)
04679 {
04680     va_list ap;
04681 
04682     va_start(ap, msg);
04683     xmlTextReaderGenericError(ctxt,
04684                               XML_PARSER_SEVERITY_ERROR,
04685                               xmlTextReaderBuildMessage(msg, ap));
04686     va_end(ap);
04687 
04688 }
04689 
04690 static void XMLCDECL
04691 xmlTextReaderWarning(void *ctxt, const char *msg, ...)
04692 {
04693     va_list ap;
04694 
04695     va_start(ap, msg);
04696     xmlTextReaderGenericError(ctxt,
04697                               XML_PARSER_SEVERITY_WARNING,
04698                               xmlTextReaderBuildMessage(msg, ap));
04699     va_end(ap);
04700 }
04701 
04702 static void XMLCDECL
04703 xmlTextReaderValidityError(void *ctxt, const char *msg, ...)
04704 {
04705     va_list ap;
04706 
04707     int len = xmlStrlen((const xmlChar *) msg);
04708 
04709     if ((len > 1) && (msg[len - 2] != ':')) {
04710         /*
04711          * some callbacks only report locator information:
04712          * skip them (mimicking behaviour in error.c)
04713          */
04714         va_start(ap, msg);
04715         xmlTextReaderGenericError(ctxt,
04716                                   XML_PARSER_SEVERITY_VALIDITY_ERROR,
04717                                   xmlTextReaderBuildMessage(msg, ap));
04718         va_end(ap);
04719     }
04720 }
04721 
04722 static void XMLCDECL
04723 xmlTextReaderValidityWarning(void *ctxt, const char *msg, ...)
04724 {
04725     va_list ap;
04726 
04727     int len = xmlStrlen((const xmlChar *) msg);
04728 
04729     if ((len != 0) && (msg[len - 1] != ':')) {
04730         /*
04731          * some callbacks only report locator information:
04732          * skip them (mimicking behaviour in error.c)
04733          */
04734         va_start(ap, msg);
04735         xmlTextReaderGenericError(ctxt,
04736                                   XML_PARSER_SEVERITY_VALIDITY_WARNING,
04737                                   xmlTextReaderBuildMessage(msg, ap));
04738         va_end(ap);
04739     }
04740 }
04741 
04752 void
04753 xmlTextReaderSetErrorHandler(xmlTextReaderPtr reader,
04754                              xmlTextReaderErrorFunc f, void *arg)
04755 {
04756     if (f != NULL) {
04757         reader->ctxt->sax->error = xmlTextReaderError;
04758         reader->ctxt->sax->serror = NULL;
04759         reader->ctxt->vctxt.error = xmlTextReaderValidityError;
04760         reader->ctxt->sax->warning = xmlTextReaderWarning;
04761         reader->ctxt->vctxt.warning = xmlTextReaderValidityWarning;
04762         reader->errorFunc = f;
04763         reader->sErrorFunc = NULL;
04764         reader->errorFuncArg = arg;
04765 #ifdef LIBXML_SCHEMAS_ENABLED
04766         if (reader->rngValidCtxt) {
04767             xmlRelaxNGSetValidErrors(reader->rngValidCtxt,
04768                                      xmlTextReaderValidityErrorRelay,
04769                                      xmlTextReaderValidityWarningRelay,
04770                                      reader);
04771             xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt, NULL,
04772                                                reader);
04773         }
04774         if (reader->xsdValidCtxt) {
04775             xmlSchemaSetValidErrors(reader->xsdValidCtxt,
04776                                     xmlTextReaderValidityErrorRelay,
04777                                     xmlTextReaderValidityWarningRelay,
04778                                     reader);
04779             xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt, NULL,
04780                                               reader);
04781         }
04782 #endif
04783     } else {
04784         /* restore defaults */
04785         reader->ctxt->sax->error = xmlParserError;
04786         reader->ctxt->vctxt.error = xmlParserValidityError;
04787         reader->ctxt->sax->warning = xmlParserWarning;
04788         reader->ctxt->vctxt.warning = xmlParserValidityWarning;
04789         reader->errorFunc = NULL;
04790         reader->sErrorFunc = NULL;
04791         reader->errorFuncArg = NULL;
04792 #ifdef LIBXML_SCHEMAS_ENABLED
04793         if (reader->rngValidCtxt) {
04794             xmlRelaxNGSetValidErrors(reader->rngValidCtxt, NULL, NULL,
04795                                      reader);
04796             xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt, NULL,
04797                                                reader);
04798         }
04799         if (reader->xsdValidCtxt) {
04800             xmlSchemaSetValidErrors(reader->xsdValidCtxt, NULL, NULL,
04801                                     reader);
04802             xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt, NULL,
04803                                               reader);
04804         }
04805 #endif
04806     }
04807 }
04808 
04819 void
04820 xmlTextReaderSetStructuredErrorHandler(xmlTextReaderPtr reader,
04821                                        xmlStructuredErrorFunc f, void *arg)
04822 {
04823     if (f != NULL) {
04824         reader->ctxt->sax->error = NULL;
04825         reader->ctxt->sax->serror = xmlTextReaderStructuredError;
04826         reader->ctxt->vctxt.error = xmlTextReaderValidityError;
04827         reader->ctxt->sax->warning = xmlTextReaderWarning;
04828         reader->ctxt->vctxt.warning = xmlTextReaderValidityWarning;
04829         reader->sErrorFunc = f;
04830         reader->errorFunc = NULL;
04831         reader->errorFuncArg = arg;
04832 #ifdef LIBXML_SCHEMAS_ENABLED
04833         if (reader->rngValidCtxt) {
04834             xmlRelaxNGSetValidErrors(reader->rngValidCtxt, NULL, NULL,
04835                                      reader);
04836             xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,
04837                                         xmlTextReaderValidityStructuredRelay,
04838                                                reader);
04839         }
04840         if (reader->xsdValidCtxt) {
04841             xmlSchemaSetValidErrors(reader->xsdValidCtxt, NULL, NULL,
04842                                     reader);
04843             xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt,
04844                                        xmlTextReaderValidityStructuredRelay,
04845                                               reader);
04846         }
04847 #endif
04848     } else {
04849         /* restore defaults */
04850         reader->ctxt->sax->error = xmlParserError;
04851         reader->ctxt->sax->serror = NULL;
04852         reader->ctxt->vctxt.error = xmlParserValidityError;
04853         reader->ctxt->sax->warning = xmlParserWarning;
04854         reader->ctxt->vctxt.warning = xmlParserValidityWarning;
04855         reader->errorFunc = NULL;
04856         reader->sErrorFunc = NULL;
04857         reader->errorFuncArg = NULL;
04858 #ifdef LIBXML_SCHEMAS_ENABLED
04859         if (reader->rngValidCtxt) {
04860             xmlRelaxNGSetValidErrors(reader->rngValidCtxt, NULL, NULL,
04861                                      reader);
04862             xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt, NULL,
04863                                                reader);
04864         }
04865         if (reader->xsdValidCtxt) {
04866             xmlSchemaSetValidErrors(reader->xsdValidCtxt, NULL, NULL,
04867                                     reader);
04868             xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt, NULL,
04869                                               reader);
04870         }
04871 #endif
04872     }
04873 }
04874 
04883 int
04884 xmlTextReaderIsValid(xmlTextReaderPtr reader)
04885 {
04886     if (reader == NULL)
04887         return (-1);
04888 #ifdef LIBXML_SCHEMAS_ENABLED
04889     if (reader->validate == XML_TEXTREADER_VALIDATE_RNG)
04890         return (reader->rngValidErrors == 0);
04891     if (reader->validate == XML_TEXTREADER_VALIDATE_XSD)
04892         return (reader->xsdValidErrors == 0);
04893 #endif
04894     if ((reader->ctxt != NULL) && (reader->ctxt->validate == 1))
04895         return (reader->ctxt->valid);
04896     return (0);
04897 }
04898 
04907 void
04908 xmlTextReaderGetErrorHandler(xmlTextReaderPtr reader,
04909                              xmlTextReaderErrorFunc * f, void **arg)
04910 {
04911     if (f != NULL)
04912         *f = reader->errorFunc;
04913     if (arg != NULL)
04914         *arg = reader->errorFuncArg;
04915 }
04916 /************************************************************************
04917  *                                  *
04918  *  New set (2.6.0) of simpler and more flexible APIs       *
04919  *                                  *
04920  ************************************************************************/
04921 
04935 int
04936 xmlTextReaderSetup(xmlTextReaderPtr reader,
04937                    xmlParserInputBufferPtr input, const char *URL,
04938                    const char *encoding, int options)
04939 {
04940     if (reader == NULL) {
04941         if (input != NULL)
04942         xmlFreeParserInputBuffer(input);
04943         return (-1);
04944     }
04945 
04946     /*
04947      * we force the generation of compact text nodes on the reader
04948      * since usr applications should never modify the tree
04949      */
04950     options |= XML_PARSE_COMPACT;
04951 
04952     reader->doc = NULL;
04953     reader->entNr = 0;
04954     reader->parserFlags = options;
04955     reader->validate = XML_TEXTREADER_NOT_VALIDATE;
04956     if ((input != NULL) && (reader->input != NULL) &&
04957         (reader->allocs & XML_TEXTREADER_INPUT)) {
04958     xmlFreeParserInputBuffer(reader->input);
04959     reader->input = NULL;
04960     reader->allocs -= XML_TEXTREADER_INPUT;
04961     }
04962     if (input != NULL) {
04963     reader->input = input;
04964     reader->allocs |= XML_TEXTREADER_INPUT;
04965     }
04966     if (reader->buffer == NULL)
04967         reader->buffer = xmlBufferCreateSize(100);
04968     if (reader->buffer == NULL) {
04969         xmlGenericError(xmlGenericErrorContext,
04970                         "xmlTextReaderSetup : malloc failed\n");
04971         return (-1);
04972     }
04973     if (reader->sax == NULL)
04974     reader->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
04975     if (reader->sax == NULL) {
04976         xmlGenericError(xmlGenericErrorContext,
04977                         "xmlTextReaderSetup : malloc failed\n");
04978         return (-1);
04979     }
04980     xmlSAXVersion(reader->sax, 2);
04981     reader->startElement = reader->sax->startElement;
04982     reader->sax->startElement = xmlTextReaderStartElement;
04983     reader->endElement = reader->sax->endElement;
04984     reader->sax->endElement = xmlTextReaderEndElement;
04985 #ifdef LIBXML_SAX1_ENABLED
04986     if (reader->sax->initialized == XML_SAX2_MAGIC) {
04987 #endif /* LIBXML_SAX1_ENABLED */
04988         reader->startElementNs = reader->sax->startElementNs;
04989         reader->sax->startElementNs = xmlTextReaderStartElementNs;
04990         reader->endElementNs = reader->sax->endElementNs;
04991         reader->sax->endElementNs = xmlTextReaderEndElementNs;
04992 #ifdef LIBXML_SAX1_ENABLED
04993     } else {
04994         reader->startElementNs = NULL;
04995         reader->endElementNs = NULL;
04996     }
04997 #endif /* LIBXML_SAX1_ENABLED */
04998     reader->characters = reader->sax->characters;
04999     reader->sax->characters = xmlTextReaderCharacters;
05000     reader->sax->ignorableWhitespace = xmlTextReaderCharacters;
05001     reader->cdataBlock = reader->sax->cdataBlock;
05002     reader->sax->cdataBlock = xmlTextReaderCDataBlock;
05003 
05004     reader->mode = XML_TEXTREADER_MODE_INITIAL;
05005     reader->node = NULL;
05006     reader->curnode = NULL;
05007     if (input != NULL) {
05008         if (reader->input->buffer->use < 4) {
05009             xmlParserInputBufferRead(input, 4);
05010         }
05011         if (reader->ctxt == NULL) {
05012             if (reader->input->buffer->use >= 4) {
05013                 reader->ctxt = xmlCreatePushParserCtxt(reader->sax, NULL,
05014                (const char *) reader->input->buffer->content, 4, URL);
05015                 reader->base = 0;
05016                 reader->cur = 4;
05017             } else {
05018                 reader->ctxt =
05019                     xmlCreatePushParserCtxt(reader->sax, NULL, NULL, 0, URL);
05020                 reader->base = 0;
05021                 reader->cur = 0;
05022             }
05023         } else {
05024         xmlParserInputPtr inputStream;
05025         xmlParserInputBufferPtr buf;
05026         xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
05027 
05028         xmlCtxtReset(reader->ctxt);
05029         buf = xmlAllocParserInputBuffer(enc);
05030         if (buf == NULL) return(-1);
05031         inputStream = xmlNewInputStream(reader->ctxt);
05032         if (inputStream == NULL) {
05033         xmlFreeParserInputBuffer(buf);
05034         return(-1);
05035         }
05036 
05037         if (URL == NULL)
05038         inputStream->filename = NULL;
05039         else
05040         inputStream->filename = (char *)
05041             xmlCanonicPath((const xmlChar *) URL);
05042         inputStream->buf = buf;
05043         inputStream->base = inputStream->buf->buffer->content;
05044         inputStream->cur = inputStream->buf->buffer->content;
05045         inputStream->end =
05046             &inputStream->buf->buffer->content[inputStream->buf->buffer->use];
05047 
05048         inputPush(reader->ctxt, inputStream);
05049         reader->cur = 0;
05050     }
05051         if (reader->ctxt == NULL) {
05052             xmlGenericError(xmlGenericErrorContext,
05053                             "xmlTextReaderSetup : malloc failed\n");
05054             return (-1);
05055         }
05056     }
05057     if (reader->dict != NULL) {
05058         if (reader->ctxt->dict != NULL) {
05059         if (reader->dict != reader->ctxt->dict) {
05060         xmlDictFree(reader->dict);
05061         reader->dict = reader->ctxt->dict;
05062         }
05063     } else {
05064         reader->ctxt->dict = reader->dict;
05065     }
05066     } else {
05067     if (reader->ctxt->dict == NULL)
05068         reader->ctxt->dict = xmlDictCreate();
05069         reader->dict = reader->ctxt->dict;
05070     }
05071     reader->ctxt->_private = reader;
05072     reader->ctxt->linenumbers = 1;
05073     reader->ctxt->dictNames = 1;
05074     /*
05075      * use the parser dictionnary to allocate all elements and attributes names
05076      */
05077     reader->ctxt->docdict = 1;
05078     reader->ctxt->parseMode = XML_PARSE_READER;
05079 
05080 #ifdef LIBXML_XINCLUDE_ENABLED
05081     if (reader->xincctxt != NULL) {
05082     xmlXIncludeFreeContext(reader->xincctxt);
05083     reader->xincctxt = NULL;
05084     }
05085     if (options & XML_PARSE_XINCLUDE) {
05086         reader->xinclude = 1;
05087     reader->xinclude_name = xmlDictLookup(reader->dict, XINCLUDE_NODE, -1);
05088     options -= XML_PARSE_XINCLUDE;
05089     } else
05090         reader->xinclude = 0;
05091     reader->in_xinclude = 0;
05092 #endif
05093 #ifdef LIBXML_PATTERN_ENABLED
05094     if (reader->patternTab == NULL) {
05095         reader->patternNr = 0;
05096     reader->patternMax = 0;
05097     }
05098     while (reader->patternNr > 0) {
05099         reader->patternNr--;
05100     if (reader->patternTab[reader->patternNr] != NULL) {
05101         xmlFreePattern(reader->patternTab[reader->patternNr]);
05102             reader->patternTab[reader->patternNr] = NULL;
05103     }
05104     }
05105 #endif
05106 
05107     if (options & XML_PARSE_DTDVALID)
05108         reader->validate = XML_TEXTREADER_VALIDATE_DTD;
05109 
05110     xmlCtxtUseOptions(reader->ctxt, options);
05111     if (encoding != NULL) {
05112         xmlCharEncodingHandlerPtr hdlr;
05113 
05114         hdlr = xmlFindCharEncodingHandler(encoding);
05115         if (hdlr != NULL)
05116             xmlSwitchToEncoding(reader->ctxt, hdlr);
05117     }
05118     if ((URL != NULL) && (reader->ctxt->input != NULL) &&
05119         (reader->ctxt->input->filename == NULL))
05120         reader->ctxt->input->filename = (char *)
05121             xmlStrdup((const xmlChar *) URL);
05122 
05123     reader->doc = NULL;
05124 
05125     return (0);
05126 }
05127 
05141 long
05142 xmlTextReaderByteConsumed(xmlTextReaderPtr reader) {
05143     if ((reader == NULL) || (reader->ctxt == NULL))
05144         return(-1);
05145     return(xmlByteConsumed(reader->ctxt));
05146 }
05147 
05148 
05157 xmlTextReaderPtr
05158 xmlReaderWalker(xmlDocPtr doc)
05159 {
05160     xmlTextReaderPtr ret;
05161 
05162     if (doc == NULL)
05163         return(NULL);
05164 
05165     ret = xmlMalloc(sizeof(xmlTextReader));
05166     if (ret == NULL) {
05167         xmlGenericError(xmlGenericErrorContext,
05168         "xmlNewTextReader : malloc failed\n");
05169     return(NULL);
05170     }
05171     memset(ret, 0, sizeof(xmlTextReader));
05172     ret->entNr = 0;
05173     ret->input = NULL;
05174     ret->mode = XML_TEXTREADER_MODE_INITIAL;
05175     ret->node = NULL;
05176     ret->curnode = NULL;
05177     ret->base = 0;
05178     ret->cur = 0;
05179     ret->allocs = XML_TEXTREADER_CTXT;
05180     ret->doc = doc;
05181     ret->state = XML_TEXTREADER_START;
05182     ret->dict = xmlDictCreate();
05183     return(ret);
05184 }
05185 
05198 xmlTextReaderPtr
05199 xmlReaderForDoc(const xmlChar * cur, const char *URL, const char *encoding,
05200                 int options)
05201 {
05202     int len;
05203 
05204     if (cur == NULL)
05205         return (NULL);
05206     len = xmlStrlen(cur);
05207 
05208     return (xmlReaderForMemory
05209             ((const char *) cur, len, URL, encoding, options));
05210 }
05211 
05223 xmlTextReaderPtr
05224 xmlReaderForFile(const char *filename, const char *encoding, int options)
05225 {
05226     xmlTextReaderPtr reader;
05227 
05228     reader = xmlNewTextReaderFilename(filename);
05229     if (reader == NULL)
05230         return (NULL);
05231     xmlTextReaderSetup(reader, NULL, NULL, encoding, options);
05232     return (reader);
05233 }
05234 
05248 xmlTextReaderPtr
05249 xmlReaderForMemory(const char *buffer, int size, const char *URL,
05250                    const char *encoding, int options)
05251 {
05252     xmlTextReaderPtr reader;
05253     xmlParserInputBufferPtr buf;
05254 
05255     buf = xmlParserInputBufferCreateStatic(buffer, size,
05256                                       XML_CHAR_ENCODING_NONE);
05257     if (buf == NULL) {
05258         return (NULL);
05259     }
05260     reader = xmlNewTextReader(buf, URL);
05261     if (reader == NULL) {
05262         xmlFreeParserInputBuffer(buf);
05263         return (NULL);
05264     }
05265     reader->allocs |= XML_TEXTREADER_INPUT;
05266     xmlTextReaderSetup(reader, NULL, URL, encoding, options);
05267     return (reader);
05268 }
05269 
05284 xmlTextReaderPtr
05285 xmlReaderForFd(int fd, const char *URL, const char *encoding, int options)
05286 {
05287     xmlTextReaderPtr reader;
05288     xmlParserInputBufferPtr input;
05289 
05290     if (fd < 0)
05291         return (NULL);
05292 
05293     input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
05294     if (input == NULL)
05295         return (NULL);
05296     input->closecallback = NULL;
05297     reader = xmlNewTextReader(input, URL);
05298     if (reader == NULL) {
05299         xmlFreeParserInputBuffer(input);
05300         return (NULL);
05301     }
05302     reader->allocs |= XML_TEXTREADER_INPUT;
05303     xmlTextReaderSetup(reader, NULL, URL, encoding, options);
05304     return (reader);
05305 }
05306 
05321 xmlTextReaderPtr
05322 xmlReaderForIO(xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
05323                void *ioctx, const char *URL, const char *encoding,
05324                int options)
05325 {
05326     xmlTextReaderPtr reader;
05327     xmlParserInputBufferPtr input;
05328 
05329     if (ioread == NULL)
05330         return (NULL);
05331 
05332     input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
05333                                          XML_CHAR_ENCODING_NONE);
05334     if (input == NULL)
05335         return (NULL);
05336     reader = xmlNewTextReader(input, URL);
05337     if (reader == NULL) {
05338         xmlFreeParserInputBuffer(input);
05339         return (NULL);
05340     }
05341     reader->allocs |= XML_TEXTREADER_INPUT;
05342     xmlTextReaderSetup(reader, NULL, URL, encoding, options);
05343     return (reader);
05344 }
05345 
05356 int
05357 xmlReaderNewWalker(xmlTextReaderPtr reader, xmlDocPtr doc)
05358 {
05359     if (doc == NULL)
05360         return (-1);
05361     if (reader == NULL)
05362         return (-1);
05363 
05364     if (reader->input != NULL) {
05365         xmlFreeParserInputBuffer(reader->input);
05366     }
05367     if (reader->ctxt != NULL) {
05368     xmlCtxtReset(reader->ctxt);
05369     }
05370 
05371     reader->entNr = 0;
05372     reader->input = NULL;
05373     reader->mode = XML_TEXTREADER_MODE_INITIAL;
05374     reader->node = NULL;
05375     reader->curnode = NULL;
05376     reader->base = 0;
05377     reader->cur = 0;
05378     reader->allocs = XML_TEXTREADER_CTXT;
05379     reader->doc = doc;
05380     reader->state = XML_TEXTREADER_START;
05381     if (reader->dict == NULL) {
05382         if ((reader->ctxt != NULL) && (reader->ctxt->dict != NULL))
05383         reader->dict = reader->ctxt->dict;
05384     else
05385         reader->dict = xmlDictCreate();
05386     }
05387     return(0);
05388 }
05389 
05404 int
05405 xmlReaderNewDoc(xmlTextReaderPtr reader, const xmlChar * cur,
05406                 const char *URL, const char *encoding, int options)
05407 {
05408 
05409     int len;
05410 
05411     if (cur == NULL)
05412         return (-1);
05413     if (reader == NULL)
05414         return (-1);
05415 
05416     len = xmlStrlen(cur);
05417     return (xmlReaderNewMemory(reader, (const char *)cur, len,
05418                                URL, encoding, options));
05419 }
05420 
05434 int
05435 xmlReaderNewFile(xmlTextReaderPtr reader, const char *filename,
05436                  const char *encoding, int options)
05437 {
05438     xmlParserInputBufferPtr input;
05439 
05440     if (filename == NULL)
05441         return (-1);
05442     if (reader == NULL)
05443         return (-1);
05444 
05445     input =
05446         xmlParserInputBufferCreateFilename(filename,
05447                                            XML_CHAR_ENCODING_NONE);
05448     if (input == NULL)
05449         return (-1);
05450     return (xmlTextReaderSetup(reader, input, filename, encoding, options));
05451 }
05452 
05468 int
05469 xmlReaderNewMemory(xmlTextReaderPtr reader, const char *buffer, int size,
05470                    const char *URL, const char *encoding, int options)
05471 {
05472     xmlParserInputBufferPtr input;
05473 
05474     if (reader == NULL)
05475         return (-1);
05476     if (buffer == NULL)
05477         return (-1);
05478 
05479     input = xmlParserInputBufferCreateStatic(buffer, size,
05480                                       XML_CHAR_ENCODING_NONE);
05481     if (input == NULL) {
05482         return (-1);
05483     }
05484     return (xmlTextReaderSetup(reader, input, URL, encoding, options));
05485 }
05486 
05503 int
05504 xmlReaderNewFd(xmlTextReaderPtr reader, int fd,
05505                const char *URL, const char *encoding, int options)
05506 {
05507     xmlParserInputBufferPtr input;
05508 
05509     if (fd < 0)
05510         return (-1);
05511     if (reader == NULL)
05512         return (-1);
05513 
05514     input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
05515     if (input == NULL)
05516         return (-1);
05517     input->closecallback = NULL;
05518     return (xmlTextReaderSetup(reader, input, URL, encoding, options));
05519 }
05520 
05538 int
05539 xmlReaderNewIO(xmlTextReaderPtr reader, xmlInputReadCallback ioread,
05540                xmlInputCloseCallback ioclose, void *ioctx,
05541                const char *URL, const char *encoding, int options)
05542 {
05543     xmlParserInputBufferPtr input;
05544 
05545     if (ioread == NULL)
05546         return (-1);
05547     if (reader == NULL)
05548         return (-1);
05549 
05550     input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
05551                                          XML_CHAR_ENCODING_NONE);
05552     if (input == NULL)
05553         return (-1);
05554     return (xmlTextReaderSetup(reader, input, URL, encoding, options));
05555 }
05556 /************************************************************************
05557  *                                  *
05558  *          Utilities                   *
05559  *                                  *
05560  ************************************************************************/
05561 #ifdef NOT_USED_YET
05562 
05576 static int
05577 xmlBase64Decode(const unsigned char *in, unsigned long *inlen,
05578                 unsigned char *to, unsigned long *tolen)
05579 {
05580     unsigned long incur;        /* current index in in[] */
05581 
05582     unsigned long inblk;        /* last block index in in[] */
05583 
05584     unsigned long outcur;       /* current index in out[] */
05585 
05586     unsigned long inmax;        /* size of in[] */
05587 
05588     unsigned long outmax;       /* size of out[] */
05589 
05590     unsigned char cur;          /* the current value read from in[] */
05591 
05592     unsigned char intmp[4], outtmp[4];  /* temporary buffers for the convert */
05593 
05594     int nbintmp;                /* number of byte in intmp[] */
05595 
05596     int is_ignore;              /* cur should be ignored */
05597 
05598     int is_end = 0;             /* the end of the base64 was found */
05599 
05600     int retval = 1;
05601 
05602     int i;
05603 
05604     if ((in == NULL) || (inlen == NULL) || (to == NULL) || (tolen == NULL))
05605         return (-1);
05606 
05607     incur = 0;
05608     inblk = 0;
05609     outcur = 0;
05610     inmax = *inlen;
05611     outmax = *tolen;
05612     nbintmp = 0;
05613 
05614     while (1) {
05615         if (incur >= inmax)
05616             break;
05617         cur = in[incur++];
05618         is_ignore = 0;
05619         if ((cur >= 'A') && (cur <= 'Z'))
05620             cur = cur - 'A';
05621         else if ((cur >= 'a') && (cur <= 'z'))
05622             cur = cur - 'a' + 26;
05623         else if ((cur >= '0') && (cur <= '9'))
05624             cur = cur - '0' + 52;
05625         else if (cur == '+')
05626             cur = 62;
05627         else if (cur == '/')
05628             cur = 63;
05629         else if (cur == '.')
05630             cur = 0;
05631         else if (cur == '=')    /*no op , end of the base64 stream */
05632             is_end = 1;
05633         else {
05634             is_ignore = 1;
05635             if (nbintmp == 0)
05636                 inblk = incur;
05637         }
05638 
05639         if (!is_ignore) {
05640             int nbouttmp = 3;
05641 
05642             int is_break = 0;
05643 
05644             if (is_end) {
05645                 if (nbintmp == 0)
05646                     break;
05647                 if ((nbintmp == 1) || (nbintmp == 2))
05648                     nbouttmp = 1;
05649                 else
05650                     nbouttmp = 2;
05651                 nbintmp = 3;
05652                 is_break = 1;
05653             }
05654             intmp[nbintmp++] = cur;
05655             /*
05656              * if intmp is full, push the 4byte sequence as a 3 byte
05657              * sequence out
05658              */
05659             if (nbintmp == 4) {
05660                 nbintmp = 0;
05661                 outtmp[0] = (intmp[0] << 2) | ((intmp[1] & 0x30) >> 4);
05662                 outtmp[1] =
05663                     ((intmp[1] & 0x0F) << 4) | ((intmp[2] & 0x3C) >> 2);
05664                 outtmp[2] = ((intmp[2] & 0x03) << 6) | (intmp[3] & 0x3F);
05665                 if (outcur + 3 >= outmax) {
05666                     retval = 2;
05667                     break;
05668                 }
05669 
05670                 for (i = 0; i < nbouttmp; i++)
05671                     to[outcur++] = outtmp[i];
05672                 inblk = incur;
05673             }
05674 
05675             if (is_break) {
05676                 retval = 0;
05677                 break;
05678             }
05679         }
05680     }
05681 
05682     *tolen = outcur;
05683     *inlen = inblk;
05684     return (retval);
05685 }
05686 
05687 /*
05688  * Test routine for the xmlBase64Decode function
05689  */
05690 #if 0
05691 int
05692 main(int argc, char **argv)
05693 {
05694     char *input = "  VW4 gcGV0        \n      aXQgdGVzdCAuCg== ";
05695 
05696     char output[100];
05697 
05698     char output2[100];
05699 
05700     char output3[100];
05701 
05702     unsigned long inlen = strlen(input);
05703 
05704     unsigned long outlen = 100;
05705 
05706     int ret;
05707 
05708     unsigned long cons, tmp, tmp2, prod;
05709 
05710     /*
05711      * Direct
05712      */
05713     ret = xmlBase64Decode(input, &inlen, output, &outlen);
05714 
05715     output[outlen] = 0;
05716     printf("ret: %d, inlen: %ld , outlen: %ld, output: '%s'\n", ret, inlen,
05717            outlen, output)indent: Standard input:179: Error:Unmatched #endif
05718 ;
05719 
05720     /*
05721      * output chunking
05722      */
05723     cons = 0;
05724     prod = 0;
05725     while (cons < inlen) {
05726         tmp = 5;
05727         tmp2 = inlen - cons;
05728 
05729         printf("%ld %ld\n", cons, prod);
05730         ret = xmlBase64Decode(&input[cons], &tmp2, &output2[prod], &tmp);
05731         cons += tmp2;
05732         prod += tmp;
05733         printf("%ld %ld\n", cons, prod);
05734     }
05735     output2[outlen] = 0;
05736     printf("ret: %d, cons: %ld , prod: %ld, output: '%s'\n", ret, cons,
05737            prod, output2);
05738 
05739     /*
05740      * input chunking
05741      */
05742     cons = 0;
05743     prod = 0;
05744     while (cons < inlen) {
05745         tmp = 100 - prod;
05746         tmp2 = inlen - cons;
05747         if (tmp2 > 5)
05748             tmp2 = 5;
05749 
05750         printf("%ld %ld\n", cons, prod);
05751         ret = xmlBase64Decode(&input[cons], &tmp2, &output3[prod], &tmp);
05752         cons += tmp2;
05753         prod += tmp;
05754         printf("%ld %ld\n", cons, prod);
05755     }
05756     output3[outlen] = 0;
05757     printf("ret: %d, cons: %ld , prod: %ld, output: '%s'\n", ret, cons,
05758            prod, output3);
05759     return (0);
05760 
05761 }
05762 #endif
05763 #endif /* NOT_USED_YET */
05764 #define bottom_xmlreader
05765 #include "elfgcchack.h"
05766 #endif /* LIBXML_READER_ENABLED */

Generated on Fri May 25 2012 04:33:16 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.