Annotation of embedaddon/libxml2/xmlreader.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * xmlreader.c: implements the xmlTextReader streaming node API
        !             3:  *
        !             4:  * NOTE:
        !             5:  *   XmlTextReader.Normalization Property won't be supported, since
        !             6:  *     it makes the parser non compliant to the XML recommendation
        !             7:  *
        !             8:  * See Copyright for the status of this software.
        !             9:  *
        !            10:  * daniel@veillard.com
        !            11:  */
        !            12: 
        !            13: /*
        !            14:  * TODOs:
        !            15:  *   - XML Schemas validation
        !            16:  */
        !            17: #define IN_LIBXML
        !            18: #include "libxml.h"
        !            19: 
        !            20: #ifdef LIBXML_READER_ENABLED
        !            21: #include <string.h> /* for memset() only ! */
        !            22: #include <stdarg.h>
        !            23: 
        !            24: #ifdef HAVE_CTYPE_H
        !            25: #include <ctype.h>
        !            26: #endif
        !            27: #ifdef HAVE_STDLIB_H
        !            28: #include <stdlib.h>
        !            29: #endif
        !            30: 
        !            31: #include <libxml/xmlmemory.h>
        !            32: #include <libxml/xmlIO.h>
        !            33: #include <libxml/xmlreader.h>
        !            34: #include <libxml/parserInternals.h>
        !            35: #ifdef LIBXML_SCHEMAS_ENABLED
        !            36: #include <libxml/relaxng.h>
        !            37: #include <libxml/xmlschemas.h>
        !            38: #endif
        !            39: #include <libxml/uri.h>
        !            40: #ifdef LIBXML_XINCLUDE_ENABLED
        !            41: #include <libxml/xinclude.h>
        !            42: #endif
        !            43: #ifdef LIBXML_PATTERN_ENABLED
        !            44: #include <libxml/pattern.h>
        !            45: #endif
        !            46: 
        !            47: #define MAX_ERR_MSG_SIZE 64000
        !            48: 
        !            49: /*
        !            50:  * The following VA_COPY was coded following an example in
        !            51:  * the Samba project.  It may not be sufficient for some
        !            52:  * esoteric implementations of va_list (i.e. it may need
        !            53:  * something involving a memcpy) but (hopefully) will be
        !            54:  * sufficient for libxml2.
        !            55:  */
        !            56: #ifndef VA_COPY
        !            57:   #ifdef HAVE_VA_COPY
        !            58:     #define VA_COPY(dest, src) va_copy(dest, src)
        !            59:   #else
        !            60:     #ifdef HAVE___VA_COPY
        !            61:       #define VA_COPY(dest,src) __va_copy(dest, src)
        !            62:     #else
        !            63:       #define VA_COPY(dest,src) (dest) = (src)
        !            64:     #endif
        !            65:   #endif
        !            66: #endif
        !            67: 
        !            68: /* #define DEBUG_CALLBACKS */
        !            69: /* #define DEBUG_READER */
        !            70: 
        !            71: /**
        !            72:  * TODO:
        !            73:  *
        !            74:  * macro to flag unimplemented blocks
        !            75:  */
        !            76: #define TODO                                                           \
        !            77:     xmlGenericError(xmlGenericErrorContext,                            \
        !            78:            "Unimplemented block at %s:%d\n",                           \
        !            79:             __FILE__, __LINE__);
        !            80: 
        !            81: #ifdef DEBUG_READER
        !            82: #define DUMP_READER xmlTextReaderDebug(reader);
        !            83: #else
        !            84: #define DUMP_READER
        !            85: #endif
        !            86: 
        !            87: #define CHUNK_SIZE 512
        !            88: /************************************************************************
        !            89:  *                                                                     *
        !            90:  *     The parser: maps the Text Reader API on top of the existing     *
        !            91:  *             parsing routines building a tree                        *
        !            92:  *                                                                     *
        !            93:  ************************************************************************/
        !            94: 
        !            95: #define XML_TEXTREADER_INPUT   1
        !            96: #define XML_TEXTREADER_CTXT    2
        !            97: 
        !            98: typedef enum {
        !            99:     XML_TEXTREADER_NONE = -1,
        !           100:     XML_TEXTREADER_START= 0,
        !           101:     XML_TEXTREADER_ELEMENT= 1,
        !           102:     XML_TEXTREADER_END= 2,
        !           103:     XML_TEXTREADER_EMPTY= 3,
        !           104:     XML_TEXTREADER_BACKTRACK= 4,
        !           105:     XML_TEXTREADER_DONE= 5,
        !           106:     XML_TEXTREADER_ERROR= 6
        !           107: } xmlTextReaderState;
        !           108: 
        !           109: typedef enum {
        !           110:     XML_TEXTREADER_NOT_VALIDATE = 0,
        !           111:     XML_TEXTREADER_VALIDATE_DTD = 1,
        !           112:     XML_TEXTREADER_VALIDATE_RNG = 2,
        !           113:     XML_TEXTREADER_VALIDATE_XSD = 4
        !           114: } xmlTextReaderValidate;
        !           115: 
        !           116: struct _xmlTextReader {
        !           117:     int                                mode;   /* the parsing mode */
        !           118:     xmlDocPtr                  doc;    /* when walking an existing doc */
        !           119:     xmlTextReaderValidate       validate;/* is there any validation */
        !           120:     int                                allocs; /* what structure were deallocated */
        !           121:     xmlTextReaderState         state;
        !           122:     xmlParserCtxtPtr           ctxt;   /* the parser context */
        !           123:     xmlSAXHandlerPtr           sax;    /* the parser SAX callbacks */
        !           124:     xmlParserInputBufferPtr    input;  /* the input */
        !           125:     startElementSAXFunc                startElement;/* initial SAX callbacks */
        !           126:     endElementSAXFunc          endElement;  /* idem */
        !           127:     startElementNsSAX2Func     startElementNs;/* idem */
        !           128:     endElementNsSAX2Func       endElementNs;  /* idem */
        !           129:     charactersSAXFunc          characters;
        !           130:     cdataBlockSAXFunc          cdataBlock;
        !           131:     unsigned int               base;   /* base of the segment in the input */
        !           132:     unsigned int               cur;    /* current position in the input */
        !           133:     xmlNodePtr                 node;   /* current node */
        !           134:     xmlNodePtr                 curnode;/* current attribute node */
        !           135:     int                                depth;  /* depth of the current node */
        !           136:     xmlNodePtr                 faketext;/* fake xmlNs chld */
        !           137:     int                                preserve;/* preserve the resulting document */
        !           138:     xmlBufferPtr               buffer; /* used to return const xmlChar * */
        !           139:     xmlDictPtr                 dict;   /* the context dictionnary */
        !           140: 
        !           141:     /* entity stack when traversing entities content */
        !           142:     xmlNodePtr         ent;          /* Current Entity Ref Node */
        !           143:     int                entNr;        /* Depth of the entities stack */
        !           144:     int                entMax;       /* Max depth of the entities stack */
        !           145:     xmlNodePtr        *entTab;       /* array of entities */
        !           146: 
        !           147:     /* error handling */
        !           148:     xmlTextReaderErrorFunc errorFunc;    /* callback function */
        !           149:     void                  *errorFuncArg; /* callback function user argument */
        !           150: 
        !           151: #ifdef LIBXML_SCHEMAS_ENABLED
        !           152:     /* Handling of RelaxNG validation */
        !           153:     xmlRelaxNGPtr          rngSchemas; /* The Relax NG schemas */
        !           154:     xmlRelaxNGValidCtxtPtr rngValidCtxt;/* The Relax NG validation context */
        !           155:     int                    rngValidErrors;/* The number of errors detected */
        !           156:     xmlNodePtr             rngFullNode;        /* the node if RNG not progressive */
        !           157:     /* Handling of Schemas validation */
        !           158:     xmlSchemaPtr          xsdSchemas;  /* The Schemas schemas */
        !           159:     xmlSchemaValidCtxtPtr xsdValidCtxt;/* The Schemas validation context */
        !           160:     int                   xsdPreserveCtxt; /* 1 if the context was provided by the user */
        !           161:     int                   xsdValidErrors;/* The number of errors detected */
        !           162:     xmlSchemaSAXPlugPtr   xsdPlug;     /* the schemas plug in SAX pipeline */
        !           163: #endif
        !           164: #ifdef LIBXML_XINCLUDE_ENABLED
        !           165:     /* Handling of XInclude processing */
        !           166:     int                xinclude;       /* is xinclude asked for */
        !           167:     const xmlChar *    xinclude_name;  /* the xinclude name from dict */
        !           168:     xmlXIncludeCtxtPtr xincctxt;       /* the xinclude context */
        !           169:     int                in_xinclude;    /* counts for xinclude */
        !           170: #endif
        !           171: #ifdef LIBXML_PATTERN_ENABLED
        !           172:     int                patternNr;       /* number of preserve patterns */
        !           173:     int                patternMax;      /* max preserve patterns */
        !           174:     xmlPatternPtr     *patternTab;      /* array of preserve patterns */
        !           175: #endif
        !           176:     int                preserves;      /* level of preserves */
        !           177:     int                parserFlags;    /* the set of options set */
        !           178:     /* Structured error handling */
        !           179:     xmlStructuredErrorFunc sErrorFunc;  /* callback function */
        !           180: };
        !           181: 
        !           182: #define NODE_IS_EMPTY          0x1
        !           183: #define NODE_IS_PRESERVED      0x2
        !           184: #define NODE_IS_SPRESERVED     0x4
        !           185: 
        !           186: /**
        !           187:  * CONSTSTR:
        !           188:  *
        !           189:  * Macro used to return an interned string
        !           190:  */
        !           191: #define CONSTSTR(str) xmlDictLookup(reader->dict, (str), -1)
        !           192: #define CONSTQSTR(p, str) xmlDictQLookup(reader->dict, (p), (str))
        !           193: 
        !           194: static int xmlTextReaderReadTree(xmlTextReaderPtr reader);
        !           195: static int xmlTextReaderNextTree(xmlTextReaderPtr reader);
        !           196: 
        !           197: /************************************************************************
        !           198:  *                                                                     *
        !           199:  *     Our own version of the freeing routines as we recycle nodes     *
        !           200:  *                                                                     *
        !           201:  ************************************************************************/
        !           202: /**
        !           203:  * DICT_FREE:
        !           204:  * @str:  a string
        !           205:  *
        !           206:  * Free a string if it is not owned by the "dict" dictionnary in the
        !           207:  * current scope
        !           208:  */
        !           209: #define DICT_FREE(str)                                         \
        !           210:        if ((str) && ((!dict) ||                                \
        !           211:            (xmlDictOwns(dict, (const xmlChar *)(str)) == 0)))  \
        !           212:            xmlFree((char *)(str));
        !           213: 
        !           214: static void xmlTextReaderFreeNode(xmlTextReaderPtr reader, xmlNodePtr cur);
        !           215: static void xmlTextReaderFreeNodeList(xmlTextReaderPtr reader, xmlNodePtr cur);
        !           216: 
        !           217: /**
        !           218:  * xmlFreeID:
        !           219:  * @not:  A id
        !           220:  *
        !           221:  * Deallocate the memory used by an id definition
        !           222:  */
        !           223: static void
        !           224: xmlFreeID(xmlIDPtr id) {
        !           225:     xmlDictPtr dict = NULL;
        !           226: 
        !           227:     if (id == NULL) return;
        !           228: 
        !           229:     if (id->doc != NULL)
        !           230:         dict = id->doc->dict;
        !           231: 
        !           232:     if (id->value != NULL)
        !           233:        DICT_FREE(id->value)
        !           234:     xmlFree(id);
        !           235: }
        !           236: 
        !           237: /**
        !           238:  * xmlTextReaderRemoveID:
        !           239:  * @doc:  the document
        !           240:  * @attr:  the attribute
        !           241:  *
        !           242:  * Remove the given attribute from the ID table maintained internally.
        !           243:  *
        !           244:  * Returns -1 if the lookup failed and 0 otherwise
        !           245:  */
        !           246: static int
        !           247: xmlTextReaderRemoveID(xmlDocPtr doc, xmlAttrPtr attr) {
        !           248:     xmlIDTablePtr table;
        !           249:     xmlIDPtr id;
        !           250:     xmlChar *ID;
        !           251: 
        !           252:     if (doc == NULL) return(-1);
        !           253:     if (attr == NULL) return(-1);
        !           254:     table = (xmlIDTablePtr) doc->ids;
        !           255:     if (table == NULL)
        !           256:         return(-1);
        !           257: 
        !           258:     ID = xmlNodeListGetString(doc, attr->children, 1);
        !           259:     if (ID == NULL)
        !           260:        return(-1);
        !           261:     id = xmlHashLookup(table, ID);
        !           262:     xmlFree(ID);
        !           263:     if (id == NULL || id->attr != attr) {
        !           264:        return(-1);
        !           265:     }
        !           266:     id->name = attr->name;
        !           267:     id->attr = NULL;
        !           268:     return(0);
        !           269: }
        !           270: 
        !           271: /**
        !           272:  * xmlTextReaderFreeProp:
        !           273:  * @reader:  the xmlTextReaderPtr used
        !           274:  * @cur:  the node
        !           275:  *
        !           276:  * Free a node.
        !           277:  */
        !           278: static void
        !           279: xmlTextReaderFreeProp(xmlTextReaderPtr reader, xmlAttrPtr cur) {
        !           280:     xmlDictPtr dict;
        !           281: 
        !           282:     dict = reader->ctxt->dict;
        !           283:     if (cur == NULL) return;
        !           284: 
        !           285:     if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
        !           286:        xmlDeregisterNodeDefaultValue((xmlNodePtr) cur);
        !           287: 
        !           288:     /* Check for ID removal -> leading to invalid references ! */
        !           289:     if ((cur->parent != NULL) && (cur->parent->doc != NULL) &&
        !           290:        ((cur->parent->doc->intSubset != NULL) ||
        !           291:         (cur->parent->doc->extSubset != NULL))) {
        !           292:         if (xmlIsID(cur->parent->doc, cur->parent, cur))
        !           293:            xmlTextReaderRemoveID(cur->parent->doc, cur);
        !           294:     }
        !           295:     if (cur->children != NULL)
        !           296:         xmlTextReaderFreeNodeList(reader, cur->children);
        !           297: 
        !           298:     DICT_FREE(cur->name);
        !           299:     if ((reader != NULL) && (reader->ctxt != NULL) &&
        !           300:         (reader->ctxt->freeAttrsNr < 100)) {
        !           301:         cur->next = reader->ctxt->freeAttrs;
        !           302:        reader->ctxt->freeAttrs = cur;
        !           303:        reader->ctxt->freeAttrsNr++;
        !           304:     } else {
        !           305:        xmlFree(cur);
        !           306:     }
        !           307: }
        !           308: 
        !           309: /**
        !           310:  * xmlTextReaderFreePropList:
        !           311:  * @reader:  the xmlTextReaderPtr used
        !           312:  * @cur:  the first property in the list
        !           313:  *
        !           314:  * Free a property and all its siblings, all the children are freed too.
        !           315:  */
        !           316: static void
        !           317: xmlTextReaderFreePropList(xmlTextReaderPtr reader, xmlAttrPtr cur) {
        !           318:     xmlAttrPtr next;
        !           319:     if (cur == NULL) return;
        !           320:     while (cur != NULL) {
        !           321:         next = cur->next;
        !           322:         xmlTextReaderFreeProp(reader, cur);
        !           323:        cur = next;
        !           324:     }
        !           325: }
        !           326: 
        !           327: /**
        !           328:  * xmlTextReaderFreeNodeList:
        !           329:  * @reader:  the xmlTextReaderPtr used
        !           330:  * @cur:  the first node in the list
        !           331:  *
        !           332:  * Free a node and all its siblings, this is a recursive behaviour, all
        !           333:  * the children are freed too.
        !           334:  */
        !           335: static void
        !           336: xmlTextReaderFreeNodeList(xmlTextReaderPtr reader, xmlNodePtr cur) {
        !           337:     xmlNodePtr next;
        !           338:     xmlDictPtr dict;
        !           339: 
        !           340:     dict = reader->ctxt->dict;
        !           341:     if (cur == NULL) return;
        !           342:     if (cur->type == XML_NAMESPACE_DECL) {
        !           343:        xmlFreeNsList((xmlNsPtr) cur);
        !           344:        return;
        !           345:     }
        !           346:     if ((cur->type == XML_DOCUMENT_NODE) ||
        !           347:        (cur->type == XML_HTML_DOCUMENT_NODE)) {
        !           348:        xmlFreeDoc((xmlDocPtr) cur);
        !           349:        return;
        !           350:     }
        !           351:     while (cur != NULL) {
        !           352:         next = cur->next;
        !           353:        /* unroll to speed up freeing the document */
        !           354:        if (cur->type != XML_DTD_NODE) {
        !           355: 
        !           356:            if ((cur->children != NULL) &&
        !           357:                (cur->type != XML_ENTITY_REF_NODE)) {
        !           358:                if (cur->children->parent == cur)
        !           359:                    xmlTextReaderFreeNodeList(reader, cur->children);
        !           360:                cur->children = NULL;
        !           361:            }
        !           362: 
        !           363:            if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
        !           364:                xmlDeregisterNodeDefaultValue(cur);
        !           365: 
        !           366:            if (((cur->type == XML_ELEMENT_NODE) ||
        !           367:                 (cur->type == XML_XINCLUDE_START) ||
        !           368:                 (cur->type == XML_XINCLUDE_END)) &&
        !           369:                (cur->properties != NULL))
        !           370:                xmlTextReaderFreePropList(reader, cur->properties);
        !           371:            if ((cur->content != (xmlChar *) &(cur->properties)) &&
        !           372:                (cur->type != XML_ELEMENT_NODE) &&
        !           373:                (cur->type != XML_XINCLUDE_START) &&
        !           374:                (cur->type != XML_XINCLUDE_END) &&
        !           375:                (cur->type != XML_ENTITY_REF_NODE)) {
        !           376:                DICT_FREE(cur->content);
        !           377:            }
        !           378:            if (((cur->type == XML_ELEMENT_NODE) ||
        !           379:                 (cur->type == XML_XINCLUDE_START) ||
        !           380:                 (cur->type == XML_XINCLUDE_END)) &&
        !           381:                (cur->nsDef != NULL))
        !           382:                xmlFreeNsList(cur->nsDef);
        !           383: 
        !           384:            /*
        !           385:             * we don't free element names here they are interned now
        !           386:             */
        !           387:            if ((cur->type != XML_TEXT_NODE) &&
        !           388:                (cur->type != XML_COMMENT_NODE))
        !           389:                DICT_FREE(cur->name);
        !           390:            if (((cur->type == XML_ELEMENT_NODE) ||
        !           391:                 (cur->type == XML_TEXT_NODE)) &&
        !           392:                (reader != NULL) && (reader->ctxt != NULL) &&
        !           393:                (reader->ctxt->freeElemsNr < 100)) {
        !           394:                cur->next = reader->ctxt->freeElems;
        !           395:                reader->ctxt->freeElems = cur;
        !           396:                reader->ctxt->freeElemsNr++;
        !           397:            } else {
        !           398:                xmlFree(cur);
        !           399:            }
        !           400:        }
        !           401:        cur = next;
        !           402:     }
        !           403: }
        !           404: 
        !           405: /**
        !           406:  * xmlTextReaderFreeNode:
        !           407:  * @reader:  the xmlTextReaderPtr used
        !           408:  * @cur:  the node
        !           409:  *
        !           410:  * Free a node, this is a recursive behaviour, all the children are freed too.
        !           411:  * This doesn't unlink the child from the list, use xmlUnlinkNode() first.
        !           412:  */
        !           413: static void
        !           414: xmlTextReaderFreeNode(xmlTextReaderPtr reader, xmlNodePtr cur) {
        !           415:     xmlDictPtr dict;
        !           416: 
        !           417:     dict = reader->ctxt->dict;
        !           418:     if (cur->type == XML_DTD_NODE) {
        !           419:        xmlFreeDtd((xmlDtdPtr) cur);
        !           420:        return;
        !           421:     }
        !           422:     if (cur->type == XML_NAMESPACE_DECL) {
        !           423:        xmlFreeNs((xmlNsPtr) cur);
        !           424:         return;
        !           425:     }
        !           426:     if (cur->type == XML_ATTRIBUTE_NODE) {
        !           427:        xmlTextReaderFreeProp(reader, (xmlAttrPtr) cur);
        !           428:        return;
        !           429:     }
        !           430: 
        !           431:     if ((cur->children != NULL) &&
        !           432:        (cur->type != XML_ENTITY_REF_NODE)) {
        !           433:        if (cur->children->parent == cur)
        !           434:            xmlTextReaderFreeNodeList(reader, cur->children);
        !           435:        cur->children = NULL;
        !           436:     }
        !           437: 
        !           438:     if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
        !           439:        xmlDeregisterNodeDefaultValue(cur);
        !           440: 
        !           441:     if (((cur->type == XML_ELEMENT_NODE) ||
        !           442:         (cur->type == XML_XINCLUDE_START) ||
        !           443:         (cur->type == XML_XINCLUDE_END)) &&
        !           444:        (cur->properties != NULL))
        !           445:        xmlTextReaderFreePropList(reader, cur->properties);
        !           446:     if ((cur->content != (xmlChar *) &(cur->properties)) &&
        !           447:         (cur->type != XML_ELEMENT_NODE) &&
        !           448:        (cur->type != XML_XINCLUDE_START) &&
        !           449:        (cur->type != XML_XINCLUDE_END) &&
        !           450:        (cur->type != XML_ENTITY_REF_NODE)) {
        !           451:        DICT_FREE(cur->content);
        !           452:     }
        !           453:     if (((cur->type == XML_ELEMENT_NODE) ||
        !           454:         (cur->type == XML_XINCLUDE_START) ||
        !           455:         (cur->type == XML_XINCLUDE_END)) &&
        !           456:        (cur->nsDef != NULL))
        !           457:        xmlFreeNsList(cur->nsDef);
        !           458: 
        !           459:     /*
        !           460:      * we don't free names here they are interned now
        !           461:      */
        !           462:     if ((cur->type != XML_TEXT_NODE) &&
        !           463:         (cur->type != XML_COMMENT_NODE))
        !           464:        DICT_FREE(cur->name);
        !           465: 
        !           466:     if (((cur->type == XML_ELEMENT_NODE) ||
        !           467:         (cur->type == XML_TEXT_NODE)) &&
        !           468:        (reader != NULL) && (reader->ctxt != NULL) &&
        !           469:        (reader->ctxt->freeElemsNr < 100)) {
        !           470:        cur->next = reader->ctxt->freeElems;
        !           471:        reader->ctxt->freeElems = cur;
        !           472:        reader->ctxt->freeElemsNr++;
        !           473:     } else {
        !           474:        xmlFree(cur);
        !           475:     }
        !           476: }
        !           477: 
        !           478: /**
        !           479:  * xmlTextReaderFreeIDTable:
        !           480:  * @table:  An id table
        !           481:  *
        !           482:  * Deallocate the memory used by an ID hash table.
        !           483:  */
        !           484: static void
        !           485: xmlTextReaderFreeIDTable(xmlIDTablePtr table) {
        !           486:     xmlHashFree(table, (xmlHashDeallocator) xmlFreeID);
        !           487: }
        !           488: 
        !           489: /**
        !           490:  * xmlTextReaderFreeDoc:
        !           491:  * @reader:  the xmlTextReaderPtr used
        !           492:  * @cur:  pointer to the document
        !           493:  *
        !           494:  * Free up all the structures used by a document, tree included.
        !           495:  */
        !           496: static void
        !           497: xmlTextReaderFreeDoc(xmlTextReaderPtr reader, xmlDocPtr cur) {
        !           498:     xmlDtdPtr extSubset, intSubset;
        !           499: 
        !           500:     if (cur == NULL) return;
        !           501: 
        !           502:     if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
        !           503:        xmlDeregisterNodeDefaultValue((xmlNodePtr) cur);
        !           504: 
        !           505:     /*
        !           506:      * Do this before freeing the children list to avoid ID lookups
        !           507:      */
        !           508:     if (cur->ids != NULL) xmlTextReaderFreeIDTable((xmlIDTablePtr) cur->ids);
        !           509:     cur->ids = NULL;
        !           510:     if (cur->refs != NULL) xmlFreeRefTable((xmlRefTablePtr) cur->refs);
        !           511:     cur->refs = NULL;
        !           512:     extSubset = cur->extSubset;
        !           513:     intSubset = cur->intSubset;
        !           514:     if (intSubset == extSubset)
        !           515:        extSubset = NULL;
        !           516:     if (extSubset != NULL) {
        !           517:        xmlUnlinkNode((xmlNodePtr) cur->extSubset);
        !           518:        cur->extSubset = NULL;
        !           519:        xmlFreeDtd(extSubset);
        !           520:     }
        !           521:     if (intSubset != NULL) {
        !           522:        xmlUnlinkNode((xmlNodePtr) cur->intSubset);
        !           523:        cur->intSubset = NULL;
        !           524:        xmlFreeDtd(intSubset);
        !           525:     }
        !           526: 
        !           527:     if (cur->children != NULL) xmlTextReaderFreeNodeList(reader, cur->children);
        !           528: 
        !           529:     if (cur->version != NULL) xmlFree((char *) cur->version);
        !           530:     if (cur->name != NULL) xmlFree((char *) cur->name);
        !           531:     if (cur->encoding != NULL) xmlFree((char *) cur->encoding);
        !           532:     if (cur->oldNs != NULL) xmlFreeNsList(cur->oldNs);
        !           533:     if (cur->URL != NULL) xmlFree((char *) cur->URL);
        !           534:     if (cur->dict != NULL) xmlDictFree(cur->dict);
        !           535: 
        !           536:     xmlFree(cur);
        !           537: }
        !           538: 
        !           539: /************************************************************************
        !           540:  *                                                                     *
        !           541:  *                     The reader core parser                          *
        !           542:  *                                                                     *
        !           543:  ************************************************************************/
        !           544: #ifdef DEBUG_READER
        !           545: static void
        !           546: xmlTextReaderDebug(xmlTextReaderPtr reader) {
        !           547:     if ((reader == NULL) || (reader->ctxt == NULL)) {
        !           548:        fprintf(stderr, "xmlTextReader NULL\n");
        !           549:        return;
        !           550:     }
        !           551:     fprintf(stderr, "xmlTextReader: state %d depth %d ",
        !           552:            reader->state, reader->depth);
        !           553:     if (reader->node == NULL) {
        !           554:        fprintf(stderr, "node = NULL\n");
        !           555:     } else {
        !           556:        fprintf(stderr, "node %s\n", reader->node->name);
        !           557:     }
        !           558:     fprintf(stderr, "  input: base %d, cur %d, depth %d: ",
        !           559:            reader->base, reader->cur, reader->ctxt->nodeNr);
        !           560:     if (reader->input->buffer == NULL) {
        !           561:        fprintf(stderr, "buffer is NULL\n");
        !           562:     } else {
        !           563: #ifdef LIBXML_DEBUG_ENABLED
        !           564:        xmlDebugDumpString(stderr,
        !           565:                &reader->input->buffer->content[reader->cur]);
        !           566: #endif
        !           567:        fprintf(stderr, "\n");
        !           568:     }
        !           569: }
        !           570: #endif
        !           571: 
        !           572: /**
        !           573:  * xmlTextReaderEntPush:
        !           574:  * @reader:  the xmlTextReaderPtr used
        !           575:  * @value:  the entity reference node
        !           576:  *
        !           577:  * Pushes a new entity reference node on top of the entities stack
        !           578:  *
        !           579:  * Returns 0 in case of error, the index in the stack otherwise
        !           580:  */
        !           581: static int
        !           582: xmlTextReaderEntPush(xmlTextReaderPtr reader, xmlNodePtr value)
        !           583: {
        !           584:     if (reader->entMax <= 0) {
        !           585:        reader->entMax = 10;
        !           586:        reader->entTab = (xmlNodePtr *) xmlMalloc(reader->entMax *
        !           587:                                                  sizeof(reader->entTab[0]));
        !           588:         if (reader->entTab == NULL) {
        !           589:             xmlGenericError(xmlGenericErrorContext, "xmlMalloc failed !\n");
        !           590:             return (0);
        !           591:         }
        !           592:     }
        !           593:     if (reader->entNr >= reader->entMax) {
        !           594:         reader->entMax *= 2;
        !           595:         reader->entTab =
        !           596:             (xmlNodePtr *) xmlRealloc(reader->entTab,
        !           597:                                       reader->entMax *
        !           598:                                       sizeof(reader->entTab[0]));
        !           599:         if (reader->entTab == NULL) {
        !           600:             xmlGenericError(xmlGenericErrorContext, "xmlRealloc failed !\n");
        !           601:             return (0);
        !           602:         }
        !           603:     }
        !           604:     reader->entTab[reader->entNr] = value;
        !           605:     reader->ent = value;
        !           606:     return (reader->entNr++);
        !           607: }
        !           608: 
        !           609: /**
        !           610:  * xmlTextReaderEntPop:
        !           611:  * @reader:  the xmlTextReaderPtr used
        !           612:  *
        !           613:  * Pops the top element entity from the entities stack
        !           614:  *
        !           615:  * Returns the entity just removed
        !           616:  */
        !           617: static xmlNodePtr
        !           618: xmlTextReaderEntPop(xmlTextReaderPtr reader)
        !           619: {
        !           620:     xmlNodePtr ret;
        !           621: 
        !           622:     if (reader->entNr <= 0)
        !           623:         return (NULL);
        !           624:     reader->entNr--;
        !           625:     if (reader->entNr > 0)
        !           626:         reader->ent = reader->entTab[reader->entNr - 1];
        !           627:     else
        !           628:         reader->ent = NULL;
        !           629:     ret = reader->entTab[reader->entNr];
        !           630:     reader->entTab[reader->entNr] = NULL;
        !           631:     return (ret);
        !           632: }
        !           633: 
        !           634: /**
        !           635:  * xmlTextReaderStartElement:
        !           636:  * @ctx: the user data (XML parser context)
        !           637:  * @fullname:  The element name, including namespace prefix
        !           638:  * @atts:  An array of name/value attributes pairs, NULL terminated
        !           639:  *
        !           640:  * called when an opening tag has been processed.
        !           641:  */
        !           642: static void
        !           643: xmlTextReaderStartElement(void *ctx, const xmlChar *fullname,
        !           644:                          const xmlChar **atts) {
        !           645:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
        !           646:     xmlTextReaderPtr reader = ctxt->_private;
        !           647: 
        !           648: #ifdef DEBUG_CALLBACKS
        !           649:     printf("xmlTextReaderStartElement(%s)\n", fullname);
        !           650: #endif
        !           651:     if ((reader != NULL) && (reader->startElement != NULL)) {
        !           652:        reader->startElement(ctx, fullname, atts);
        !           653:        if ((ctxt->node != NULL) && (ctxt->input != NULL) &&
        !           654:            (ctxt->input->cur != NULL) && (ctxt->input->cur[0] == '/') &&
        !           655:            (ctxt->input->cur[1] == '>'))
        !           656:            ctxt->node->extra = NODE_IS_EMPTY;
        !           657:     }
        !           658:     if (reader != NULL)
        !           659:        reader->state = XML_TEXTREADER_ELEMENT;
        !           660: }
        !           661: 
        !           662: /**
        !           663:  * xmlTextReaderEndElement:
        !           664:  * @ctx: the user data (XML parser context)
        !           665:  * @fullname:  The element name, including namespace prefix
        !           666:  *
        !           667:  * called when an ending tag has been processed.
        !           668:  */
        !           669: static void
        !           670: xmlTextReaderEndElement(void *ctx, const xmlChar *fullname) {
        !           671:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
        !           672:     xmlTextReaderPtr reader = ctxt->_private;
        !           673: 
        !           674: #ifdef DEBUG_CALLBACKS
        !           675:     printf("xmlTextReaderEndElement(%s)\n", fullname);
        !           676: #endif
        !           677:     if ((reader != NULL) && (reader->endElement != NULL)) {
        !           678:        reader->endElement(ctx, fullname);
        !           679:     }
        !           680: }
        !           681: 
        !           682: /**
        !           683:  * xmlTextReaderStartElementNs:
        !           684:  * @ctx: the user data (XML parser context)
        !           685:  * @localname:  the local name of the element
        !           686:  * @prefix:  the element namespace prefix if available
        !           687:  * @URI:  the element namespace name if available
        !           688:  * @nb_namespaces:  number of namespace definitions on that node
        !           689:  * @namespaces:  pointer to the array of prefix/URI pairs namespace definitions
        !           690:  * @nb_attributes:  the number of attributes on that node
        !           691:  * nb_defaulted:  the number of defaulted attributes.
        !           692:  * @attributes:  pointer to the array of (localname/prefix/URI/value/end)
        !           693:  *               attribute values.
        !           694:  *
        !           695:  * called when an opening tag has been processed.
        !           696:  */
        !           697: static void
        !           698: xmlTextReaderStartElementNs(void *ctx,
        !           699:                       const xmlChar *localname,
        !           700:                      const xmlChar *prefix,
        !           701:                      const xmlChar *URI,
        !           702:                      int nb_namespaces,
        !           703:                      const xmlChar **namespaces,
        !           704:                      int nb_attributes,
        !           705:                      int nb_defaulted,
        !           706:                      const xmlChar **attributes)
        !           707: {
        !           708:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
        !           709:     xmlTextReaderPtr reader = ctxt->_private;
        !           710: 
        !           711: #ifdef DEBUG_CALLBACKS
        !           712:     printf("xmlTextReaderStartElementNs(%s)\n", localname);
        !           713: #endif
        !           714:     if ((reader != NULL) && (reader->startElementNs != NULL)) {
        !           715:        reader->startElementNs(ctx, localname, prefix, URI, nb_namespaces,
        !           716:                               namespaces, nb_attributes, nb_defaulted,
        !           717:                               attributes);
        !           718:        if ((ctxt->node != NULL) && (ctxt->input != NULL) &&
        !           719:            (ctxt->input->cur != NULL) && (ctxt->input->cur[0] == '/') &&
        !           720:            (ctxt->input->cur[1] == '>'))
        !           721:            ctxt->node->extra = NODE_IS_EMPTY;
        !           722:     }
        !           723:     if (reader != NULL)
        !           724:        reader->state = XML_TEXTREADER_ELEMENT;
        !           725: }
        !           726: 
        !           727: /**
        !           728:  * xmlTextReaderEndElementNs:
        !           729:  * @ctx: the user data (XML parser context)
        !           730:  * @localname:  the local name of the element
        !           731:  * @prefix:  the element namespace prefix if available
        !           732:  * @URI:  the element namespace name if available
        !           733:  *
        !           734:  * called when an ending tag has been processed.
        !           735:  */
        !           736: static void
        !           737: xmlTextReaderEndElementNs(void *ctx,
        !           738:                           const xmlChar * localname,
        !           739:                           const xmlChar * prefix,
        !           740:                          const xmlChar * URI)
        !           741: {
        !           742:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
        !           743:     xmlTextReaderPtr reader = ctxt->_private;
        !           744: 
        !           745: #ifdef DEBUG_CALLBACKS
        !           746:     printf("xmlTextReaderEndElementNs(%s)\n", localname);
        !           747: #endif
        !           748:     if ((reader != NULL) && (reader->endElementNs != NULL)) {
        !           749:        reader->endElementNs(ctx, localname, prefix, URI);
        !           750:     }
        !           751: }
        !           752: 
        !           753: 
        !           754: /**
        !           755:  * xmlTextReaderCharacters:
        !           756:  * @ctx: the user data (XML parser context)
        !           757:  * @ch:  a xmlChar string
        !           758:  * @len: the number of xmlChar
        !           759:  *
        !           760:  * receiving some chars from the parser.
        !           761:  */
        !           762: static void
        !           763: xmlTextReaderCharacters(void *ctx, const xmlChar *ch, int len)
        !           764: {
        !           765:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
        !           766:     xmlTextReaderPtr reader = ctxt->_private;
        !           767: 
        !           768: #ifdef DEBUG_CALLBACKS
        !           769:     printf("xmlTextReaderCharacters()\n");
        !           770: #endif
        !           771:     if ((reader != NULL) && (reader->characters != NULL)) {
        !           772:        reader->characters(ctx, ch, len);
        !           773:     }
        !           774: }
        !           775: 
        !           776: /**
        !           777:  * xmlTextReaderCDataBlock:
        !           778:  * @ctx: the user data (XML parser context)
        !           779:  * @value:  The pcdata content
        !           780:  * @len:  the block length
        !           781:  *
        !           782:  * called when a pcdata block has been parsed
        !           783:  */
        !           784: static void
        !           785: xmlTextReaderCDataBlock(void *ctx, const xmlChar *ch, int len)
        !           786: {
        !           787:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
        !           788:     xmlTextReaderPtr reader = ctxt->_private;
        !           789: 
        !           790: #ifdef DEBUG_CALLBACKS
        !           791:     printf("xmlTextReaderCDataBlock()\n");
        !           792: #endif
        !           793:     if ((reader != NULL) && (reader->cdataBlock != NULL)) {
        !           794:        reader->cdataBlock(ctx, ch, len);
        !           795:     }
        !           796: }
        !           797: 
        !           798: /**
        !           799:  * xmlTextReaderPushData:
        !           800:  * @reader:  the xmlTextReaderPtr used
        !           801:  *
        !           802:  * Push data down the progressive parser until a significant callback
        !           803:  * got raised.
        !           804:  *
        !           805:  * Returns -1 in case of failure, 0 otherwise
        !           806:  */
        !           807: static int
        !           808: xmlTextReaderPushData(xmlTextReaderPtr reader) {
        !           809:     xmlBufferPtr inbuf;
        !           810:     int val, s;
        !           811:     xmlTextReaderState oldstate;
        !           812: 
        !           813:     if ((reader->input == NULL) || (reader->input->buffer == NULL))
        !           814:        return(-1);
        !           815: 
        !           816:     oldstate = reader->state;
        !           817:     reader->state = XML_TEXTREADER_NONE;
        !           818:     inbuf = reader->input->buffer;
        !           819: 
        !           820:     while (reader->state == XML_TEXTREADER_NONE) {
        !           821:        if (inbuf->use < reader->cur + CHUNK_SIZE) {
        !           822:            /*
        !           823:             * Refill the buffer unless we are at the end of the stream
        !           824:             */
        !           825:            if (reader->mode != XML_TEXTREADER_MODE_EOF) {
        !           826:                val = xmlParserInputBufferRead(reader->input, 4096);
        !           827:                if ((val == 0) &&
        !           828:                    (inbuf->alloc == XML_BUFFER_ALLOC_IMMUTABLE)) {
        !           829:                    if (inbuf->use == reader->cur) {
        !           830:                        reader->mode = XML_TEXTREADER_MODE_EOF;
        !           831:                        reader->state = oldstate;
        !           832:                    }
        !           833:                } else if (val < 0) {
        !           834:                    reader->mode = XML_TEXTREADER_MODE_EOF;
        !           835:                    reader->state = oldstate;
        !           836:                    if ((oldstate != XML_TEXTREADER_START) ||
        !           837:                        (reader->ctxt->myDoc != NULL))
        !           838:                        return(val);
        !           839:                } else if (val == 0) {
        !           840:                    /* mark the end of the stream and process the remains */
        !           841:                    reader->mode = XML_TEXTREADER_MODE_EOF;
        !           842:                    break;
        !           843:                }
        !           844: 
        !           845:            } else
        !           846:                break;
        !           847:        }
        !           848:        /*
        !           849:         * parse by block of CHUNK_SIZE bytes, various tests show that
        !           850:         * it's the best tradeoff at least on a 1.2GH Duron
        !           851:         */
        !           852:        if (inbuf->use >= reader->cur + CHUNK_SIZE) {
        !           853:            val = xmlParseChunk(reader->ctxt,
        !           854:                          (const char *) &inbuf->content[reader->cur],
        !           855:                          CHUNK_SIZE, 0);
        !           856:            reader->cur += CHUNK_SIZE;
        !           857:            if ((val != 0) || (reader->ctxt->wellFormed == 0))
        !           858:                return(-1);
        !           859:        } else {
        !           860:            s = inbuf->use - reader->cur;
        !           861:            val = xmlParseChunk(reader->ctxt,
        !           862:                          (const char *) &inbuf->content[reader->cur],
        !           863:                          s, 0);
        !           864:            reader->cur += s;
        !           865:            if ((val != 0) || (reader->ctxt->wellFormed == 0))
        !           866:                return(-1);
        !           867:            break;
        !           868:        }
        !           869:     }
        !           870: 
        !           871:     /*
        !           872:      * Discard the consumed input when needed and possible
        !           873:      */
        !           874:     if (reader->mode == XML_TEXTREADER_MODE_INTERACTIVE) {
        !           875:         if (inbuf->alloc != XML_BUFFER_ALLOC_IMMUTABLE) {
        !           876:            if ((reader->cur >= 4096) &&
        !           877:                (inbuf->use - reader->cur <= CHUNK_SIZE)) {
        !           878:                val = xmlBufferShrink(inbuf, reader->cur);
        !           879:                if (val >= 0) {
        !           880:                    reader->cur -= val;
        !           881:                }
        !           882:            }
        !           883:        }
        !           884:     }
        !           885: 
        !           886:     /*
        !           887:      * At the end of the stream signal that the work is done to the Push
        !           888:      * parser.
        !           889:      */
        !           890:     else if (reader->mode == XML_TEXTREADER_MODE_EOF) {
        !           891:        if (reader->state != XML_TEXTREADER_DONE) {
        !           892:            s = inbuf->use - reader->cur;
        !           893:            val = xmlParseChunk(reader->ctxt,
        !           894:                    (const char *) &inbuf->content[reader->cur],
        !           895:                    s, 1);
        !           896:            reader->cur = inbuf->use;
        !           897:            reader->state  = XML_TEXTREADER_DONE;
        !           898:            if ((val != 0) || (reader->ctxt->wellFormed == 0))
        !           899:                return(-1);
        !           900:        }
        !           901:     }
        !           902:     reader->state = oldstate;
        !           903:     return(0);
        !           904: }
        !           905: 
        !           906: #ifdef LIBXML_REGEXP_ENABLED
        !           907: /**
        !           908:  * xmlTextReaderValidatePush:
        !           909:  * @reader:  the xmlTextReaderPtr used
        !           910:  *
        !           911:  * Push the current node for validation
        !           912:  */
        !           913: static void
        !           914: xmlTextReaderValidatePush(xmlTextReaderPtr reader ATTRIBUTE_UNUSED) {
        !           915:     xmlNodePtr node = reader->node;
        !           916: 
        !           917: #ifdef LIBXML_VALID_ENABLED
        !           918:     if ((reader->validate == XML_TEXTREADER_VALIDATE_DTD) &&
        !           919:         (reader->ctxt != NULL) && (reader->ctxt->validate == 1)) {
        !           920:        if ((node->ns == NULL) || (node->ns->prefix == NULL)) {
        !           921:            reader->ctxt->valid &= xmlValidatePushElement(&reader->ctxt->vctxt,
        !           922:                                    reader->ctxt->myDoc, node, node->name);
        !           923:        } else {
        !           924:            /* TODO use the BuildQName interface */
        !           925:            xmlChar *qname;
        !           926: 
        !           927:            qname = xmlStrdup(node->ns->prefix);
        !           928:            qname = xmlStrcat(qname, BAD_CAST ":");
        !           929:            qname = xmlStrcat(qname, node->name);
        !           930:            reader->ctxt->valid &= xmlValidatePushElement(&reader->ctxt->vctxt,
        !           931:                                    reader->ctxt->myDoc, node, qname);
        !           932:            if (qname != NULL)
        !           933:                xmlFree(qname);
        !           934:        }
        !           935:     }
        !           936: #endif /* LIBXML_VALID_ENABLED */
        !           937: #ifdef LIBXML_SCHEMAS_ENABLED
        !           938:     if ((reader->validate == XML_TEXTREADER_VALIDATE_RNG) &&
        !           939:                (reader->rngValidCtxt != NULL)) {
        !           940:        int ret;
        !           941: 
        !           942:        if (reader->rngFullNode != NULL) return;
        !           943:        ret = xmlRelaxNGValidatePushElement(reader->rngValidCtxt,
        !           944:                                            reader->ctxt->myDoc,
        !           945:                                            node);
        !           946:        if (ret == 0) {
        !           947:            /*
        !           948:             * this element requires a full tree
        !           949:             */
        !           950:            node = xmlTextReaderExpand(reader);
        !           951:            if (node == NULL) {
        !           952: printf("Expand failed !\n");
        !           953:                ret = -1;
        !           954:            } else {
        !           955:                ret = xmlRelaxNGValidateFullElement(reader->rngValidCtxt,
        !           956:                                                    reader->ctxt->myDoc,
        !           957:                                                    node);
        !           958:                reader->rngFullNode = node;
        !           959:            }
        !           960:        }
        !           961:        if (ret != 1)
        !           962:            reader->rngValidErrors++;
        !           963:     }
        !           964: #endif
        !           965: }
        !           966: 
        !           967: /**
        !           968:  * xmlTextReaderValidateCData:
        !           969:  * @reader:  the xmlTextReaderPtr used
        !           970:  * @data:  pointer to the CData
        !           971:  * @len:  lenght of the CData block in bytes.
        !           972:  *
        !           973:  * Push some CData for validation
        !           974:  */
        !           975: static void
        !           976: xmlTextReaderValidateCData(xmlTextReaderPtr reader,
        !           977:                            const xmlChar *data, int len) {
        !           978: #ifdef LIBXML_VALID_ENABLED
        !           979:     if ((reader->validate == XML_TEXTREADER_VALIDATE_DTD) &&
        !           980:         (reader->ctxt != NULL) && (reader->ctxt->validate == 1)) {
        !           981:        reader->ctxt->valid &= xmlValidatePushCData(&reader->ctxt->vctxt,
        !           982:                                                    data, len);
        !           983:     }
        !           984: #endif /* LIBXML_VALID_ENABLED */
        !           985: #ifdef LIBXML_SCHEMAS_ENABLED
        !           986:     if ((reader->validate == XML_TEXTREADER_VALIDATE_RNG) &&
        !           987:                (reader->rngValidCtxt != NULL)) {
        !           988:        int ret;
        !           989: 
        !           990:        if (reader->rngFullNode != NULL) return;
        !           991:        ret = xmlRelaxNGValidatePushCData(reader->rngValidCtxt, data, len);
        !           992:        if (ret != 1)
        !           993:            reader->rngValidErrors++;
        !           994:     }
        !           995: #endif
        !           996: }
        !           997: 
        !           998: /**
        !           999:  * xmlTextReaderValidatePop:
        !          1000:  * @reader:  the xmlTextReaderPtr used
        !          1001:  *
        !          1002:  * Pop the current node from validation
        !          1003:  */
        !          1004: static void
        !          1005: xmlTextReaderValidatePop(xmlTextReaderPtr reader) {
        !          1006:     xmlNodePtr node = reader->node;
        !          1007: 
        !          1008: #ifdef LIBXML_VALID_ENABLED
        !          1009:     if ((reader->validate == XML_TEXTREADER_VALIDATE_DTD) &&
        !          1010:         (reader->ctxt != NULL) && (reader->ctxt->validate == 1)) {
        !          1011:        if ((node->ns == NULL) || (node->ns->prefix == NULL)) {
        !          1012:            reader->ctxt->valid &= xmlValidatePopElement(&reader->ctxt->vctxt,
        !          1013:                                    reader->ctxt->myDoc, node, node->name);
        !          1014:        } else {
        !          1015:            /* TODO use the BuildQName interface */
        !          1016:            xmlChar *qname;
        !          1017: 
        !          1018:            qname = xmlStrdup(node->ns->prefix);
        !          1019:            qname = xmlStrcat(qname, BAD_CAST ":");
        !          1020:            qname = xmlStrcat(qname, node->name);
        !          1021:            reader->ctxt->valid &= xmlValidatePopElement(&reader->ctxt->vctxt,
        !          1022:                                    reader->ctxt->myDoc, node, qname);
        !          1023:            if (qname != NULL)
        !          1024:                xmlFree(qname);
        !          1025:        }
        !          1026:     }
        !          1027: #endif /* LIBXML_VALID_ENABLED */
        !          1028: #ifdef LIBXML_SCHEMAS_ENABLED
        !          1029:     if ((reader->validate == XML_TEXTREADER_VALIDATE_RNG) &&
        !          1030:                (reader->rngValidCtxt != NULL)) {
        !          1031:        int ret;
        !          1032: 
        !          1033:        if (reader->rngFullNode != NULL) {
        !          1034:            if (node == reader->rngFullNode)
        !          1035:                reader->rngFullNode = NULL;
        !          1036:            return;
        !          1037:        }
        !          1038:        ret = xmlRelaxNGValidatePopElement(reader->rngValidCtxt,
        !          1039:                                           reader->ctxt->myDoc,
        !          1040:                                           node);
        !          1041:        if (ret != 1)
        !          1042:            reader->rngValidErrors++;
        !          1043:     }
        !          1044: #endif
        !          1045: }
        !          1046: 
        !          1047: /**
        !          1048:  * xmlTextReaderValidateEntity:
        !          1049:  * @reader:  the xmlTextReaderPtr used
        !          1050:  *
        !          1051:  * Handle the validation when an entity reference is encountered and
        !          1052:  * entity substitution is not activated. As a result the parser interface
        !          1053:  * must walk through the entity and do the validation calls
        !          1054:  */
        !          1055: static void
        !          1056: xmlTextReaderValidateEntity(xmlTextReaderPtr reader) {
        !          1057:     xmlNodePtr oldnode = reader->node;
        !          1058:     xmlNodePtr node = reader->node;
        !          1059:     xmlParserCtxtPtr ctxt = reader->ctxt;
        !          1060: 
        !          1061:     do {
        !          1062:        if (node->type == XML_ENTITY_REF_NODE) {
        !          1063:            /*
        !          1064:             * Case where the underlying tree is not availble, lookup the entity
        !          1065:             * and walk it.
        !          1066:             */
        !          1067:            if ((node->children == NULL) && (ctxt->sax != NULL) &&
        !          1068:                (ctxt->sax->getEntity != NULL)) {
        !          1069:                node->children = (xmlNodePtr)
        !          1070:                    ctxt->sax->getEntity(ctxt, node->name);
        !          1071:            }
        !          1072: 
        !          1073:            if ((node->children != NULL) &&
        !          1074:                (node->children->type == XML_ENTITY_DECL) &&
        !          1075:                (node->children->children != NULL)) {
        !          1076:                xmlTextReaderEntPush(reader, node);
        !          1077:                node = node->children->children;
        !          1078:                continue;
        !          1079:            } else {
        !          1080:                /*
        !          1081:                 * The error has probably be raised already.
        !          1082:                 */
        !          1083:                if (node == oldnode)
        !          1084:                    break;
        !          1085:                node = node->next;
        !          1086:            }
        !          1087: #ifdef LIBXML_REGEXP_ENABLED
        !          1088:        } else if (node->type == XML_ELEMENT_NODE) {
        !          1089:            reader->node = node;
        !          1090:            xmlTextReaderValidatePush(reader);
        !          1091:        } else if ((node->type == XML_TEXT_NODE) ||
        !          1092:                   (node->type == XML_CDATA_SECTION_NODE)) {
        !          1093:             xmlTextReaderValidateCData(reader, node->content,
        !          1094:                                       xmlStrlen(node->content));
        !          1095: #endif
        !          1096:        }
        !          1097: 
        !          1098:        /*
        !          1099:         * go to next node
        !          1100:         */
        !          1101:        if (node->children != NULL) {
        !          1102:            node = node->children;
        !          1103:            continue;
        !          1104:        } else if (node->type == XML_ELEMENT_NODE) {
        !          1105:            xmlTextReaderValidatePop(reader);
        !          1106:        }
        !          1107:        if (node->next != NULL) {
        !          1108:            node = node->next;
        !          1109:            continue;
        !          1110:        }
        !          1111:        do {
        !          1112:            node = node->parent;
        !          1113:            if (node->type == XML_ELEMENT_NODE) {
        !          1114:                xmlNodePtr tmp;
        !          1115:                if (reader->entNr == 0) {
        !          1116:                    while ((tmp = node->last) != NULL) {
        !          1117:                        if ((tmp->extra & NODE_IS_PRESERVED) == 0) {
        !          1118:                            xmlUnlinkNode(tmp);
        !          1119:                            xmlTextReaderFreeNode(reader, tmp);
        !          1120:                        } else
        !          1121:                            break;
        !          1122:                    }
        !          1123:                }
        !          1124:                reader->node = node;
        !          1125:                xmlTextReaderValidatePop(reader);
        !          1126:            }
        !          1127:            if ((node->type == XML_ENTITY_DECL) &&
        !          1128:                (reader->ent != NULL) && (reader->ent->children == node)) {
        !          1129:                node = xmlTextReaderEntPop(reader);
        !          1130:            }
        !          1131:            if (node == oldnode)
        !          1132:                break;
        !          1133:            if (node->next != NULL) {
        !          1134:                node = node->next;
        !          1135:                break;
        !          1136:            }
        !          1137:        } while ((node != NULL) && (node != oldnode));
        !          1138:     } while ((node != NULL) && (node != oldnode));
        !          1139:     reader->node = oldnode;
        !          1140: }
        !          1141: #endif /* LIBXML_REGEXP_ENABLED */
        !          1142: 
        !          1143: 
        !          1144: /**
        !          1145:  * xmlTextReaderGetSuccessor:
        !          1146:  * @cur:  the current node
        !          1147:  *
        !          1148:  * Get the successor of a node if available.
        !          1149:  *
        !          1150:  * Returns the successor node or NULL
        !          1151:  */
        !          1152: static xmlNodePtr
        !          1153: xmlTextReaderGetSuccessor(xmlNodePtr cur) {
        !          1154:     if (cur == NULL) return(NULL) ; /* ERROR */
        !          1155:     if (cur->next != NULL) return(cur->next) ;
        !          1156:     do {
        !          1157:         cur = cur->parent;
        !          1158:         if (cur == NULL) break;
        !          1159:         if (cur->next != NULL) return(cur->next);
        !          1160:     } while (cur != NULL);
        !          1161:     return(cur);
        !          1162: }
        !          1163: 
        !          1164: /**
        !          1165:  * xmlTextReaderDoExpand:
        !          1166:  * @reader:  the xmlTextReaderPtr used
        !          1167:  *
        !          1168:  * Makes sure that the current node is fully read as well as all its
        !          1169:  * descendant. It means the full DOM subtree must be available at the
        !          1170:  * end of the call.
        !          1171:  *
        !          1172:  * Returns 1 if the node was expanded successfully, 0 if there is no more
        !          1173:  *          nodes to read, or -1 in case of error
        !          1174:  */
        !          1175: static int
        !          1176: xmlTextReaderDoExpand(xmlTextReaderPtr reader) {
        !          1177:     int val;
        !          1178: 
        !          1179:     if ((reader == NULL) || (reader->node == NULL) || (reader->ctxt == NULL))
        !          1180:         return(-1);
        !          1181:     do {
        !          1182:        if (reader->ctxt->instate == XML_PARSER_EOF) return(1);
        !          1183: 
        !          1184:         if (xmlTextReaderGetSuccessor(reader->node) != NULL)
        !          1185:            return(1);
        !          1186:        if (reader->ctxt->nodeNr < reader->depth)
        !          1187:            return(1);
        !          1188:        if (reader->mode == XML_TEXTREADER_MODE_EOF)
        !          1189:            return(1);
        !          1190:        val = xmlTextReaderPushData(reader);
        !          1191:        if (val < 0){
        !          1192:            reader->mode = XML_TEXTREADER_MODE_ERROR;
        !          1193:            return(-1);
        !          1194:        }
        !          1195:     } while(reader->mode != XML_TEXTREADER_MODE_EOF);
        !          1196:     return(1);
        !          1197: }
        !          1198: 
        !          1199: /**
        !          1200:  * xmlTextReaderCollectSiblings:
        !          1201:  * @node:    the first child
        !          1202:  *
        !          1203:  *  Traverse depth-first through all sibling nodes and their children
        !          1204:  *  nodes and concatenate their content. This is an auxiliary function
        !          1205:  *  to xmlTextReaderReadString.
        !          1206:  *
        !          1207:  *  Returns a string containing the content, or NULL in case of error.
        !          1208:  */
        !          1209: static xmlChar *
        !          1210: xmlTextReaderCollectSiblings(xmlNodePtr node)
        !          1211: {
        !          1212:     xmlBufferPtr buffer;
        !          1213:     xmlChar *ret;
        !          1214: 
        !          1215:     buffer = xmlBufferCreate();
        !          1216:     if (buffer == NULL)
        !          1217:        return NULL;
        !          1218: 
        !          1219:     for ( ; node != NULL; node = node->next) {
        !          1220:        switch (node->type) {
        !          1221:        case XML_TEXT_NODE:
        !          1222:        case XML_CDATA_SECTION_NODE:
        !          1223:            xmlBufferCat(buffer, node->content);
        !          1224:            break;
        !          1225:        case XML_ELEMENT_NODE: {
        !          1226:            xmlChar *tmp;
        !          1227: 
        !          1228:           tmp = xmlTextReaderCollectSiblings(node->children);
        !          1229:            xmlBufferCat(buffer, tmp);
        !          1230:           xmlFree(tmp);
        !          1231:           break;
        !          1232:        }
        !          1233:        default:
        !          1234:            break;
        !          1235:        }
        !          1236:     }
        !          1237:     ret = buffer->content;
        !          1238:     buffer->content = NULL;
        !          1239:     xmlBufferFree(buffer);
        !          1240:     return(ret);
        !          1241: }
        !          1242: 
        !          1243: /**
        !          1244:  * xmlTextReaderRead:
        !          1245:  * @reader:  the xmlTextReaderPtr used
        !          1246:  *
        !          1247:  *  Moves the position of the current instance to the next node in
        !          1248:  *  the stream, exposing its properties.
        !          1249:  *
        !          1250:  *  Returns 1 if the node was read successfully, 0 if there is no more
        !          1251:  *          nodes to read, or -1 in case of error
        !          1252:  */
        !          1253: int
        !          1254: xmlTextReaderRead(xmlTextReaderPtr reader) {
        !          1255:     int val, olddepth = 0;
        !          1256:     xmlTextReaderState oldstate = XML_TEXTREADER_START;
        !          1257:     xmlNodePtr oldnode = NULL;
        !          1258: 
        !          1259: 
        !          1260:     if (reader == NULL)
        !          1261:        return(-1);
        !          1262:     reader->curnode = NULL;
        !          1263:     if (reader->doc != NULL)
        !          1264:         return(xmlTextReaderReadTree(reader));
        !          1265:     if (reader->ctxt == NULL)
        !          1266:        return(-1);
        !          1267:     if (reader->ctxt->wellFormed != 1)
        !          1268:        return(-1);
        !          1269: 
        !          1270: #ifdef DEBUG_READER
        !          1271:     fprintf(stderr, "\nREAD ");
        !          1272:     DUMP_READER
        !          1273: #endif
        !          1274:     if (reader->mode == XML_TEXTREADER_MODE_INITIAL) {
        !          1275:        reader->mode = XML_TEXTREADER_MODE_INTERACTIVE;
        !          1276:        /*
        !          1277:         * Initial state
        !          1278:         */
        !          1279:        do {
        !          1280:            val = xmlTextReaderPushData(reader);
        !          1281:                if (val < 0){
        !          1282:                        reader->mode = XML_TEXTREADER_MODE_ERROR;
        !          1283:                        reader->state = XML_TEXTREADER_ERROR;
        !          1284:                return(-1);
        !          1285:                }
        !          1286:        } while ((reader->ctxt->node == NULL) &&
        !          1287:                 ((reader->mode != XML_TEXTREADER_MODE_EOF) &&
        !          1288:                  (reader->state != XML_TEXTREADER_DONE)));
        !          1289:        if (reader->ctxt->node == NULL) {
        !          1290:            if (reader->ctxt->myDoc != NULL) {
        !          1291:                reader->node = reader->ctxt->myDoc->children;
        !          1292:            }
        !          1293:            if (reader->node == NULL){
        !          1294:                        reader->mode = XML_TEXTREADER_MODE_ERROR;
        !          1295:                        reader->state = XML_TEXTREADER_ERROR;
        !          1296:                return(-1);
        !          1297:                }
        !          1298:            reader->state = XML_TEXTREADER_ELEMENT;
        !          1299:        } else {
        !          1300:            if (reader->ctxt->myDoc != NULL) {
        !          1301:                reader->node = reader->ctxt->myDoc->children;
        !          1302:            }
        !          1303:            if (reader->node == NULL)
        !          1304:                reader->node = reader->ctxt->nodeTab[0];
        !          1305:            reader->state = XML_TEXTREADER_ELEMENT;
        !          1306:        }
        !          1307:        reader->depth = 0;
        !          1308:        reader->ctxt->parseMode = XML_PARSE_READER;
        !          1309:        goto node_found;
        !          1310:     }
        !          1311:     oldstate = reader->state;
        !          1312:     olddepth = reader->ctxt->nodeNr;
        !          1313:     oldnode = reader->node;
        !          1314: 
        !          1315: get_next_node:
        !          1316:     if (reader->node == NULL) {
        !          1317:        if (reader->mode == XML_TEXTREADER_MODE_EOF)
        !          1318:            return(0);
        !          1319:        else
        !          1320:            return(-1);
        !          1321:     }
        !          1322: 
        !          1323:     /*
        !          1324:      * If we are not backtracking on ancestors or examined nodes,
        !          1325:      * that the parser didn't finished or that we arent at the end
        !          1326:      * of stream, continue processing.
        !          1327:      */
        !          1328:     while ((reader->node != NULL) && (reader->node->next == NULL) &&
        !          1329:           (reader->ctxt->nodeNr == olddepth) &&
        !          1330:            ((oldstate == XML_TEXTREADER_BACKTRACK) ||
        !          1331:             (reader->node->children == NULL) ||
        !          1332:            (reader->node->type == XML_ENTITY_REF_NODE) ||
        !          1333:            ((reader->node->children != NULL) &&
        !          1334:             (reader->node->children->type == XML_TEXT_NODE) &&
        !          1335:             (reader->node->children->next == NULL)) ||
        !          1336:            (reader->node->type == XML_DTD_NODE) ||
        !          1337:            (reader->node->type == XML_DOCUMENT_NODE) ||
        !          1338:            (reader->node->type == XML_HTML_DOCUMENT_NODE)) &&
        !          1339:           ((reader->ctxt->node == NULL) ||
        !          1340:            (reader->ctxt->node == reader->node) ||
        !          1341:            (reader->ctxt->node == reader->node->parent)) &&
        !          1342:           (reader->ctxt->instate != XML_PARSER_EOF)) {
        !          1343:        val = xmlTextReaderPushData(reader);
        !          1344:        if (val < 0){
        !          1345:                reader->mode = XML_TEXTREADER_MODE_ERROR;
        !          1346:                reader->state = XML_TEXTREADER_ERROR;
        !          1347:            return(-1);
        !          1348:        }
        !          1349:        if (reader->node == NULL)
        !          1350:            goto node_end;
        !          1351:     }
        !          1352:     if (oldstate != XML_TEXTREADER_BACKTRACK) {
        !          1353:        if ((reader->node->children != NULL) &&
        !          1354:            (reader->node->type != XML_ENTITY_REF_NODE) &&
        !          1355:            (reader->node->type != XML_XINCLUDE_START) &&
        !          1356:            (reader->node->type != XML_DTD_NODE)) {
        !          1357:            reader->node = reader->node->children;
        !          1358:            reader->depth++;
        !          1359:            reader->state = XML_TEXTREADER_ELEMENT;
        !          1360:            goto node_found;
        !          1361:        }
        !          1362:     }
        !          1363:     if (reader->node->next != NULL) {
        !          1364:        if ((oldstate == XML_TEXTREADER_ELEMENT) &&
        !          1365:             (reader->node->type == XML_ELEMENT_NODE) &&
        !          1366:            (reader->node->children == NULL) &&
        !          1367:            ((reader->node->extra & NODE_IS_EMPTY) == 0)
        !          1368: #ifdef LIBXML_XINCLUDE_ENABLED
        !          1369:            && (reader->in_xinclude <= 0)
        !          1370: #endif
        !          1371:            ) {
        !          1372:            reader->state = XML_TEXTREADER_END;
        !          1373:            goto node_found;
        !          1374:        }
        !          1375: #ifdef LIBXML_REGEXP_ENABLED
        !          1376:        if ((reader->validate) &&
        !          1377:            (reader->node->type == XML_ELEMENT_NODE))
        !          1378:            xmlTextReaderValidatePop(reader);
        !          1379: #endif /* LIBXML_REGEXP_ENABLED */
        !          1380:         if ((reader->preserves > 0) &&
        !          1381:            (reader->node->extra & NODE_IS_SPRESERVED))
        !          1382:            reader->preserves--;
        !          1383:        reader->node = reader->node->next;
        !          1384:        reader->state = XML_TEXTREADER_ELEMENT;
        !          1385: 
        !          1386:        /*
        !          1387:         * Cleanup of the old node
        !          1388:         */
        !          1389:        if ((reader->preserves == 0) &&
        !          1390: #ifdef LIBXML_XINCLUDE_ENABLED
        !          1391:            (reader->in_xinclude == 0) &&
        !          1392: #endif
        !          1393:            (reader->entNr == 0) &&
        !          1394:            (reader->node->prev != NULL) &&
        !          1395:             (reader->node->prev->type != XML_DTD_NODE) &&
        !          1396:            (reader->entNr == 0)) {
        !          1397:            xmlNodePtr tmp = reader->node->prev;
        !          1398:            if ((tmp->extra & NODE_IS_PRESERVED) == 0) {
        !          1399:                xmlUnlinkNode(tmp);
        !          1400:                xmlTextReaderFreeNode(reader, tmp);
        !          1401:            }
        !          1402:        }
        !          1403: 
        !          1404:        goto node_found;
        !          1405:     }
        !          1406:     if ((oldstate == XML_TEXTREADER_ELEMENT) &&
        !          1407:        (reader->node->type == XML_ELEMENT_NODE) &&
        !          1408:        (reader->node->children == NULL) &&
        !          1409:        ((reader->node->extra & NODE_IS_EMPTY) == 0)) {;
        !          1410:        reader->state = XML_TEXTREADER_END;
        !          1411:        goto node_found;
        !          1412:     }
        !          1413: #ifdef LIBXML_REGEXP_ENABLED
        !          1414:     if ((reader->validate) && (reader->node->type == XML_ELEMENT_NODE))
        !          1415:        xmlTextReaderValidatePop(reader);
        !          1416: #endif /* LIBXML_REGEXP_ENABLED */
        !          1417:     if ((reader->preserves > 0) &&
        !          1418:        (reader->node->extra & NODE_IS_SPRESERVED))
        !          1419:        reader->preserves--;
        !          1420:     reader->node = reader->node->parent;
        !          1421:     if ((reader->node == NULL) ||
        !          1422:        (reader->node->type == XML_DOCUMENT_NODE) ||
        !          1423: #ifdef LIBXML_DOCB_ENABLED
        !          1424:        (reader->node->type == XML_DOCB_DOCUMENT_NODE) ||
        !          1425: #endif
        !          1426:        (reader->node->type == XML_HTML_DOCUMENT_NODE)) {
        !          1427:        if (reader->mode != XML_TEXTREADER_MODE_EOF) {
        !          1428:            val = xmlParseChunk(reader->ctxt, "", 0, 1);
        !          1429:            reader->state = XML_TEXTREADER_DONE;
        !          1430:            if (val != 0)
        !          1431:                return(-1);
        !          1432:        }
        !          1433:        reader->node = NULL;
        !          1434:        reader->depth = -1;
        !          1435: 
        !          1436:        /*
        !          1437:         * Cleanup of the old node
        !          1438:         */
        !          1439:        if ((oldnode != NULL) && (reader->preserves == 0) &&
        !          1440: #ifdef LIBXML_XINCLUDE_ENABLED
        !          1441:            (reader->in_xinclude == 0) &&
        !          1442: #endif
        !          1443:            (reader->entNr == 0) &&
        !          1444:            (oldnode->type != XML_DTD_NODE) &&
        !          1445:            ((oldnode->extra & NODE_IS_PRESERVED) == 0) &&
        !          1446:            (reader->entNr == 0)) {
        !          1447:            xmlUnlinkNode(oldnode);
        !          1448:            xmlTextReaderFreeNode(reader, oldnode);
        !          1449:        }
        !          1450: 
        !          1451:        goto node_end;
        !          1452:     }
        !          1453:     if ((reader->preserves == 0) &&
        !          1454: #ifdef LIBXML_XINCLUDE_ENABLED
        !          1455:         (reader->in_xinclude == 0) &&
        !          1456: #endif
        !          1457:        (reader->entNr == 0) &&
        !          1458:         (reader->node->last != NULL) &&
        !          1459:         ((reader->node->last->extra & NODE_IS_PRESERVED) == 0)) {
        !          1460:        xmlNodePtr tmp = reader->node->last;
        !          1461:        xmlUnlinkNode(tmp);
        !          1462:        xmlTextReaderFreeNode(reader, tmp);
        !          1463:     }
        !          1464:     reader->depth--;
        !          1465:     reader->state = XML_TEXTREADER_BACKTRACK;
        !          1466: 
        !          1467: node_found:
        !          1468:     DUMP_READER
        !          1469: 
        !          1470:     /*
        !          1471:      * If we are in the middle of a piece of CDATA make sure it's finished
        !          1472:      */
        !          1473:     if ((reader->node != NULL) &&
        !          1474:         (reader->node->next == NULL) &&
        !          1475:         ((reader->node->type == XML_TEXT_NODE) ||
        !          1476:         (reader->node->type == XML_CDATA_SECTION_NODE))) {
        !          1477:             if (xmlTextReaderExpand(reader) == NULL)
        !          1478:                return -1;
        !          1479:     }
        !          1480: 
        !          1481: #ifdef LIBXML_XINCLUDE_ENABLED
        !          1482:     /*
        !          1483:      * Handle XInclude if asked for
        !          1484:      */
        !          1485:     if ((reader->xinclude) && (reader->node != NULL) &&
        !          1486:        (reader->node->type == XML_ELEMENT_NODE) &&
        !          1487:        (reader->node->ns != NULL) &&
        !          1488:        ((xmlStrEqual(reader->node->ns->href, XINCLUDE_NS)) ||
        !          1489:         (xmlStrEqual(reader->node->ns->href, XINCLUDE_OLD_NS)))) {
        !          1490:        if (reader->xincctxt == NULL) {
        !          1491:            reader->xincctxt = xmlXIncludeNewContext(reader->ctxt->myDoc);
        !          1492:            xmlXIncludeSetFlags(reader->xincctxt,
        !          1493:                                reader->parserFlags & (~XML_PARSE_NOXINCNODE));
        !          1494:        }
        !          1495:        /*
        !          1496:         * expand that node and process it
        !          1497:         */
        !          1498:        if (xmlTextReaderExpand(reader) == NULL)
        !          1499:            return -1;
        !          1500:        xmlXIncludeProcessNode(reader->xincctxt, reader->node);
        !          1501:     }
        !          1502:     if ((reader->node != NULL) && (reader->node->type == XML_XINCLUDE_START)) {
        !          1503:         reader->in_xinclude++;
        !          1504:        goto get_next_node;
        !          1505:     }
        !          1506:     if ((reader->node != NULL) && (reader->node->type == XML_XINCLUDE_END)) {
        !          1507:         reader->in_xinclude--;
        !          1508:        goto get_next_node;
        !          1509:     }
        !          1510: #endif
        !          1511:     /*
        !          1512:      * Handle entities enter and exit when in entity replacement mode
        !          1513:      */
        !          1514:     if ((reader->node != NULL) &&
        !          1515:        (reader->node->type == XML_ENTITY_REF_NODE) &&
        !          1516:        (reader->ctxt != NULL) && (reader->ctxt->replaceEntities == 1)) {
        !          1517:        /*
        !          1518:         * Case where the underlying tree is not availble, lookup the entity
        !          1519:         * and walk it.
        !          1520:         */
        !          1521:        if ((reader->node->children == NULL) && (reader->ctxt->sax != NULL) &&
        !          1522:            (reader->ctxt->sax->getEntity != NULL)) {
        !          1523:            reader->node->children = (xmlNodePtr)
        !          1524:                reader->ctxt->sax->getEntity(reader->ctxt, reader->node->name);
        !          1525:        }
        !          1526: 
        !          1527:        if ((reader->node->children != NULL) &&
        !          1528:            (reader->node->children->type == XML_ENTITY_DECL) &&
        !          1529:            (reader->node->children->children != NULL)) {
        !          1530:            xmlTextReaderEntPush(reader, reader->node);
        !          1531:            reader->node = reader->node->children->children;
        !          1532:        }
        !          1533: #ifdef LIBXML_REGEXP_ENABLED
        !          1534:     } else if ((reader->node != NULL) &&
        !          1535:               (reader->node->type == XML_ENTITY_REF_NODE) &&
        !          1536:               (reader->ctxt != NULL) && (reader->validate)) {
        !          1537:        xmlTextReaderValidateEntity(reader);
        !          1538: #endif /* LIBXML_REGEXP_ENABLED */
        !          1539:     }
        !          1540:     if ((reader->node != NULL) &&
        !          1541:        (reader->node->type == XML_ENTITY_DECL) &&
        !          1542:        (reader->ent != NULL) && (reader->ent->children == reader->node)) {
        !          1543:        reader->node = xmlTextReaderEntPop(reader);
        !          1544:        reader->depth++;
        !          1545:         goto get_next_node;
        !          1546:     }
        !          1547: #ifdef LIBXML_REGEXP_ENABLED
        !          1548:     if ((reader->validate) && (reader->node != NULL)) {
        !          1549:        xmlNodePtr node = reader->node;
        !          1550: 
        !          1551:        if ((node->type == XML_ELEMENT_NODE) &&
        !          1552:             ((reader->state != XML_TEXTREADER_END) &&
        !          1553:             (reader->state != XML_TEXTREADER_BACKTRACK))) {
        !          1554:            xmlTextReaderValidatePush(reader);
        !          1555:        } else if ((node->type == XML_TEXT_NODE) ||
        !          1556:                   (node->type == XML_CDATA_SECTION_NODE)) {
        !          1557:             xmlTextReaderValidateCData(reader, node->content,
        !          1558:                                       xmlStrlen(node->content));
        !          1559:        }
        !          1560:     }
        !          1561: #endif /* LIBXML_REGEXP_ENABLED */
        !          1562: #ifdef LIBXML_PATTERN_ENABLED
        !          1563:     if ((reader->patternNr > 0) && (reader->state != XML_TEXTREADER_END) &&
        !          1564:         (reader->state != XML_TEXTREADER_BACKTRACK)) {
        !          1565:         int i;
        !          1566:        for (i = 0;i < reader->patternNr;i++) {
        !          1567:             if (xmlPatternMatch(reader->patternTab[i], reader->node) == 1) {
        !          1568:                 xmlTextReaderPreserve(reader);
        !          1569:                 break;
        !          1570:              }
        !          1571:        }
        !          1572:     }
        !          1573: #endif /* LIBXML_PATTERN_ENABLED */
        !          1574: #ifdef LIBXML_SCHEMAS_ENABLED
        !          1575:     if ((reader->validate == XML_TEXTREADER_VALIDATE_XSD) &&
        !          1576:         (reader->xsdValidErrors == 0) &&
        !          1577:        (reader->xsdValidCtxt != NULL)) {
        !          1578:        reader->xsdValidErrors = !xmlSchemaIsValid(reader->xsdValidCtxt);
        !          1579:     }
        !          1580: #endif /* LIBXML_PATTERN_ENABLED */
        !          1581:     return(1);
        !          1582: node_end:
        !          1583:     reader->state = XML_TEXTREADER_DONE;
        !          1584:     return(0);
        !          1585: }
        !          1586: 
        !          1587: /**
        !          1588:  * xmlTextReaderReadState:
        !          1589:  * @reader:  the xmlTextReaderPtr used
        !          1590:  *
        !          1591:  * Gets the read state of the reader.
        !          1592:  *
        !          1593:  * Returns the state value, or -1 in case of error
        !          1594:  */
        !          1595: int
        !          1596: xmlTextReaderReadState(xmlTextReaderPtr reader) {
        !          1597:     if (reader == NULL)
        !          1598:        return(-1);
        !          1599:     return(reader->mode);
        !          1600: }
        !          1601: 
        !          1602: /**
        !          1603:  * xmlTextReaderExpand:
        !          1604:  * @reader:  the xmlTextReaderPtr used
        !          1605:  *
        !          1606:  * Reads the contents of the current node and the full subtree. It then makes
        !          1607:  * the subtree available until the next xmlTextReaderRead() call
        !          1608:  *
        !          1609:  * Returns a node pointer valid until the next xmlTextReaderRead() call
        !          1610:  *         or NULL in case of error.
        !          1611:  */
        !          1612: xmlNodePtr
        !          1613: xmlTextReaderExpand(xmlTextReaderPtr reader) {
        !          1614:     if ((reader == NULL) || (reader->node == NULL))
        !          1615:         return(NULL);
        !          1616:     if (reader->doc != NULL)
        !          1617:         return(reader->node);
        !          1618:     if (reader->ctxt == NULL)
        !          1619:         return(NULL);
        !          1620:     if (xmlTextReaderDoExpand(reader) < 0)
        !          1621:         return(NULL);
        !          1622:     return(reader->node);
        !          1623: }
        !          1624: 
        !          1625: /**
        !          1626:  * xmlTextReaderNext:
        !          1627:  * @reader:  the xmlTextReaderPtr used
        !          1628:  *
        !          1629:  * Skip to the node following the current one in document order while
        !          1630:  * avoiding the subtree if any.
        !          1631:  *
        !          1632:  * Returns 1 if the node was read successfully, 0 if there is no more
        !          1633:  *          nodes to read, or -1 in case of error
        !          1634:  */
        !          1635: int
        !          1636: xmlTextReaderNext(xmlTextReaderPtr reader) {
        !          1637:     int ret;
        !          1638:     xmlNodePtr cur;
        !          1639: 
        !          1640:     if (reader == NULL)
        !          1641:        return(-1);
        !          1642:     if (reader->doc != NULL)
        !          1643:         return(xmlTextReaderNextTree(reader));
        !          1644:     cur = reader->node;
        !          1645:     if ((cur == NULL) || (cur->type != XML_ELEMENT_NODE))
        !          1646:         return(xmlTextReaderRead(reader));
        !          1647:     if (reader->state == XML_TEXTREADER_END || reader->state == XML_TEXTREADER_BACKTRACK)
        !          1648:         return(xmlTextReaderRead(reader));
        !          1649:     if (cur->extra & NODE_IS_EMPTY)
        !          1650:         return(xmlTextReaderRead(reader));
        !          1651:     do {
        !          1652:         ret = xmlTextReaderRead(reader);
        !          1653:        if (ret != 1)
        !          1654:            return(ret);
        !          1655:     } while (reader->node != cur);
        !          1656:     return(xmlTextReaderRead(reader));
        !          1657: }
        !          1658: 
        !          1659: #ifdef LIBXML_WRITER_ENABLED
        !          1660: /**
        !          1661:  * xmlTextReaderReadInnerXml:
        !          1662:  * @reader:  the xmlTextReaderPtr used
        !          1663:  *
        !          1664:  * Reads the contents of the current node, including child nodes and markup.
        !          1665:  *
        !          1666:  * Returns a string containing the XML content, or NULL if the current node
        !          1667:  *         is neither an element nor attribute, or has no child nodes. The
        !          1668:  *         string must be deallocated by the caller.
        !          1669:  */
        !          1670: xmlChar *
        !          1671: xmlTextReaderReadInnerXml(xmlTextReaderPtr reader ATTRIBUTE_UNUSED)
        !          1672: {
        !          1673:     xmlChar *resbuf;
        !          1674:     xmlNodePtr node, cur_node;
        !          1675:     xmlBufferPtr buff, buff2;
        !          1676:     xmlDocPtr doc;
        !          1677: 
        !          1678:     if (xmlTextReaderExpand(reader) == NULL) {
        !          1679:         return NULL;
        !          1680:     }
        !          1681:     doc = reader->doc;
        !          1682:     buff = xmlBufferCreate();
        !          1683:     for (cur_node = reader->node->children; cur_node != NULL;
        !          1684:          cur_node = cur_node->next) {
        !          1685:         node = xmlDocCopyNode(cur_node, doc, 1);
        !          1686:         buff2 = xmlBufferCreate();
        !          1687:         if (xmlNodeDump(buff2, doc, node, 0, 0) == -1) {
        !          1688:             xmlFreeNode(node);
        !          1689:             xmlBufferFree(buff2);
        !          1690:             xmlBufferFree(buff);
        !          1691:             return NULL;
        !          1692:         }
        !          1693:         xmlBufferCat(buff, buff2->content);
        !          1694:         xmlFreeNode(node);
        !          1695:         xmlBufferFree(buff2);
        !          1696:     }
        !          1697:     resbuf = buff->content;
        !          1698:     buff->content = NULL;
        !          1699: 
        !          1700:     xmlBufferFree(buff);
        !          1701:     return resbuf;
        !          1702: }
        !          1703: #endif
        !          1704: 
        !          1705: #ifdef LIBXML_WRITER_ENABLED
        !          1706: /**
        !          1707:  * xmlTextReaderReadOuterXml:
        !          1708:  * @reader:  the xmlTextReaderPtr used
        !          1709:  *
        !          1710:  * Reads the contents of the current node, including child nodes and markup.
        !          1711:  *
        !          1712:  * Returns a string containing the node and any XML content, or NULL if the 
        !          1713:  *         current node cannot be serialized. The string must be deallocated 
        !          1714:  *         by the caller.
        !          1715:  */
        !          1716: xmlChar *
        !          1717: xmlTextReaderReadOuterXml(xmlTextReaderPtr reader ATTRIBUTE_UNUSED)
        !          1718: {
        !          1719:     xmlChar *resbuf;
        !          1720:     xmlNodePtr node;
        !          1721:     xmlBufferPtr buff;
        !          1722:     xmlDocPtr doc;
        !          1723: 
        !          1724:     node = reader->node;
        !          1725:     doc = reader->doc;
        !          1726:     if (xmlTextReaderExpand(reader) == NULL) {
        !          1727:         return NULL;
        !          1728:     }
        !          1729:        if (node->type == XML_DTD_NODE) {
        !          1730:                node = (xmlNodePtr) xmlCopyDtd((xmlDtdPtr) node);
        !          1731:        } else {
        !          1732:                node = xmlDocCopyNode(node, doc, 1);
        !          1733:        }
        !          1734:     buff = xmlBufferCreate();
        !          1735:     if (xmlNodeDump(buff, doc, node, 0, 0) == -1) {
        !          1736:         xmlFreeNode(node);
        !          1737:         xmlBufferFree(buff);
        !          1738:         return NULL;
        !          1739:     }
        !          1740: 
        !          1741:     resbuf = buff->content;
        !          1742:     buff->content = NULL;
        !          1743: 
        !          1744:     xmlFreeNode(node);
        !          1745:     xmlBufferFree(buff);
        !          1746:     return resbuf;
        !          1747: }
        !          1748: #endif
        !          1749: 
        !          1750: /**
        !          1751:  * xmlTextReaderReadString:
        !          1752:  * @reader:  the xmlTextReaderPtr used
        !          1753:  *
        !          1754:  * Reads the contents of an element or a text node as a string.
        !          1755:  *
        !          1756:  * Returns a string containing the contents of the Element or Text node,
        !          1757:  *         or NULL if the reader is positioned on any other type of node.
        !          1758:  *         The string must be deallocated by the caller.
        !          1759:  */
        !          1760: xmlChar *
        !          1761: xmlTextReaderReadString(xmlTextReaderPtr reader)
        !          1762: {
        !          1763:     xmlNodePtr node;
        !          1764: 
        !          1765:     if ((reader == NULL) || (reader->node == NULL))
        !          1766:        return(NULL);
        !          1767: 
        !          1768:     node = (reader->curnode != NULL) ? reader->curnode : reader->node;
        !          1769:     switch (node->type) {
        !          1770:     case XML_TEXT_NODE:
        !          1771:        if (node->content != NULL)
        !          1772:            return(xmlStrdup(node->content));
        !          1773:        break;
        !          1774:     case XML_ELEMENT_NODE:
        !          1775:        if (xmlTextReaderDoExpand(reader) != -1) {
        !          1776:            return xmlTextReaderCollectSiblings(node->children);
        !          1777:        }
        !          1778:     case XML_ATTRIBUTE_NODE:
        !          1779:        TODO
        !          1780:        break;
        !          1781:     default:
        !          1782:        break;
        !          1783:     }
        !          1784:     return(NULL);
        !          1785: }
        !          1786: 
        !          1787: #if 0
        !          1788: /**
        !          1789:  * xmlTextReaderReadBase64:
        !          1790:  * @reader:  the xmlTextReaderPtr used
        !          1791:  * @array:  a byte array to store the content.
        !          1792:  * @offset:  the zero-based index into array where the method should
        !          1793:  *           begin to write.
        !          1794:  * @len:  the number of bytes to write.
        !          1795:  *
        !          1796:  * Reads and decodes the Base64 encoded contents of an element and
        !          1797:  * stores the result in a byte buffer.
        !          1798:  *
        !          1799:  * Returns the number of bytes written to array, or zero if the current
        !          1800:  *         instance is not positioned on an element or -1 in case of error.
        !          1801:  */
        !          1802: int
        !          1803: xmlTextReaderReadBase64(xmlTextReaderPtr reader,
        !          1804:                         unsigned char *array ATTRIBUTE_UNUSED,
        !          1805:                        int offset ATTRIBUTE_UNUSED,
        !          1806:                        int len ATTRIBUTE_UNUSED) {
        !          1807:     if ((reader == NULL) || (reader->ctxt == NULL))
        !          1808:        return(-1);
        !          1809:     if (reader->ctxt->wellFormed != 1)
        !          1810:        return(-1);
        !          1811: 
        !          1812:     if ((reader->node == NULL) || (reader->node->type == XML_ELEMENT_NODE))
        !          1813:        return(0);
        !          1814:     TODO
        !          1815:     return(0);
        !          1816: }
        !          1817: 
        !          1818: /**
        !          1819:  * xmlTextReaderReadBinHex:
        !          1820:  * @reader:  the xmlTextReaderPtr used
        !          1821:  * @array:  a byte array to store the content.
        !          1822:  * @offset:  the zero-based index into array where the method should
        !          1823:  *           begin to write.
        !          1824:  * @len:  the number of bytes to write.
        !          1825:  *
        !          1826:  * Reads and decodes the BinHex encoded contents of an element and
        !          1827:  * stores the result in a byte buffer.
        !          1828:  *
        !          1829:  * Returns the number of bytes written to array, or zero if the current
        !          1830:  *         instance is not positioned on an element or -1 in case of error.
        !          1831:  */
        !          1832: int
        !          1833: xmlTextReaderReadBinHex(xmlTextReaderPtr reader,
        !          1834:                         unsigned char *array ATTRIBUTE_UNUSED,
        !          1835:                        int offset ATTRIBUTE_UNUSED,
        !          1836:                        int len ATTRIBUTE_UNUSED) {
        !          1837:     if ((reader == NULL) || (reader->ctxt == NULL))
        !          1838:        return(-1);
        !          1839:     if (reader->ctxt->wellFormed != 1)
        !          1840:        return(-1);
        !          1841: 
        !          1842:     if ((reader->node == NULL) || (reader->node->type == XML_ELEMENT_NODE))
        !          1843:        return(0);
        !          1844:     TODO
        !          1845:     return(0);
        !          1846: }
        !          1847: #endif
        !          1848: 
        !          1849: /************************************************************************
        !          1850:  *                                                                     *
        !          1851:  *                     Operating on a preparsed tree                   *
        !          1852:  *                                                                     *
        !          1853:  ************************************************************************/
        !          1854: static int
        !          1855: xmlTextReaderNextTree(xmlTextReaderPtr reader)
        !          1856: {
        !          1857:     if (reader == NULL)
        !          1858:         return(-1);
        !          1859: 
        !          1860:     if (reader->state == XML_TEXTREADER_END)
        !          1861:         return(0);
        !          1862: 
        !          1863:     if (reader->node == NULL) {
        !          1864:         if (reader->doc->children == NULL) {
        !          1865:             reader->state = XML_TEXTREADER_END;
        !          1866:             return(0);
        !          1867:         }
        !          1868: 
        !          1869:         reader->node = reader->doc->children;
        !          1870:         reader->state = XML_TEXTREADER_START;
        !          1871:         return(1);
        !          1872:     }
        !          1873: 
        !          1874:     if (reader->state != XML_TEXTREADER_BACKTRACK) {
        !          1875:        /* Here removed traversal to child, because we want to skip the subtree,
        !          1876:        replace with traversal to sibling to skip subtree */
        !          1877:         if (reader->node->next != 0) {
        !          1878:            /* Move to sibling if present,skipping sub-tree */
        !          1879:             reader->node = reader->node->next;
        !          1880:             reader->state = XML_TEXTREADER_START;
        !          1881:             return(1);
        !          1882:         }
        !          1883: 
        !          1884:        /* if reader->node->next is NULL mean no subtree for current node,
        !          1885:        so need to move to sibling of parent node if present */
        !          1886:         if ((reader->node->type == XML_ELEMENT_NODE) ||
        !          1887:             (reader->node->type == XML_ATTRIBUTE_NODE)) {
        !          1888:             reader->state = XML_TEXTREADER_BACKTRACK;
        !          1889:            /* This will move to parent if present */
        !          1890:             xmlTextReaderRead(reader);
        !          1891:         }
        !          1892:     }
        !          1893: 
        !          1894:     if (reader->node->next != 0) {
        !          1895:         reader->node = reader->node->next;
        !          1896:         reader->state = XML_TEXTREADER_START;
        !          1897:         return(1);
        !          1898:     }
        !          1899: 
        !          1900:     if (reader->node->parent != 0) {
        !          1901:         if (reader->node->parent->type == XML_DOCUMENT_NODE) {
        !          1902:             reader->state = XML_TEXTREADER_END;
        !          1903:             return(0);
        !          1904:         }
        !          1905: 
        !          1906:         reader->node = reader->node->parent;
        !          1907:         reader->depth--;
        !          1908:         reader->state = XML_TEXTREADER_BACKTRACK;
        !          1909:        /* Repeat process to move to sibling of parent node if present */
        !          1910:         xmlTextReaderNextTree(reader);
        !          1911:     }
        !          1912: 
        !          1913:     reader->state = XML_TEXTREADER_END;
        !          1914: 
        !          1915:     return(1);
        !          1916: }
        !          1917: 
        !          1918: /**
        !          1919:  * xmlTextReaderReadTree:
        !          1920:  * @reader:  the xmlTextReaderPtr used
        !          1921:  *
        !          1922:  *  Moves the position of the current instance to the next node in
        !          1923:  *  the stream, exposing its properties.
        !          1924:  *
        !          1925:  *  Returns 1 if the node was read successfully, 0 if there is no more
        !          1926:  *          nodes to read, or -1 in case of error
        !          1927:  */
        !          1928: static int
        !          1929: xmlTextReaderReadTree(xmlTextReaderPtr reader) {
        !          1930:     if (reader->state == XML_TEXTREADER_END)
        !          1931:         return(0);
        !          1932: 
        !          1933: next_node:
        !          1934:     if (reader->node == NULL) {
        !          1935:         if (reader->doc->children == NULL) {
        !          1936:             reader->state = XML_TEXTREADER_END;
        !          1937:             return(0);
        !          1938:         }
        !          1939: 
        !          1940:         reader->node = reader->doc->children;
        !          1941:         reader->state = XML_TEXTREADER_START;
        !          1942:         goto found_node;
        !          1943:     }
        !          1944: 
        !          1945:     if ((reader->state != XML_TEXTREADER_BACKTRACK) &&
        !          1946:         (reader->node->type != XML_DTD_NODE) &&
        !          1947:         (reader->node->type != XML_XINCLUDE_START) &&
        !          1948:        (reader->node->type != XML_ENTITY_REF_NODE)) {
        !          1949:         if (reader->node->children != NULL) {
        !          1950:             reader->node = reader->node->children;
        !          1951:             reader->depth++;
        !          1952:             reader->state = XML_TEXTREADER_START;
        !          1953:             goto found_node;
        !          1954:         }
        !          1955: 
        !          1956:         if (reader->node->type == XML_ATTRIBUTE_NODE) {
        !          1957:             reader->state = XML_TEXTREADER_BACKTRACK;
        !          1958:             goto found_node;
        !          1959:         }
        !          1960:     }
        !          1961: 
        !          1962:     if (reader->node->next != NULL) {
        !          1963:         reader->node = reader->node->next;
        !          1964:         reader->state = XML_TEXTREADER_START;
        !          1965:         goto found_node;
        !          1966:     }
        !          1967: 
        !          1968:     if (reader->node->parent != NULL) {
        !          1969:         if ((reader->node->parent->type == XML_DOCUMENT_NODE) ||
        !          1970:            (reader->node->parent->type == XML_HTML_DOCUMENT_NODE)) {
        !          1971:             reader->state = XML_TEXTREADER_END;
        !          1972:             return(0);
        !          1973:         }
        !          1974: 
        !          1975:         reader->node = reader->node->parent;
        !          1976:         reader->depth--;
        !          1977:         reader->state = XML_TEXTREADER_BACKTRACK;
        !          1978:         goto found_node;
        !          1979:     }
        !          1980: 
        !          1981:     reader->state = XML_TEXTREADER_END;
        !          1982: 
        !          1983: found_node:
        !          1984:     if ((reader->node->type == XML_XINCLUDE_START) ||
        !          1985:         (reader->node->type == XML_XINCLUDE_END))
        !          1986:        goto next_node;
        !          1987: 
        !          1988:     return(1);
        !          1989: }
        !          1990: 
        !          1991: /**
        !          1992:  * xmlTextReaderNextSibling:
        !          1993:  * @reader:  the xmlTextReaderPtr used
        !          1994:  *
        !          1995:  * Skip to the node following the current one in document order while
        !          1996:  * avoiding the subtree if any.
        !          1997:  * Currently implemented only for Readers built on a document
        !          1998:  *
        !          1999:  * Returns 1 if the node was read successfully, 0 if there is no more
        !          2000:  *          nodes to read, or -1 in case of error
        !          2001:  */
        !          2002: int
        !          2003: xmlTextReaderNextSibling(xmlTextReaderPtr reader) {
        !          2004:     if (reader == NULL)
        !          2005:         return(-1);
        !          2006:     if (reader->doc == NULL) {
        !          2007:         /* TODO */
        !          2008:        return(-1);
        !          2009:     }
        !          2010: 
        !          2011:     if (reader->state == XML_TEXTREADER_END)
        !          2012:         return(0);
        !          2013: 
        !          2014:     if (reader->node == NULL)
        !          2015:         return(xmlTextReaderNextTree(reader));
        !          2016: 
        !          2017:     if (reader->node->next != NULL) {
        !          2018:         reader->node = reader->node->next;
        !          2019:         reader->state = XML_TEXTREADER_START;
        !          2020:         return(1);
        !          2021:     }
        !          2022: 
        !          2023:     return(0);
        !          2024: }
        !          2025: 
        !          2026: /************************************************************************
        !          2027:  *                                                                     *
        !          2028:  *                     Constructor and destructors                     *
        !          2029:  *                                                                     *
        !          2030:  ************************************************************************/
        !          2031: /**
        !          2032:  * xmlNewTextReader:
        !          2033:  * @input: the xmlParserInputBufferPtr used to read data
        !          2034:  * @URI: the URI information for the source if available
        !          2035:  *
        !          2036:  * Create an xmlTextReader structure fed with @input
        !          2037:  *
        !          2038:  * Returns the new xmlTextReaderPtr or NULL in case of error
        !          2039:  */
        !          2040: xmlTextReaderPtr
        !          2041: xmlNewTextReader(xmlParserInputBufferPtr input, const char *URI) {
        !          2042:     xmlTextReaderPtr ret;
        !          2043: 
        !          2044:     if (input == NULL)
        !          2045:        return(NULL);
        !          2046:     ret = xmlMalloc(sizeof(xmlTextReader));
        !          2047:     if (ret == NULL) {
        !          2048:         xmlGenericError(xmlGenericErrorContext,
        !          2049:                "xmlNewTextReader : malloc failed\n");
        !          2050:        return(NULL);
        !          2051:     }
        !          2052:     memset(ret, 0, sizeof(xmlTextReader));
        !          2053:     ret->doc = NULL;
        !          2054:     ret->entTab = NULL;
        !          2055:     ret->entMax = 0;
        !          2056:     ret->entNr = 0;
        !          2057:     ret->input = input;
        !          2058:     ret->buffer = xmlBufferCreateSize(100);
        !          2059:     if (ret->buffer == NULL) {
        !          2060:         xmlFree(ret);
        !          2061:         xmlGenericError(xmlGenericErrorContext,
        !          2062:                "xmlNewTextReader : malloc failed\n");
        !          2063:        return(NULL);
        !          2064:     }
        !          2065:     ret->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
        !          2066:     if (ret->sax == NULL) {
        !          2067:        xmlBufferFree(ret->buffer);
        !          2068:        xmlFree(ret);
        !          2069:         xmlGenericError(xmlGenericErrorContext,
        !          2070:                "xmlNewTextReader : malloc failed\n");
        !          2071:        return(NULL);
        !          2072:     }
        !          2073:     xmlSAXVersion(ret->sax, 2);
        !          2074:     ret->startElement = ret->sax->startElement;
        !          2075:     ret->sax->startElement = xmlTextReaderStartElement;
        !          2076:     ret->endElement = ret->sax->endElement;
        !          2077:     ret->sax->endElement = xmlTextReaderEndElement;
        !          2078: #ifdef LIBXML_SAX1_ENABLED
        !          2079:     if (ret->sax->initialized == XML_SAX2_MAGIC) {
        !          2080: #endif /* LIBXML_SAX1_ENABLED */
        !          2081:        ret->startElementNs = ret->sax->startElementNs;
        !          2082:        ret->sax->startElementNs = xmlTextReaderStartElementNs;
        !          2083:        ret->endElementNs = ret->sax->endElementNs;
        !          2084:        ret->sax->endElementNs = xmlTextReaderEndElementNs;
        !          2085: #ifdef LIBXML_SAX1_ENABLED
        !          2086:     } else {
        !          2087:        ret->startElementNs = NULL;
        !          2088:        ret->endElementNs = NULL;
        !          2089:     }
        !          2090: #endif /* LIBXML_SAX1_ENABLED */
        !          2091:     ret->characters = ret->sax->characters;
        !          2092:     ret->sax->characters = xmlTextReaderCharacters;
        !          2093:     ret->sax->ignorableWhitespace = xmlTextReaderCharacters;
        !          2094:     ret->cdataBlock = ret->sax->cdataBlock;
        !          2095:     ret->sax->cdataBlock = xmlTextReaderCDataBlock;
        !          2096: 
        !          2097:     ret->mode = XML_TEXTREADER_MODE_INITIAL;
        !          2098:     ret->node = NULL;
        !          2099:     ret->curnode = NULL;
        !          2100:     if (ret->input->buffer->use < 4) {
        !          2101:        xmlParserInputBufferRead(input, 4);
        !          2102:     }
        !          2103:     if (ret->input->buffer->use >= 4) {
        !          2104:        ret->ctxt = xmlCreatePushParserCtxt(ret->sax, NULL,
        !          2105:                        (const char *) ret->input->buffer->content, 4, URI);
        !          2106:        ret->base = 0;
        !          2107:        ret->cur = 4;
        !          2108:     } else {
        !          2109:        ret->ctxt = xmlCreatePushParserCtxt(ret->sax, NULL, NULL, 0, URI);
        !          2110:        ret->base = 0;
        !          2111:        ret->cur = 0;
        !          2112:     }
        !          2113: 
        !          2114:     if (ret->ctxt == NULL) {
        !          2115:         xmlGenericError(xmlGenericErrorContext,
        !          2116:                "xmlNewTextReader : malloc failed\n");
        !          2117:        xmlBufferFree(ret->buffer);
        !          2118:        xmlFree(ret->sax);
        !          2119:        xmlFree(ret);
        !          2120:        return(NULL);
        !          2121:     }
        !          2122:     ret->ctxt->parseMode = XML_PARSE_READER;
        !          2123:     ret->ctxt->_private = ret;
        !          2124:     ret->ctxt->linenumbers = 1;
        !          2125:     ret->ctxt->dictNames = 1;
        !          2126:     ret->allocs = XML_TEXTREADER_CTXT;
        !          2127:     /*
        !          2128:      * use the parser dictionnary to allocate all elements and attributes names
        !          2129:      */
        !          2130:     ret->ctxt->docdict = 1;
        !          2131:     ret->dict = ret->ctxt->dict;
        !          2132: #ifdef LIBXML_XINCLUDE_ENABLED
        !          2133:     ret->xinclude = 0;
        !          2134: #endif
        !          2135: #ifdef LIBXML_PATTERN_ENABLED
        !          2136:     ret->patternMax = 0;
        !          2137:     ret->patternTab = NULL;
        !          2138: #endif
        !          2139:     return(ret);
        !          2140: }
        !          2141: 
        !          2142: /**
        !          2143:  * xmlNewTextReaderFilename:
        !          2144:  * @URI: the URI of the resource to process
        !          2145:  *
        !          2146:  * Create an xmlTextReader structure fed with the resource at @URI
        !          2147:  *
        !          2148:  * Returns the new xmlTextReaderPtr or NULL in case of error
        !          2149:  */
        !          2150: xmlTextReaderPtr
        !          2151: xmlNewTextReaderFilename(const char *URI) {
        !          2152:     xmlParserInputBufferPtr input;
        !          2153:     xmlTextReaderPtr ret;
        !          2154:     char *directory = NULL;
        !          2155: 
        !          2156:     input = xmlParserInputBufferCreateFilename(URI, XML_CHAR_ENCODING_NONE);
        !          2157:     if (input == NULL)
        !          2158:        return(NULL);
        !          2159:     ret = xmlNewTextReader(input, URI);
        !          2160:     if (ret == NULL) {
        !          2161:        xmlFreeParserInputBuffer(input);
        !          2162:        return(NULL);
        !          2163:     }
        !          2164:     ret->allocs |= XML_TEXTREADER_INPUT;
        !          2165:     if (ret->ctxt->directory == NULL)
        !          2166:         directory = xmlParserGetDirectory(URI);
        !          2167:     if ((ret->ctxt->directory == NULL) && (directory != NULL))
        !          2168:         ret->ctxt->directory = (char *) xmlStrdup((xmlChar *) directory);
        !          2169:     if (directory != NULL)
        !          2170:        xmlFree(directory);
        !          2171:     return(ret);
        !          2172: }
        !          2173: 
        !          2174: /**
        !          2175:  * xmlFreeTextReader:
        !          2176:  * @reader:  the xmlTextReaderPtr
        !          2177:  *
        !          2178:  * Deallocate all the resources associated to the reader
        !          2179:  */
        !          2180: void
        !          2181: xmlFreeTextReader(xmlTextReaderPtr reader) {
        !          2182:     if (reader == NULL)
        !          2183:        return;
        !          2184: #ifdef LIBXML_SCHEMAS_ENABLED
        !          2185:     if (reader->rngSchemas != NULL) {
        !          2186:        xmlRelaxNGFree(reader->rngSchemas);
        !          2187:        reader->rngSchemas = NULL;
        !          2188:     }
        !          2189:     if (reader->rngValidCtxt != NULL) {
        !          2190:        xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);
        !          2191:        reader->rngValidCtxt = NULL;
        !          2192:     }
        !          2193:     if (reader->xsdPlug != NULL) {
        !          2194:        xmlSchemaSAXUnplug(reader->xsdPlug);
        !          2195:        reader->xsdPlug = NULL;
        !          2196:     }
        !          2197:     if (reader->xsdValidCtxt != NULL) {
        !          2198:        if (! reader->xsdPreserveCtxt)
        !          2199:            xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
        !          2200:        reader->xsdValidCtxt = NULL;
        !          2201:     }
        !          2202:     if (reader->xsdSchemas != NULL) {
        !          2203:        xmlSchemaFree(reader->xsdSchemas);
        !          2204:        reader->xsdSchemas = NULL;
        !          2205:     }
        !          2206: #endif
        !          2207: #ifdef LIBXML_XINCLUDE_ENABLED
        !          2208:     if (reader->xincctxt != NULL)
        !          2209:        xmlXIncludeFreeContext(reader->xincctxt);
        !          2210: #endif
        !          2211: #ifdef LIBXML_PATTERN_ENABLED
        !          2212:     if (reader->patternTab != NULL) {
        !          2213:         int i;
        !          2214:        for (i = 0;i < reader->patternNr;i++) {
        !          2215:            if (reader->patternTab[i] != NULL)
        !          2216:                xmlFreePattern(reader->patternTab[i]);
        !          2217:        }
        !          2218:        xmlFree(reader->patternTab);
        !          2219:     }
        !          2220: #endif
        !          2221:     if (reader->faketext != NULL) {
        !          2222:        xmlFreeNode(reader->faketext);
        !          2223:     }
        !          2224:     if (reader->ctxt != NULL) {
        !          2225:         if (reader->dict == reader->ctxt->dict)
        !          2226:            reader->dict = NULL;
        !          2227:        if (reader->ctxt->myDoc != NULL) {
        !          2228:            if (reader->preserve == 0)
        !          2229:                xmlTextReaderFreeDoc(reader, reader->ctxt->myDoc);
        !          2230:            reader->ctxt->myDoc = NULL;
        !          2231:        }
        !          2232:        if ((reader->ctxt->vctxt.vstateTab != NULL) &&
        !          2233:            (reader->ctxt->vctxt.vstateMax > 0)){
        !          2234:            xmlFree(reader->ctxt->vctxt.vstateTab);
        !          2235:            reader->ctxt->vctxt.vstateTab = NULL;
        !          2236:            reader->ctxt->vctxt.vstateMax = 0;
        !          2237:        }
        !          2238:        if (reader->allocs & XML_TEXTREADER_CTXT)
        !          2239:            xmlFreeParserCtxt(reader->ctxt);
        !          2240:     }
        !          2241:     if (reader->sax != NULL)
        !          2242:        xmlFree(reader->sax);
        !          2243:     if ((reader->input != NULL)  && (reader->allocs & XML_TEXTREADER_INPUT))
        !          2244:        xmlFreeParserInputBuffer(reader->input);
        !          2245:     if (reader->buffer != NULL)
        !          2246:         xmlBufferFree(reader->buffer);
        !          2247:     if (reader->entTab != NULL)
        !          2248:        xmlFree(reader->entTab);
        !          2249:     if (reader->dict != NULL)
        !          2250:         xmlDictFree(reader->dict);
        !          2251:     xmlFree(reader);
        !          2252: }
        !          2253: 
        !          2254: /************************************************************************
        !          2255:  *                                                                     *
        !          2256:  *                     Methods for XmlTextReader                       *
        !          2257:  *                                                                     *
        !          2258:  ************************************************************************/
        !          2259: /**
        !          2260:  * xmlTextReaderClose:
        !          2261:  * @reader:  the xmlTextReaderPtr used
        !          2262:  *
        !          2263:  * This method releases any resources allocated by the current instance
        !          2264:  * changes the state to Closed and close any underlying input.
        !          2265:  *
        !          2266:  * Returns 0 or -1 in case of error
        !          2267:  */
        !          2268: int
        !          2269: xmlTextReaderClose(xmlTextReaderPtr reader) {
        !          2270:     if (reader == NULL)
        !          2271:        return(-1);
        !          2272:     reader->node = NULL;
        !          2273:     reader->curnode = NULL;
        !          2274:     reader->mode = XML_TEXTREADER_MODE_CLOSED;
        !          2275:     if (reader->ctxt != NULL) {
        !          2276:        xmlStopParser(reader->ctxt);
        !          2277:        if (reader->ctxt->myDoc != NULL) {
        !          2278:            if (reader->preserve == 0)
        !          2279:                xmlTextReaderFreeDoc(reader, reader->ctxt->myDoc);
        !          2280:            reader->ctxt->myDoc = NULL;
        !          2281:        }
        !          2282:     }
        !          2283:     if ((reader->input != NULL)  && (reader->allocs & XML_TEXTREADER_INPUT)) {
        !          2284:        xmlFreeParserInputBuffer(reader->input);
        !          2285:        reader->allocs -= XML_TEXTREADER_INPUT;
        !          2286:     }
        !          2287:     return(0);
        !          2288: }
        !          2289: 
        !          2290: /**
        !          2291:  * xmlTextReaderGetAttributeNo:
        !          2292:  * @reader:  the xmlTextReaderPtr used
        !          2293:  * @no: the zero-based index of the attribute relative to the containing element
        !          2294:  *
        !          2295:  * Provides the value of the attribute with the specified index relative
        !          2296:  * to the containing element.
        !          2297:  *
        !          2298:  * Returns a string containing the value of the specified attribute, or NULL
        !          2299:  *    in case of error. The string must be deallocated by the caller.
        !          2300:  */
        !          2301: xmlChar *
        !          2302: xmlTextReaderGetAttributeNo(xmlTextReaderPtr reader, int no) {
        !          2303:     xmlChar *ret;
        !          2304:     int i;
        !          2305:     xmlAttrPtr cur;
        !          2306:     xmlNsPtr ns;
        !          2307: 
        !          2308:     if (reader == NULL)
        !          2309:        return(NULL);
        !          2310:     if (reader->node == NULL)
        !          2311:        return(NULL);
        !          2312:     if (reader->curnode != NULL)
        !          2313:        return(NULL);
        !          2314:     /* TODO: handle the xmlDecl */
        !          2315:     if (reader->node->type != XML_ELEMENT_NODE)
        !          2316:        return(NULL);
        !          2317: 
        !          2318:     ns = reader->node->nsDef;
        !          2319:     for (i = 0;(i < no) && (ns != NULL);i++) {
        !          2320:        ns = ns->next;
        !          2321:     }
        !          2322:     if (ns != NULL)
        !          2323:        return(xmlStrdup(ns->href));
        !          2324: 
        !          2325:     cur = reader->node->properties;
        !          2326:     if (cur == NULL)
        !          2327:        return(NULL);
        !          2328:     for (;i < no;i++) {
        !          2329:        cur = cur->next;
        !          2330:        if (cur == NULL)
        !          2331:            return(NULL);
        !          2332:     }
        !          2333:     /* TODO walk the DTD if present */
        !          2334: 
        !          2335:     ret = xmlNodeListGetString(reader->node->doc, cur->children, 1);
        !          2336:     if (ret == NULL) return(xmlStrdup((xmlChar *)""));
        !          2337:     return(ret);
        !          2338: }
        !          2339: 
        !          2340: /**
        !          2341:  * xmlTextReaderGetAttribute:
        !          2342:  * @reader:  the xmlTextReaderPtr used
        !          2343:  * @name: the qualified name of the attribute.
        !          2344:  *
        !          2345:  * Provides the value of the attribute with the specified qualified name.
        !          2346:  *
        !          2347:  * Returns a string containing the value of the specified attribute, or NULL
        !          2348:  *    in case of error. The string must be deallocated by the caller.
        !          2349:  */
        !          2350: xmlChar *
        !          2351: xmlTextReaderGetAttribute(xmlTextReaderPtr reader, const xmlChar *name) {
        !          2352:     xmlChar *prefix = NULL;
        !          2353:     xmlChar *localname;
        !          2354:     xmlNsPtr ns;
        !          2355:     xmlChar *ret = NULL;
        !          2356: 
        !          2357:     if ((reader == NULL) || (name == NULL))
        !          2358:        return(NULL);
        !          2359:     if (reader->node == NULL)
        !          2360:        return(NULL);
        !          2361:     if (reader->curnode != NULL)
        !          2362:        return(NULL);
        !          2363: 
        !          2364:     /* TODO: handle the xmlDecl */
        !          2365:     if (reader->node->type != XML_ELEMENT_NODE)
        !          2366:        return(NULL);
        !          2367: 
        !          2368:     localname = xmlSplitQName2(name, &prefix);
        !          2369:     if (localname == NULL) {
        !          2370:                /*
        !          2371:                 * Namespace default decl
        !          2372:                 */
        !          2373:                if (xmlStrEqual(name, BAD_CAST "xmlns")) {
        !          2374:                        ns = reader->node->nsDef;
        !          2375:                        while (ns != NULL) {
        !          2376:                                if (ns->prefix == NULL) {
        !          2377:                                        return(xmlStrdup(ns->href));
        !          2378:                                }
        !          2379:                                ns = ns->next;
        !          2380:                        }
        !          2381:                        return NULL;
        !          2382:                }
        !          2383:                return(xmlGetNoNsProp(reader->node, name));
        !          2384:        }
        !          2385: 
        !          2386:     /*
        !          2387:      * Namespace default decl
        !          2388:      */
        !          2389:     if (xmlStrEqual(prefix, BAD_CAST "xmlns")) {
        !          2390:                ns = reader->node->nsDef;
        !          2391:                while (ns != NULL) {
        !          2392:                        if ((ns->prefix != NULL) && (xmlStrEqual(ns->prefix, localname))) {
        !          2393:                                ret = xmlStrdup(ns->href);
        !          2394:                                break;
        !          2395:                        }
        !          2396:                        ns = ns->next;
        !          2397:                }
        !          2398:     } else {
        !          2399:                ns = xmlSearchNs(reader->node->doc, reader->node, prefix);
        !          2400:                if (ns != NULL)
        !          2401:                        ret = xmlGetNsProp(reader->node, localname, ns->href);
        !          2402:        }
        !          2403: 
        !          2404:     xmlFree(localname);
        !          2405:     if (prefix != NULL)
        !          2406:         xmlFree(prefix);
        !          2407:     return(ret);
        !          2408: }
        !          2409: 
        !          2410: 
        !          2411: /**
        !          2412:  * xmlTextReaderGetAttributeNs:
        !          2413:  * @reader:  the xmlTextReaderPtr used
        !          2414:  * @localName: the local name of the attribute.
        !          2415:  * @namespaceURI: the namespace URI of the attribute.
        !          2416:  *
        !          2417:  * Provides the value of the specified attribute
        !          2418:  *
        !          2419:  * Returns a string containing the value of the specified attribute, or NULL
        !          2420:  *    in case of error. The string must be deallocated by the caller.
        !          2421:  */
        !          2422: xmlChar *
        !          2423: xmlTextReaderGetAttributeNs(xmlTextReaderPtr reader, const xmlChar *localName,
        !          2424:                            const xmlChar *namespaceURI) {
        !          2425:     xmlChar *prefix = NULL;
        !          2426:     xmlNsPtr ns;
        !          2427: 
        !          2428:     if ((reader == NULL) || (localName == NULL))
        !          2429:        return(NULL);
        !          2430:     if (reader->node == NULL)
        !          2431:        return(NULL);
        !          2432:     if (reader->curnode != NULL)
        !          2433:        return(NULL);
        !          2434: 
        !          2435:     /* TODO: handle the xmlDecl */
        !          2436:     if (reader->node->type != XML_ELEMENT_NODE)
        !          2437:        return(NULL);
        !          2438: 
        !          2439:     if (xmlStrEqual(namespaceURI, BAD_CAST "http://www.w3.org/2000/xmlns/")) {
        !          2440:                if (! xmlStrEqual(localName, BAD_CAST "xmlns")) {
        !          2441:                        prefix = BAD_CAST localName;
        !          2442:                }
        !          2443:                ns = reader->node->nsDef;
        !          2444:                while (ns != NULL) {
        !          2445:                        if ((prefix == NULL && ns->prefix == NULL) ||
        !          2446:                                ((ns->prefix != NULL) && (xmlStrEqual(ns->prefix, localName)))) {
        !          2447:                                return xmlStrdup(ns->href);
        !          2448:                        }
        !          2449:                        ns = ns->next;
        !          2450:                }
        !          2451:                return NULL;
        !          2452:     }
        !          2453: 
        !          2454:     return(xmlGetNsProp(reader->node, localName, namespaceURI));
        !          2455: }
        !          2456: 
        !          2457: /**
        !          2458:  * xmlTextReaderGetRemainder:
        !          2459:  * @reader:  the xmlTextReaderPtr used
        !          2460:  *
        !          2461:  * Method to get the remainder of the buffered XML. this method stops the
        !          2462:  * parser, set its state to End Of File and return the input stream with
        !          2463:  * what is left that the parser did not use.
        !          2464:  *
        !          2465:  * The implementation is not good, the parser certainly procgressed past
        !          2466:  * what's left in reader->input, and there is an allocation problem. Best
        !          2467:  * would be to rewrite it differently.
        !          2468:  *
        !          2469:  * Returns the xmlParserInputBufferPtr attached to the XML or NULL
        !          2470:  *    in case of error.
        !          2471:  */
        !          2472: xmlParserInputBufferPtr
        !          2473: xmlTextReaderGetRemainder(xmlTextReaderPtr reader) {
        !          2474:     xmlParserInputBufferPtr ret = NULL;
        !          2475: 
        !          2476:     if (reader == NULL)
        !          2477:        return(NULL);
        !          2478:     if (reader->node == NULL)
        !          2479:        return(NULL);
        !          2480: 
        !          2481:     reader->node = NULL;
        !          2482:     reader->curnode = NULL;
        !          2483:     reader->mode = XML_TEXTREADER_MODE_EOF;
        !          2484:     if (reader->ctxt != NULL) {
        !          2485:        xmlStopParser(reader->ctxt);
        !          2486:        if (reader->ctxt->myDoc != NULL) {
        !          2487:            if (reader->preserve == 0)
        !          2488:                xmlTextReaderFreeDoc(reader, reader->ctxt->myDoc);
        !          2489:            reader->ctxt->myDoc = NULL;
        !          2490:        }
        !          2491:     }
        !          2492:     if (reader->allocs & XML_TEXTREADER_INPUT) {
        !          2493:        ret = reader->input;
        !          2494:        reader->input = NULL;
        !          2495:        reader->allocs -= XML_TEXTREADER_INPUT;
        !          2496:     } else {
        !          2497:        /*
        !          2498:         * Hum, one may need to duplicate the data structure because
        !          2499:         * without reference counting the input may be freed twice:
        !          2500:         *   - by the layer which allocated it.
        !          2501:         *   - by the layer to which would have been returned to.
        !          2502:         */
        !          2503:        TODO
        !          2504:        return(NULL);
        !          2505:     }
        !          2506:     return(ret);
        !          2507: }
        !          2508: 
        !          2509: /**
        !          2510:  * xmlTextReaderLookupNamespace:
        !          2511:  * @reader:  the xmlTextReaderPtr used
        !          2512:  * @prefix: the prefix whose namespace URI is to be resolved. To return
        !          2513:  *          the default namespace, specify NULL
        !          2514:  *
        !          2515:  * Resolves a namespace prefix in the scope of the current element.
        !          2516:  *
        !          2517:  * Returns a string containing the namespace URI to which the prefix maps
        !          2518:  *    or NULL in case of error. The string must be deallocated by the caller.
        !          2519:  */
        !          2520: xmlChar *
        !          2521: xmlTextReaderLookupNamespace(xmlTextReaderPtr reader, const xmlChar *prefix) {
        !          2522:     xmlNsPtr ns;
        !          2523: 
        !          2524:     if (reader == NULL)
        !          2525:        return(NULL);
        !          2526:     if (reader->node == NULL)
        !          2527:        return(NULL);
        !          2528: 
        !          2529:     ns = xmlSearchNs(reader->node->doc, reader->node, prefix);
        !          2530:     if (ns == NULL)
        !          2531:        return(NULL);
        !          2532:     return(xmlStrdup(ns->href));
        !          2533: }
        !          2534: 
        !          2535: /**
        !          2536:  * xmlTextReaderMoveToAttributeNo:
        !          2537:  * @reader:  the xmlTextReaderPtr used
        !          2538:  * @no: the zero-based index of the attribute relative to the containing
        !          2539:  *      element.
        !          2540:  *
        !          2541:  * Moves the position of the current instance to the attribute with
        !          2542:  * the specified index relative to the containing element.
        !          2543:  *
        !          2544:  * Returns 1 in case of success, -1 in case of error, 0 if not found
        !          2545:  */
        !          2546: int
        !          2547: xmlTextReaderMoveToAttributeNo(xmlTextReaderPtr reader, int no) {
        !          2548:     int i;
        !          2549:     xmlAttrPtr cur;
        !          2550:     xmlNsPtr ns;
        !          2551: 
        !          2552:     if (reader == NULL)
        !          2553:        return(-1);
        !          2554:     if (reader->node == NULL)
        !          2555:        return(-1);
        !          2556:     /* TODO: handle the xmlDecl */
        !          2557:     if (reader->node->type != XML_ELEMENT_NODE)
        !          2558:        return(-1);
        !          2559: 
        !          2560:     reader->curnode = NULL;
        !          2561: 
        !          2562:     ns = reader->node->nsDef;
        !          2563:     for (i = 0;(i < no) && (ns != NULL);i++) {
        !          2564:        ns = ns->next;
        !          2565:     }
        !          2566:     if (ns != NULL) {
        !          2567:        reader->curnode = (xmlNodePtr) ns;
        !          2568:        return(1);
        !          2569:     }
        !          2570: 
        !          2571:     cur = reader->node->properties;
        !          2572:     if (cur == NULL)
        !          2573:        return(0);
        !          2574:     for (;i < no;i++) {
        !          2575:        cur = cur->next;
        !          2576:        if (cur == NULL)
        !          2577:            return(0);
        !          2578:     }
        !          2579:     /* TODO walk the DTD if present */
        !          2580: 
        !          2581:     reader->curnode = (xmlNodePtr) cur;
        !          2582:     return(1);
        !          2583: }
        !          2584: 
        !          2585: /**
        !          2586:  * xmlTextReaderMoveToAttribute:
        !          2587:  * @reader:  the xmlTextReaderPtr used
        !          2588:  * @name: the qualified name of the attribute.
        !          2589:  *
        !          2590:  * Moves the position of the current instance to the attribute with
        !          2591:  * the specified qualified name.
        !          2592:  *
        !          2593:  * Returns 1 in case of success, -1 in case of error, 0 if not found
        !          2594:  */
        !          2595: int
        !          2596: xmlTextReaderMoveToAttribute(xmlTextReaderPtr reader, const xmlChar *name) {
        !          2597:     xmlChar *prefix = NULL;
        !          2598:     xmlChar *localname;
        !          2599:     xmlNsPtr ns;
        !          2600:     xmlAttrPtr prop;
        !          2601: 
        !          2602:     if ((reader == NULL) || (name == NULL))
        !          2603:        return(-1);
        !          2604:     if (reader->node == NULL)
        !          2605:        return(-1);
        !          2606: 
        !          2607:     /* TODO: handle the xmlDecl */
        !          2608:     if (reader->node->type != XML_ELEMENT_NODE)
        !          2609:        return(0);
        !          2610: 
        !          2611:     localname = xmlSplitQName2(name, &prefix);
        !          2612:     if (localname == NULL) {
        !          2613:        /*
        !          2614:         * Namespace default decl
        !          2615:         */
        !          2616:        if (xmlStrEqual(name, BAD_CAST "xmlns")) {
        !          2617:            ns = reader->node->nsDef;
        !          2618:            while (ns != NULL) {
        !          2619:                if (ns->prefix == NULL) {
        !          2620:                    reader->curnode = (xmlNodePtr) ns;
        !          2621:                    return(1);
        !          2622:                }
        !          2623:                ns = ns->next;
        !          2624:            }
        !          2625:            return(0);
        !          2626:        }
        !          2627: 
        !          2628:        prop = reader->node->properties;
        !          2629:        while (prop != NULL) {
        !          2630:            /*
        !          2631:             * One need to have
        !          2632:             *   - same attribute names
        !          2633:             *   - and the attribute carrying that namespace
        !          2634:             */
        !          2635:            if ((xmlStrEqual(prop->name, name)) &&
        !          2636:                ((prop->ns == NULL) || (prop->ns->prefix == NULL))) {
        !          2637:                reader->curnode = (xmlNodePtr) prop;
        !          2638:                return(1);
        !          2639:            }
        !          2640:            prop = prop->next;
        !          2641:        }
        !          2642:        return(0);
        !          2643:     }
        !          2644: 
        !          2645:     /*
        !          2646:      * Namespace default decl
        !          2647:      */
        !          2648:     if (xmlStrEqual(prefix, BAD_CAST "xmlns")) {
        !          2649:        ns = reader->node->nsDef;
        !          2650:        while (ns != NULL) {
        !          2651:            if ((ns->prefix != NULL) && (xmlStrEqual(ns->prefix, localname))) {
        !          2652:                reader->curnode = (xmlNodePtr) ns;
        !          2653:                goto found;
        !          2654:            }
        !          2655:            ns = ns->next;
        !          2656:        }
        !          2657:        goto not_found;
        !          2658:     }
        !          2659:     prop = reader->node->properties;
        !          2660:     while (prop != NULL) {
        !          2661:        /*
        !          2662:         * One need to have
        !          2663:         *   - same attribute names
        !          2664:         *   - and the attribute carrying that namespace
        !          2665:         */
        !          2666:        if ((xmlStrEqual(prop->name, localname)) &&
        !          2667:            (prop->ns != NULL) && (xmlStrEqual(prop->ns->prefix, prefix))) {
        !          2668:            reader->curnode = (xmlNodePtr) prop;
        !          2669:            goto found;
        !          2670:        }
        !          2671:        prop = prop->next;
        !          2672:     }
        !          2673: not_found:
        !          2674:     if (localname != NULL)
        !          2675:         xmlFree(localname);
        !          2676:     if (prefix != NULL)
        !          2677:         xmlFree(prefix);
        !          2678:     return(0);
        !          2679: 
        !          2680: found:
        !          2681:     if (localname != NULL)
        !          2682:         xmlFree(localname);
        !          2683:     if (prefix != NULL)
        !          2684:         xmlFree(prefix);
        !          2685:     return(1);
        !          2686: }
        !          2687: 
        !          2688: /**
        !          2689:  * xmlTextReaderMoveToAttributeNs:
        !          2690:  * @reader:  the xmlTextReaderPtr used
        !          2691:  * @localName:  the local name of the attribute.
        !          2692:  * @namespaceURI:  the namespace URI of the attribute.
        !          2693:  *
        !          2694:  * Moves the position of the current instance to the attribute with the
        !          2695:  * specified local name and namespace URI.
        !          2696:  *
        !          2697:  * Returns 1 in case of success, -1 in case of error, 0 if not found
        !          2698:  */
        !          2699: int
        !          2700: xmlTextReaderMoveToAttributeNs(xmlTextReaderPtr reader,
        !          2701:        const xmlChar *localName, const xmlChar *namespaceURI) {
        !          2702:     xmlAttrPtr prop;
        !          2703:     xmlNodePtr node;
        !          2704:     xmlNsPtr ns;
        !          2705:     xmlChar *prefix = NULL;
        !          2706: 
        !          2707:     if ((reader == NULL) || (localName == NULL) || (namespaceURI == NULL))
        !          2708:        return(-1);
        !          2709:     if (reader->node == NULL)
        !          2710:        return(-1);
        !          2711:     if (reader->node->type != XML_ELEMENT_NODE)
        !          2712:        return(0);
        !          2713:     node = reader->node;
        !          2714: 
        !          2715:     if (xmlStrEqual(namespaceURI, BAD_CAST "http://www.w3.org/2000/xmlns/")) {
        !          2716:                if (! xmlStrEqual(localName, BAD_CAST "xmlns")) {
        !          2717:                        prefix = BAD_CAST localName;
        !          2718:                }
        !          2719:                ns = reader->node->nsDef;
        !          2720:                while (ns != NULL) {
        !          2721:                        if ((prefix == NULL && ns->prefix == NULL) ||
        !          2722:                                ((ns->prefix != NULL) && (xmlStrEqual(ns->prefix, localName)))) {
        !          2723:                                reader->curnode = (xmlNodePtr) ns;
        !          2724:                                return(1);
        !          2725:                        }
        !          2726:                        ns = ns->next;
        !          2727:                }
        !          2728:                return(0);
        !          2729:     }
        !          2730: 
        !          2731:     prop = node->properties;
        !          2732:     while (prop != NULL) {
        !          2733:        /*
        !          2734:         * One need to have
        !          2735:         *   - same attribute names
        !          2736:         *   - and the attribute carrying that namespace
        !          2737:         */
        !          2738:         if (xmlStrEqual(prop->name, localName) &&
        !          2739:            ((prop->ns != NULL) &&
        !          2740:             (xmlStrEqual(prop->ns->href, namespaceURI)))) {
        !          2741:            reader->curnode = (xmlNodePtr) prop;
        !          2742:            return(1);
        !          2743:         }
        !          2744:        prop = prop->next;
        !          2745:     }
        !          2746:     return(0);
        !          2747: }
        !          2748: 
        !          2749: /**
        !          2750:  * xmlTextReaderMoveToFirstAttribute:
        !          2751:  * @reader:  the xmlTextReaderPtr used
        !          2752:  *
        !          2753:  * Moves the position of the current instance to the first attribute
        !          2754:  * associated with the current node.
        !          2755:  *
        !          2756:  * Returns 1 in case of success, -1 in case of error, 0 if not found
        !          2757:  */
        !          2758: int
        !          2759: xmlTextReaderMoveToFirstAttribute(xmlTextReaderPtr reader) {
        !          2760:     if (reader == NULL)
        !          2761:        return(-1);
        !          2762:     if (reader->node == NULL)
        !          2763:        return(-1);
        !          2764:     if (reader->node->type != XML_ELEMENT_NODE)
        !          2765:        return(0);
        !          2766: 
        !          2767:     if (reader->node->nsDef != NULL) {
        !          2768:        reader->curnode = (xmlNodePtr) reader->node->nsDef;
        !          2769:        return(1);
        !          2770:     }
        !          2771:     if (reader->node->properties != NULL) {
        !          2772:        reader->curnode = (xmlNodePtr) reader->node->properties;
        !          2773:        return(1);
        !          2774:     }
        !          2775:     return(0);
        !          2776: }
        !          2777: 
        !          2778: /**
        !          2779:  * xmlTextReaderMoveToNextAttribute:
        !          2780:  * @reader:  the xmlTextReaderPtr used
        !          2781:  *
        !          2782:  * Moves the position of the current instance to the next attribute
        !          2783:  * associated with the current node.
        !          2784:  *
        !          2785:  * Returns 1 in case of success, -1 in case of error, 0 if not found
        !          2786:  */
        !          2787: int
        !          2788: xmlTextReaderMoveToNextAttribute(xmlTextReaderPtr reader) {
        !          2789:     if (reader == NULL)
        !          2790:        return(-1);
        !          2791:     if (reader->node == NULL)
        !          2792:        return(-1);
        !          2793:     if (reader->node->type != XML_ELEMENT_NODE)
        !          2794:        return(0);
        !          2795:     if (reader->curnode == NULL)
        !          2796:        return(xmlTextReaderMoveToFirstAttribute(reader));
        !          2797: 
        !          2798:     if (reader->curnode->type == XML_NAMESPACE_DECL) {
        !          2799:        xmlNsPtr ns = (xmlNsPtr) reader->curnode;
        !          2800:        if (ns->next != NULL) {
        !          2801:            reader->curnode = (xmlNodePtr) ns->next;
        !          2802:            return(1);
        !          2803:        }
        !          2804:        if (reader->node->properties != NULL) {
        !          2805:            reader->curnode = (xmlNodePtr) reader->node->properties;
        !          2806:            return(1);
        !          2807:        }
        !          2808:        return(0);
        !          2809:     } else if ((reader->curnode->type == XML_ATTRIBUTE_NODE) &&
        !          2810:               (reader->curnode->next != NULL)) {
        !          2811:        reader->curnode = reader->curnode->next;
        !          2812:        return(1);
        !          2813:     }
        !          2814:     return(0);
        !          2815: }
        !          2816: 
        !          2817: /**
        !          2818:  * xmlTextReaderMoveToElement:
        !          2819:  * @reader:  the xmlTextReaderPtr used
        !          2820:  *
        !          2821:  * Moves the position of the current instance to the node that
        !          2822:  * contains the current Attribute  node.
        !          2823:  *
        !          2824:  * Returns 1 in case of success, -1 in case of error, 0 if not moved
        !          2825:  */
        !          2826: int
        !          2827: xmlTextReaderMoveToElement(xmlTextReaderPtr reader) {
        !          2828:     if (reader == NULL)
        !          2829:        return(-1);
        !          2830:     if (reader->node == NULL)
        !          2831:        return(-1);
        !          2832:     if (reader->node->type != XML_ELEMENT_NODE)
        !          2833:        return(0);
        !          2834:     if (reader->curnode != NULL) {
        !          2835:        reader->curnode = NULL;
        !          2836:        return(1);
        !          2837:     }
        !          2838:     return(0);
        !          2839: }
        !          2840: 
        !          2841: /**
        !          2842:  * xmlTextReaderReadAttributeValue:
        !          2843:  * @reader:  the xmlTextReaderPtr used
        !          2844:  *
        !          2845:  * Parses an attribute value into one or more Text and EntityReference nodes.
        !          2846:  *
        !          2847:  * Returns 1 in case of success, 0 if the reader was not positionned on an
        !          2848:  *         ttribute node or all the attribute values have been read, or -1
        !          2849:  *         in case of error.
        !          2850:  */
        !          2851: int
        !          2852: xmlTextReaderReadAttributeValue(xmlTextReaderPtr reader) {
        !          2853:     if (reader == NULL)
        !          2854:        return(-1);
        !          2855:     if (reader->node == NULL)
        !          2856:        return(-1);
        !          2857:     if (reader->curnode == NULL)
        !          2858:        return(0);
        !          2859:     if (reader->curnode->type == XML_ATTRIBUTE_NODE) {
        !          2860:        if (reader->curnode->children == NULL)
        !          2861:            return(0);
        !          2862:        reader->curnode = reader->curnode->children;
        !          2863:     } else if (reader->curnode->type == XML_NAMESPACE_DECL) {
        !          2864:        xmlNsPtr ns = (xmlNsPtr) reader->curnode;
        !          2865: 
        !          2866:        if (reader->faketext == NULL) {
        !          2867:            reader->faketext = xmlNewDocText(reader->node->doc,
        !          2868:                                             ns->href);
        !          2869:        } else {
        !          2870:             if ((reader->faketext->content != NULL) &&
        !          2871:                (reader->faketext->content !=
        !          2872:                 (xmlChar *) &(reader->faketext->properties)))
        !          2873:                xmlFree(reader->faketext->content);
        !          2874:            reader->faketext->content = xmlStrdup(ns->href);
        !          2875:        }
        !          2876:        reader->curnode = reader->faketext;
        !          2877:     } else {
        !          2878:        if (reader->curnode->next == NULL)
        !          2879:            return(0);
        !          2880:        reader->curnode = reader->curnode->next;
        !          2881:     }
        !          2882:     return(1);
        !          2883: }
        !          2884: 
        !          2885: /**
        !          2886:  * xmlTextReaderConstEncoding:
        !          2887:  * @reader:  the xmlTextReaderPtr used
        !          2888:  *
        !          2889:  * Determine the encoding of the document being read.
        !          2890:  *
        !          2891:  * Returns a string containing the encoding of the document or NULL in
        !          2892:  * case of error.  The string is deallocated with the reader.
        !          2893:  */
        !          2894: const xmlChar *
        !          2895: xmlTextReaderConstEncoding(xmlTextReaderPtr reader) {
        !          2896:     xmlDocPtr doc = NULL;
        !          2897:     if (reader == NULL)
        !          2898:        return(NULL);
        !          2899:     if (reader->doc != NULL)
        !          2900:         doc = reader->doc;
        !          2901:     else if (reader->ctxt != NULL)
        !          2902:        doc = reader->ctxt->myDoc;
        !          2903:     if (doc == NULL)
        !          2904:        return(NULL);
        !          2905: 
        !          2906:     if (doc->encoding == NULL)
        !          2907:        return(NULL);
        !          2908:     else
        !          2909:       return(CONSTSTR(doc->encoding));
        !          2910: }
        !          2911: 
        !          2912: 
        !          2913: /************************************************************************
        !          2914:  *                                                                     *
        !          2915:  *                     Acces API to the current node                   *
        !          2916:  *                                                                     *
        !          2917:  ************************************************************************/
        !          2918: /**
        !          2919:  * xmlTextReaderAttributeCount:
        !          2920:  * @reader:  the xmlTextReaderPtr used
        !          2921:  *
        !          2922:  * Provides the number of attributes of the current node
        !          2923:  *
        !          2924:  * Returns 0 i no attributes, -1 in case of error or the attribute count
        !          2925:  */
        !          2926: int
        !          2927: xmlTextReaderAttributeCount(xmlTextReaderPtr reader) {
        !          2928:     int ret;
        !          2929:     xmlAttrPtr attr;
        !          2930:     xmlNsPtr ns;
        !          2931:     xmlNodePtr node;
        !          2932: 
        !          2933:     if (reader == NULL)
        !          2934:        return(-1);
        !          2935:     if (reader->node == NULL)
        !          2936:        return(0);
        !          2937: 
        !          2938:     if (reader->curnode != NULL)
        !          2939:        node = reader->curnode;
        !          2940:     else
        !          2941:        node = reader->node;
        !          2942: 
        !          2943:     if (node->type != XML_ELEMENT_NODE)
        !          2944:        return(0);
        !          2945:     if ((reader->state == XML_TEXTREADER_END) ||
        !          2946:        (reader->state == XML_TEXTREADER_BACKTRACK))
        !          2947:        return(0);
        !          2948:     ret = 0;
        !          2949:     attr = node->properties;
        !          2950:     while (attr != NULL) {
        !          2951:        ret++;
        !          2952:        attr = attr->next;
        !          2953:     }
        !          2954:     ns = node->nsDef;
        !          2955:     while (ns != NULL) {
        !          2956:        ret++;
        !          2957:        ns = ns->next;
        !          2958:     }
        !          2959:     return(ret);
        !          2960: }
        !          2961: 
        !          2962: /**
        !          2963:  * xmlTextReaderNodeType:
        !          2964:  * @reader:  the xmlTextReaderPtr used
        !          2965:  *
        !          2966:  * Get the node type of the current node
        !          2967:  * Reference:
        !          2968:  * http://www.gnu.org/software/dotgnu/pnetlib-doc/System/Xml/XmlNodeType.html
        !          2969:  *
        !          2970:  * Returns the xmlNodeType of the current node or -1 in case of error
        !          2971:  */
        !          2972: int
        !          2973: xmlTextReaderNodeType(xmlTextReaderPtr reader) {
        !          2974:     xmlNodePtr node;
        !          2975: 
        !          2976:     if (reader == NULL)
        !          2977:        return(-1);
        !          2978:     if (reader->node == NULL)
        !          2979:        return(XML_READER_TYPE_NONE);
        !          2980:     if (reader->curnode != NULL)
        !          2981:        node = reader->curnode;
        !          2982:     else
        !          2983:        node = reader->node;
        !          2984:     switch (node->type) {
        !          2985:         case XML_ELEMENT_NODE:
        !          2986:            if ((reader->state == XML_TEXTREADER_END) ||
        !          2987:                (reader->state == XML_TEXTREADER_BACKTRACK))
        !          2988:                return(XML_READER_TYPE_END_ELEMENT);
        !          2989:            return(XML_READER_TYPE_ELEMENT);
        !          2990:         case XML_NAMESPACE_DECL:
        !          2991:         case XML_ATTRIBUTE_NODE:
        !          2992:            return(XML_READER_TYPE_ATTRIBUTE);
        !          2993:         case XML_TEXT_NODE:
        !          2994:            if (xmlIsBlankNode(reader->node)) {
        !          2995:                if (xmlNodeGetSpacePreserve(reader->node))
        !          2996:                    return(XML_READER_TYPE_SIGNIFICANT_WHITESPACE);
        !          2997:                else
        !          2998:                    return(XML_READER_TYPE_WHITESPACE);
        !          2999:            } else {
        !          3000:                return(XML_READER_TYPE_TEXT);
        !          3001:            }
        !          3002:         case XML_CDATA_SECTION_NODE:
        !          3003:            return(XML_READER_TYPE_CDATA);
        !          3004:         case XML_ENTITY_REF_NODE:
        !          3005:            return(XML_READER_TYPE_ENTITY_REFERENCE);
        !          3006:         case XML_ENTITY_NODE:
        !          3007:            return(XML_READER_TYPE_ENTITY);
        !          3008:         case XML_PI_NODE:
        !          3009:            return(XML_READER_TYPE_PROCESSING_INSTRUCTION);
        !          3010:         case XML_COMMENT_NODE:
        !          3011:            return(XML_READER_TYPE_COMMENT);
        !          3012:         case XML_DOCUMENT_NODE:
        !          3013:         case XML_HTML_DOCUMENT_NODE:
        !          3014: #ifdef LIBXML_DOCB_ENABLED
        !          3015:         case XML_DOCB_DOCUMENT_NODE:
        !          3016: #endif
        !          3017:            return(XML_READER_TYPE_DOCUMENT);
        !          3018:         case XML_DOCUMENT_FRAG_NODE:
        !          3019:            return(XML_READER_TYPE_DOCUMENT_FRAGMENT);
        !          3020:         case XML_NOTATION_NODE:
        !          3021:            return(XML_READER_TYPE_NOTATION);
        !          3022:         case XML_DOCUMENT_TYPE_NODE:
        !          3023:         case XML_DTD_NODE:
        !          3024:            return(XML_READER_TYPE_DOCUMENT_TYPE);
        !          3025: 
        !          3026:         case XML_ELEMENT_DECL:
        !          3027:         case XML_ATTRIBUTE_DECL:
        !          3028:         case XML_ENTITY_DECL:
        !          3029:         case XML_XINCLUDE_START:
        !          3030:         case XML_XINCLUDE_END:
        !          3031:            return(XML_READER_TYPE_NONE);
        !          3032:     }
        !          3033:     return(-1);
        !          3034: }
        !          3035: 
        !          3036: /**
        !          3037:  * xmlTextReaderIsEmptyElement:
        !          3038:  * @reader:  the xmlTextReaderPtr used
        !          3039:  *
        !          3040:  * Check if the current node is empty
        !          3041:  *
        !          3042:  * Returns 1 if empty, 0 if not and -1 in case of error
        !          3043:  */
        !          3044: int
        !          3045: xmlTextReaderIsEmptyElement(xmlTextReaderPtr reader) {
        !          3046:     if ((reader == NULL) || (reader->node == NULL))
        !          3047:        return(-1);
        !          3048:     if (reader->node->type != XML_ELEMENT_NODE)
        !          3049:        return(0);
        !          3050:     if (reader->curnode != NULL)
        !          3051:        return(0);
        !          3052:     if (reader->node->children != NULL)
        !          3053:        return(0);
        !          3054:     if (reader->state == XML_TEXTREADER_END)
        !          3055:        return(0);
        !          3056:     if (reader->doc != NULL)
        !          3057:         return(1);
        !          3058: #ifdef LIBXML_XINCLUDE_ENABLED
        !          3059:     if (reader->in_xinclude > 0)
        !          3060:         return(1);
        !          3061: #endif
        !          3062:     return((reader->node->extra & NODE_IS_EMPTY) != 0);
        !          3063: }
        !          3064: 
        !          3065: /**
        !          3066:  * xmlTextReaderLocalName:
        !          3067:  * @reader:  the xmlTextReaderPtr used
        !          3068:  *
        !          3069:  * The local name of the node.
        !          3070:  *
        !          3071:  * Returns the local name or NULL if not available,
        !          3072:  *   if non NULL it need to be freed by the caller.
        !          3073:  */
        !          3074: xmlChar *
        !          3075: xmlTextReaderLocalName(xmlTextReaderPtr reader) {
        !          3076:     xmlNodePtr node;
        !          3077:     if ((reader == NULL) || (reader->node == NULL))
        !          3078:        return(NULL);
        !          3079:     if (reader->curnode != NULL)
        !          3080:        node = reader->curnode;
        !          3081:     else
        !          3082:        node = reader->node;
        !          3083:     if (node->type == XML_NAMESPACE_DECL) {
        !          3084:        xmlNsPtr ns = (xmlNsPtr) node;
        !          3085:        if (ns->prefix == NULL)
        !          3086:            return(xmlStrdup(BAD_CAST "xmlns"));
        !          3087:        else
        !          3088:            return(xmlStrdup(ns->prefix));
        !          3089:     }
        !          3090:     if ((node->type != XML_ELEMENT_NODE) &&
        !          3091:        (node->type != XML_ATTRIBUTE_NODE))
        !          3092:        return(xmlTextReaderName(reader));
        !          3093:     return(xmlStrdup(node->name));
        !          3094: }
        !          3095: 
        !          3096: /**
        !          3097:  * xmlTextReaderConstLocalName:
        !          3098:  * @reader:  the xmlTextReaderPtr used
        !          3099:  *
        !          3100:  * The local name of the node.
        !          3101:  *
        !          3102:  * Returns the local name or NULL if not available, the
        !          3103:  *         string will be deallocated with the reader.
        !          3104:  */
        !          3105: const xmlChar *
        !          3106: xmlTextReaderConstLocalName(xmlTextReaderPtr reader) {
        !          3107:     xmlNodePtr node;
        !          3108:     if ((reader == NULL) || (reader->node == NULL))
        !          3109:        return(NULL);
        !          3110:     if (reader->curnode != NULL)
        !          3111:        node = reader->curnode;
        !          3112:     else
        !          3113:        node = reader->node;
        !          3114:     if (node->type == XML_NAMESPACE_DECL) {
        !          3115:        xmlNsPtr ns = (xmlNsPtr) node;
        !          3116:        if (ns->prefix == NULL)
        !          3117:            return(CONSTSTR(BAD_CAST "xmlns"));
        !          3118:        else
        !          3119:            return(ns->prefix);
        !          3120:     }
        !          3121:     if ((node->type != XML_ELEMENT_NODE) &&
        !          3122:        (node->type != XML_ATTRIBUTE_NODE))
        !          3123:        return(xmlTextReaderConstName(reader));
        !          3124:     return(node->name);
        !          3125: }
        !          3126: 
        !          3127: /**
        !          3128:  * xmlTextReaderName:
        !          3129:  * @reader:  the xmlTextReaderPtr used
        !          3130:  *
        !          3131:  * The qualified name of the node, equal to Prefix :LocalName.
        !          3132:  *
        !          3133:  * Returns the local name or NULL if not available,
        !          3134:  *   if non NULL it need to be freed by the caller.
        !          3135:  */
        !          3136: xmlChar *
        !          3137: xmlTextReaderName(xmlTextReaderPtr reader) {
        !          3138:     xmlNodePtr node;
        !          3139:     xmlChar *ret;
        !          3140: 
        !          3141:     if ((reader == NULL) || (reader->node == NULL))
        !          3142:        return(NULL);
        !          3143:     if (reader->curnode != NULL)
        !          3144:        node = reader->curnode;
        !          3145:     else
        !          3146:        node = reader->node;
        !          3147:     switch (node->type) {
        !          3148:         case XML_ELEMENT_NODE:
        !          3149:         case XML_ATTRIBUTE_NODE:
        !          3150:            if ((node->ns == NULL) ||
        !          3151:                (node->ns->prefix == NULL))
        !          3152:                return(xmlStrdup(node->name));
        !          3153: 
        !          3154:            ret = xmlStrdup(node->ns->prefix);
        !          3155:            ret = xmlStrcat(ret, BAD_CAST ":");
        !          3156:            ret = xmlStrcat(ret, node->name);
        !          3157:            return(ret);
        !          3158:         case XML_TEXT_NODE:
        !          3159:            return(xmlStrdup(BAD_CAST "#text"));
        !          3160:         case XML_CDATA_SECTION_NODE:
        !          3161:            return(xmlStrdup(BAD_CAST "#cdata-section"));
        !          3162:         case XML_ENTITY_NODE:
        !          3163:         case XML_ENTITY_REF_NODE:
        !          3164:            return(xmlStrdup(node->name));
        !          3165:         case XML_PI_NODE:
        !          3166:            return(xmlStrdup(node->name));
        !          3167:         case XML_COMMENT_NODE:
        !          3168:            return(xmlStrdup(BAD_CAST "#comment"));
        !          3169:         case XML_DOCUMENT_NODE:
        !          3170:         case XML_HTML_DOCUMENT_NODE:
        !          3171: #ifdef LIBXML_DOCB_ENABLED
        !          3172:         case XML_DOCB_DOCUMENT_NODE:
        !          3173: #endif
        !          3174:            return(xmlStrdup(BAD_CAST "#document"));
        !          3175:         case XML_DOCUMENT_FRAG_NODE:
        !          3176:            return(xmlStrdup(BAD_CAST "#document-fragment"));
        !          3177:         case XML_NOTATION_NODE:
        !          3178:            return(xmlStrdup(node->name));
        !          3179:         case XML_DOCUMENT_TYPE_NODE:
        !          3180:         case XML_DTD_NODE:
        !          3181:            return(xmlStrdup(node->name));
        !          3182:         case XML_NAMESPACE_DECL: {
        !          3183:            xmlNsPtr ns = (xmlNsPtr) node;
        !          3184: 
        !          3185:            ret = xmlStrdup(BAD_CAST "xmlns");
        !          3186:            if (ns->prefix == NULL)
        !          3187:                return(ret);
        !          3188:            ret = xmlStrcat(ret, BAD_CAST ":");
        !          3189:            ret = xmlStrcat(ret, ns->prefix);
        !          3190:            return(ret);
        !          3191:        }
        !          3192: 
        !          3193:         case XML_ELEMENT_DECL:
        !          3194:         case XML_ATTRIBUTE_DECL:
        !          3195:         case XML_ENTITY_DECL:
        !          3196:         case XML_XINCLUDE_START:
        !          3197:         case XML_XINCLUDE_END:
        !          3198:            return(NULL);
        !          3199:     }
        !          3200:     return(NULL);
        !          3201: }
        !          3202: 
        !          3203: /**
        !          3204:  * xmlTextReaderConstName:
        !          3205:  * @reader:  the xmlTextReaderPtr used
        !          3206:  *
        !          3207:  * The qualified name of the node, equal to Prefix :LocalName.
        !          3208:  *
        !          3209:  * Returns the local name or NULL if not available, the string is
        !          3210:  *         deallocated with the reader.
        !          3211:  */
        !          3212: const xmlChar *
        !          3213: xmlTextReaderConstName(xmlTextReaderPtr reader) {
        !          3214:     xmlNodePtr node;
        !          3215: 
        !          3216:     if ((reader == NULL) || (reader->node == NULL))
        !          3217:        return(NULL);
        !          3218:     if (reader->curnode != NULL)
        !          3219:        node = reader->curnode;
        !          3220:     else
        !          3221:        node = reader->node;
        !          3222:     switch (node->type) {
        !          3223:         case XML_ELEMENT_NODE:
        !          3224:         case XML_ATTRIBUTE_NODE:
        !          3225:            if ((node->ns == NULL) ||
        !          3226:                (node->ns->prefix == NULL))
        !          3227:                return(node->name);
        !          3228:            return(CONSTQSTR(node->ns->prefix, node->name));
        !          3229:         case XML_TEXT_NODE:
        !          3230:            return(CONSTSTR(BAD_CAST "#text"));
        !          3231:         case XML_CDATA_SECTION_NODE:
        !          3232:            return(CONSTSTR(BAD_CAST "#cdata-section"));
        !          3233:         case XML_ENTITY_NODE:
        !          3234:         case XML_ENTITY_REF_NODE:
        !          3235:            return(CONSTSTR(node->name));
        !          3236:         case XML_PI_NODE:
        !          3237:            return(CONSTSTR(node->name));
        !          3238:         case XML_COMMENT_NODE:
        !          3239:            return(CONSTSTR(BAD_CAST "#comment"));
        !          3240:         case XML_DOCUMENT_NODE:
        !          3241:         case XML_HTML_DOCUMENT_NODE:
        !          3242: #ifdef LIBXML_DOCB_ENABLED
        !          3243:         case XML_DOCB_DOCUMENT_NODE:
        !          3244: #endif
        !          3245:            return(CONSTSTR(BAD_CAST "#document"));
        !          3246:         case XML_DOCUMENT_FRAG_NODE:
        !          3247:            return(CONSTSTR(BAD_CAST "#document-fragment"));
        !          3248:         case XML_NOTATION_NODE:
        !          3249:            return(CONSTSTR(node->name));
        !          3250:         case XML_DOCUMENT_TYPE_NODE:
        !          3251:         case XML_DTD_NODE:
        !          3252:            return(CONSTSTR(node->name));
        !          3253:         case XML_NAMESPACE_DECL: {
        !          3254:            xmlNsPtr ns = (xmlNsPtr) node;
        !          3255: 
        !          3256:            if (ns->prefix == NULL)
        !          3257:                return(CONSTSTR(BAD_CAST "xmlns"));
        !          3258:            return(CONSTQSTR(BAD_CAST "xmlns", ns->prefix));
        !          3259:        }
        !          3260: 
        !          3261:         case XML_ELEMENT_DECL:
        !          3262:         case XML_ATTRIBUTE_DECL:
        !          3263:         case XML_ENTITY_DECL:
        !          3264:         case XML_XINCLUDE_START:
        !          3265:         case XML_XINCLUDE_END:
        !          3266:            return(NULL);
        !          3267:     }
        !          3268:     return(NULL);
        !          3269: }
        !          3270: 
        !          3271: /**
        !          3272:  * xmlTextReaderPrefix:
        !          3273:  * @reader:  the xmlTextReaderPtr used
        !          3274:  *
        !          3275:  * A shorthand reference to the namespace associated with the node.
        !          3276:  *
        !          3277:  * Returns the prefix or NULL if not available,
        !          3278:  *    if non NULL it need to be freed by the caller.
        !          3279:  */
        !          3280: xmlChar *
        !          3281: xmlTextReaderPrefix(xmlTextReaderPtr reader) {
        !          3282:     xmlNodePtr node;
        !          3283:     if ((reader == NULL) || (reader->node == NULL))
        !          3284:        return(NULL);
        !          3285:     if (reader->curnode != NULL)
        !          3286:        node = reader->curnode;
        !          3287:     else
        !          3288:        node = reader->node;
        !          3289:     if (node->type == XML_NAMESPACE_DECL) {
        !          3290:        xmlNsPtr ns = (xmlNsPtr) node;
        !          3291:        if (ns->prefix == NULL)
        !          3292:            return(NULL);
        !          3293:        return(xmlStrdup(BAD_CAST "xmlns"));
        !          3294:     }
        !          3295:     if ((node->type != XML_ELEMENT_NODE) &&
        !          3296:        (node->type != XML_ATTRIBUTE_NODE))
        !          3297:        return(NULL);
        !          3298:     if ((node->ns != NULL) && (node->ns->prefix != NULL))
        !          3299:        return(xmlStrdup(node->ns->prefix));
        !          3300:     return(NULL);
        !          3301: }
        !          3302: 
        !          3303: /**
        !          3304:  * xmlTextReaderConstPrefix:
        !          3305:  * @reader:  the xmlTextReaderPtr used
        !          3306:  *
        !          3307:  * A shorthand reference to the namespace associated with the node.
        !          3308:  *
        !          3309:  * Returns the prefix or NULL if not available, the string is deallocated
        !          3310:  *         with the reader.
        !          3311:  */
        !          3312: const xmlChar *
        !          3313: xmlTextReaderConstPrefix(xmlTextReaderPtr reader) {
        !          3314:     xmlNodePtr node;
        !          3315:     if ((reader == NULL) || (reader->node == NULL))
        !          3316:        return(NULL);
        !          3317:     if (reader->curnode != NULL)
        !          3318:        node = reader->curnode;
        !          3319:     else
        !          3320:        node = reader->node;
        !          3321:     if (node->type == XML_NAMESPACE_DECL) {
        !          3322:        xmlNsPtr ns = (xmlNsPtr) node;
        !          3323:        if (ns->prefix == NULL)
        !          3324:            return(NULL);
        !          3325:        return(CONSTSTR(BAD_CAST "xmlns"));
        !          3326:     }
        !          3327:     if ((node->type != XML_ELEMENT_NODE) &&
        !          3328:        (node->type != XML_ATTRIBUTE_NODE))
        !          3329:        return(NULL);
        !          3330:     if ((node->ns != NULL) && (node->ns->prefix != NULL))
        !          3331:        return(CONSTSTR(node->ns->prefix));
        !          3332:     return(NULL);
        !          3333: }
        !          3334: 
        !          3335: /**
        !          3336:  * xmlTextReaderNamespaceUri:
        !          3337:  * @reader:  the xmlTextReaderPtr used
        !          3338:  *
        !          3339:  * The URI defining the namespace associated with the node.
        !          3340:  *
        !          3341:  * Returns the namespace URI or NULL if not available,
        !          3342:  *    if non NULL it need to be freed by the caller.
        !          3343:  */
        !          3344: xmlChar *
        !          3345: xmlTextReaderNamespaceUri(xmlTextReaderPtr reader) {
        !          3346:     xmlNodePtr node;
        !          3347:     if ((reader == NULL) || (reader->node == NULL))
        !          3348:        return(NULL);
        !          3349:     if (reader->curnode != NULL)
        !          3350:        node = reader->curnode;
        !          3351:     else
        !          3352:        node = reader->node;
        !          3353:     if (node->type == XML_NAMESPACE_DECL)
        !          3354:        return(xmlStrdup(BAD_CAST "http://www.w3.org/2000/xmlns/"));
        !          3355:     if ((node->type != XML_ELEMENT_NODE) &&
        !          3356:        (node->type != XML_ATTRIBUTE_NODE))
        !          3357:        return(NULL);
        !          3358:     if (node->ns != NULL)
        !          3359:        return(xmlStrdup(node->ns->href));
        !          3360:     return(NULL);
        !          3361: }
        !          3362: 
        !          3363: /**
        !          3364:  * xmlTextReaderConstNamespaceUri:
        !          3365:  * @reader:  the xmlTextReaderPtr used
        !          3366:  *
        !          3367:  * The URI defining the namespace associated with the node.
        !          3368:  *
        !          3369:  * Returns the namespace URI or NULL if not available, the string
        !          3370:  *         will be deallocated with the reader
        !          3371:  */
        !          3372: const xmlChar *
        !          3373: xmlTextReaderConstNamespaceUri(xmlTextReaderPtr reader) {
        !          3374:     xmlNodePtr node;
        !          3375:     if ((reader == NULL) || (reader->node == NULL))
        !          3376:        return(NULL);
        !          3377:     if (reader->curnode != NULL)
        !          3378:        node = reader->curnode;
        !          3379:     else
        !          3380:        node = reader->node;
        !          3381:     if (node->type == XML_NAMESPACE_DECL)
        !          3382:        return(CONSTSTR(BAD_CAST "http://www.w3.org/2000/xmlns/"));
        !          3383:     if ((node->type != XML_ELEMENT_NODE) &&
        !          3384:        (node->type != XML_ATTRIBUTE_NODE))
        !          3385:        return(NULL);
        !          3386:     if (node->ns != NULL)
        !          3387:        return(CONSTSTR(node->ns->href));
        !          3388:     return(NULL);
        !          3389: }
        !          3390: 
        !          3391: /**
        !          3392:  * xmlTextReaderBaseUri:
        !          3393:  * @reader:  the xmlTextReaderPtr used
        !          3394:  *
        !          3395:  * The base URI of the node.
        !          3396:  *
        !          3397:  * Returns the base URI or NULL if not available,
        !          3398:  *    if non NULL it need to be freed by the caller.
        !          3399:  */
        !          3400: xmlChar *
        !          3401: xmlTextReaderBaseUri(xmlTextReaderPtr reader) {
        !          3402:     if ((reader == NULL) || (reader->node == NULL))
        !          3403:        return(NULL);
        !          3404:     return(xmlNodeGetBase(NULL, reader->node));
        !          3405: }
        !          3406: 
        !          3407: /**
        !          3408:  * xmlTextReaderConstBaseUri:
        !          3409:  * @reader:  the xmlTextReaderPtr used
        !          3410:  *
        !          3411:  * The base URI of the node.
        !          3412:  *
        !          3413:  * Returns the base URI or NULL if not available, the string
        !          3414:  *         will be deallocated with the reader
        !          3415:  */
        !          3416: const xmlChar *
        !          3417: xmlTextReaderConstBaseUri(xmlTextReaderPtr reader) {
        !          3418:     xmlChar *tmp;
        !          3419:     const xmlChar *ret;
        !          3420: 
        !          3421:     if ((reader == NULL) || (reader->node == NULL))
        !          3422:        return(NULL);
        !          3423:     tmp = xmlNodeGetBase(NULL, reader->node);
        !          3424:     if (tmp == NULL)
        !          3425:         return(NULL);
        !          3426:     ret = CONSTSTR(tmp);
        !          3427:     xmlFree(tmp);
        !          3428:     return(ret);
        !          3429: }
        !          3430: 
        !          3431: /**
        !          3432:  * xmlTextReaderDepth:
        !          3433:  * @reader:  the xmlTextReaderPtr used
        !          3434:  *
        !          3435:  * The depth of the node in the tree.
        !          3436:  *
        !          3437:  * Returns the depth or -1 in case of error
        !          3438:  */
        !          3439: int
        !          3440: xmlTextReaderDepth(xmlTextReaderPtr reader) {
        !          3441:     if (reader == NULL)
        !          3442:        return(-1);
        !          3443:     if (reader->node == NULL)
        !          3444:        return(0);
        !          3445: 
        !          3446:     if (reader->curnode != NULL) {
        !          3447:        if ((reader->curnode->type == XML_ATTRIBUTE_NODE) ||
        !          3448:            (reader->curnode->type == XML_NAMESPACE_DECL))
        !          3449:            return(reader->depth + 1);
        !          3450:        return(reader->depth + 2);
        !          3451:     }
        !          3452:     return(reader->depth);
        !          3453: }
        !          3454: 
        !          3455: /**
        !          3456:  * xmlTextReaderHasAttributes:
        !          3457:  * @reader:  the xmlTextReaderPtr used
        !          3458:  *
        !          3459:  * Whether the node has attributes.
        !          3460:  *
        !          3461:  * Returns 1 if true, 0 if false, and -1 in case or error
        !          3462:  */
        !          3463: int
        !          3464: xmlTextReaderHasAttributes(xmlTextReaderPtr reader) {
        !          3465:     xmlNodePtr node;
        !          3466:     if (reader == NULL)
        !          3467:        return(-1);
        !          3468:     if (reader->node == NULL)
        !          3469:        return(0);
        !          3470:     if (reader->curnode != NULL)
        !          3471:        node = reader->curnode;
        !          3472:     else
        !          3473:        node = reader->node;
        !          3474: 
        !          3475:     if ((node->type == XML_ELEMENT_NODE) &&
        !          3476:        ((node->properties != NULL) || (node->nsDef != NULL)))
        !          3477:        return(1);
        !          3478:     /* TODO: handle the xmlDecl */
        !          3479:     return(0);
        !          3480: }
        !          3481: 
        !          3482: /**
        !          3483:  * xmlTextReaderHasValue:
        !          3484:  * @reader:  the xmlTextReaderPtr used
        !          3485:  *
        !          3486:  * Whether the node can have a text value.
        !          3487:  *
        !          3488:  * Returns 1 if true, 0 if false, and -1 in case or error
        !          3489:  */
        !          3490: int
        !          3491: xmlTextReaderHasValue(xmlTextReaderPtr reader) {
        !          3492:     xmlNodePtr node;
        !          3493:     if (reader == NULL)
        !          3494:        return(-1);
        !          3495:     if (reader->node == NULL)
        !          3496:        return(0);
        !          3497:     if (reader->curnode != NULL)
        !          3498:        node = reader->curnode;
        !          3499:     else
        !          3500:        node = reader->node;
        !          3501: 
        !          3502:     switch (node->type) {
        !          3503:         case XML_ATTRIBUTE_NODE:
        !          3504:         case XML_TEXT_NODE:
        !          3505:         case XML_CDATA_SECTION_NODE:
        !          3506:         case XML_PI_NODE:
        !          3507:         case XML_COMMENT_NODE:
        !          3508:         case XML_NAMESPACE_DECL:
        !          3509:            return(1);
        !          3510:        default:
        !          3511:            break;
        !          3512:     }
        !          3513:     return(0);
        !          3514: }
        !          3515: 
        !          3516: /**
        !          3517:  * xmlTextReaderValue:
        !          3518:  * @reader:  the xmlTextReaderPtr used
        !          3519:  *
        !          3520:  * Provides the text value of the node if present
        !          3521:  *
        !          3522:  * Returns the string or NULL if not available. The result must be deallocated
        !          3523:  *     with xmlFree()
        !          3524:  */
        !          3525: xmlChar *
        !          3526: xmlTextReaderValue(xmlTextReaderPtr reader) {
        !          3527:     xmlNodePtr node;
        !          3528:     if (reader == NULL)
        !          3529:        return(NULL);
        !          3530:     if (reader->node == NULL)
        !          3531:        return(NULL);
        !          3532:     if (reader->curnode != NULL)
        !          3533:        node = reader->curnode;
        !          3534:     else
        !          3535:        node = reader->node;
        !          3536: 
        !          3537:     switch (node->type) {
        !          3538:         case XML_NAMESPACE_DECL:
        !          3539:            return(xmlStrdup(((xmlNsPtr) node)->href));
        !          3540:         case XML_ATTRIBUTE_NODE:{
        !          3541:            xmlAttrPtr attr = (xmlAttrPtr) node;
        !          3542: 
        !          3543:            if (attr->parent != NULL)
        !          3544:                return (xmlNodeListGetString
        !          3545:                        (attr->parent->doc, attr->children, 1));
        !          3546:            else
        !          3547:                return (xmlNodeListGetString(NULL, attr->children, 1));
        !          3548:            break;
        !          3549:        }
        !          3550:         case XML_TEXT_NODE:
        !          3551:         case XML_CDATA_SECTION_NODE:
        !          3552:         case XML_PI_NODE:
        !          3553:         case XML_COMMENT_NODE:
        !          3554:             if (node->content != NULL)
        !          3555:                 return (xmlStrdup(node->content));
        !          3556:        default:
        !          3557:            break;
        !          3558:     }
        !          3559:     return(NULL);
        !          3560: }
        !          3561: 
        !          3562: /**
        !          3563:  * xmlTextReaderConstValue:
        !          3564:  * @reader:  the xmlTextReaderPtr used
        !          3565:  *
        !          3566:  * Provides the text value of the node if present
        !          3567:  *
        !          3568:  * Returns the string or NULL if not available. The result will be
        !          3569:  *     deallocated on the next Read() operation.
        !          3570:  */
        !          3571: const xmlChar *
        !          3572: xmlTextReaderConstValue(xmlTextReaderPtr reader) {
        !          3573:     xmlNodePtr node;
        !          3574:     if (reader == NULL)
        !          3575:        return(NULL);
        !          3576:     if (reader->node == NULL)
        !          3577:        return(NULL);
        !          3578:     if (reader->curnode != NULL)
        !          3579:        node = reader->curnode;
        !          3580:     else
        !          3581:        node = reader->node;
        !          3582: 
        !          3583:     switch (node->type) {
        !          3584:         case XML_NAMESPACE_DECL:
        !          3585:            return(((xmlNsPtr) node)->href);
        !          3586:         case XML_ATTRIBUTE_NODE:{
        !          3587:            xmlAttrPtr attr = (xmlAttrPtr) node;
        !          3588: 
        !          3589:            if ((attr->children != NULL) &&
        !          3590:                (attr->children->type == XML_TEXT_NODE) &&
        !          3591:                (attr->children->next == NULL))
        !          3592:                return(attr->children->content);
        !          3593:            else {
        !          3594:                if (reader->buffer == NULL)
        !          3595:                    reader->buffer = xmlBufferCreateSize(100);
        !          3596:                if (reader->buffer == NULL) {
        !          3597:                    xmlGenericError(xmlGenericErrorContext,
        !          3598:                                    "xmlTextReaderSetup : malloc failed\n");
        !          3599:                    return (NULL);
        !          3600:                }
        !          3601:                reader->buffer->use = 0;
        !          3602:                xmlNodeBufGetContent(reader->buffer, node);
        !          3603:                return(reader->buffer->content);
        !          3604:            }
        !          3605:            break;
        !          3606:        }
        !          3607:         case XML_TEXT_NODE:
        !          3608:         case XML_CDATA_SECTION_NODE:
        !          3609:         case XML_PI_NODE:
        !          3610:         case XML_COMMENT_NODE:
        !          3611:            return(node->content);
        !          3612:        default:
        !          3613:            break;
        !          3614:     }
        !          3615:     return(NULL);
        !          3616: }
        !          3617: 
        !          3618: /**
        !          3619:  * xmlTextReaderIsDefault:
        !          3620:  * @reader:  the xmlTextReaderPtr used
        !          3621:  *
        !          3622:  * Whether an Attribute  node was generated from the default value
        !          3623:  * defined in the DTD or schema.
        !          3624:  *
        !          3625:  * Returns 0 if not defaulted, 1 if defaulted, and -1 in case of error
        !          3626:  */
        !          3627: int
        !          3628: xmlTextReaderIsDefault(xmlTextReaderPtr reader) {
        !          3629:     if (reader == NULL)
        !          3630:        return(-1);
        !          3631:     return(0);
        !          3632: }
        !          3633: 
        !          3634: /**
        !          3635:  * xmlTextReaderQuoteChar:
        !          3636:  * @reader:  the xmlTextReaderPtr used
        !          3637:  *
        !          3638:  * The quotation mark character used to enclose the value of an attribute.
        !          3639:  *
        !          3640:  * Returns " or ' and -1 in case of error
        !          3641:  */
        !          3642: int
        !          3643: xmlTextReaderQuoteChar(xmlTextReaderPtr reader) {
        !          3644:     if (reader == NULL)
        !          3645:        return(-1);
        !          3646:     /* TODO maybe lookup the attribute value for " first */
        !          3647:     return((int) '"');
        !          3648: }
        !          3649: 
        !          3650: /**
        !          3651:  * xmlTextReaderXmlLang:
        !          3652:  * @reader:  the xmlTextReaderPtr used
        !          3653:  *
        !          3654:  * The xml:lang scope within which the node resides.
        !          3655:  *
        !          3656:  * Returns the xml:lang value or NULL if none exists.,
        !          3657:  *    if non NULL it need to be freed by the caller.
        !          3658:  */
        !          3659: xmlChar *
        !          3660: xmlTextReaderXmlLang(xmlTextReaderPtr reader) {
        !          3661:     if (reader == NULL)
        !          3662:        return(NULL);
        !          3663:     if (reader->node == NULL)
        !          3664:        return(NULL);
        !          3665:     return(xmlNodeGetLang(reader->node));
        !          3666: }
        !          3667: 
        !          3668: /**
        !          3669:  * xmlTextReaderConstXmlLang:
        !          3670:  * @reader:  the xmlTextReaderPtr used
        !          3671:  *
        !          3672:  * The xml:lang scope within which the node resides.
        !          3673:  *
        !          3674:  * Returns the xml:lang value or NULL if none exists.
        !          3675:  */
        !          3676: const xmlChar *
        !          3677: xmlTextReaderConstXmlLang(xmlTextReaderPtr reader) {
        !          3678:     xmlChar *tmp;
        !          3679:     const xmlChar *ret;
        !          3680: 
        !          3681:     if (reader == NULL)
        !          3682:        return(NULL);
        !          3683:     if (reader->node == NULL)
        !          3684:        return(NULL);
        !          3685:     tmp = xmlNodeGetLang(reader->node);
        !          3686:     if (tmp == NULL)
        !          3687:         return(NULL);
        !          3688:     ret = CONSTSTR(tmp);
        !          3689:     xmlFree(tmp);
        !          3690:     return(ret);
        !          3691: }
        !          3692: 
        !          3693: /**
        !          3694:  * xmlTextReaderConstString:
        !          3695:  * @reader:  the xmlTextReaderPtr used
        !          3696:  * @str:  the string to intern.
        !          3697:  *
        !          3698:  * Get an interned string from the reader, allows for example to
        !          3699:  * speedup string name comparisons
        !          3700:  *
        !          3701:  * Returns an interned copy of the string or NULL in case of error. The
        !          3702:  *         string will be deallocated with the reader.
        !          3703:  */
        !          3704: const xmlChar *
        !          3705: xmlTextReaderConstString(xmlTextReaderPtr reader, const xmlChar *str) {
        !          3706:     if (reader == NULL)
        !          3707:        return(NULL);
        !          3708:     return(CONSTSTR(str));
        !          3709: }
        !          3710: 
        !          3711: /**
        !          3712:  * xmlTextReaderNormalization:
        !          3713:  * @reader:  the xmlTextReaderPtr used
        !          3714:  *
        !          3715:  * The value indicating whether to normalize white space and attribute values.
        !          3716:  * Since attribute value and end of line normalizations are a MUST in the XML
        !          3717:  * specification only the value true is accepted. The broken bahaviour of
        !          3718:  * accepting out of range character entities like &#0; is of course not
        !          3719:  * supported either.
        !          3720:  *
        !          3721:  * Returns 1 or -1 in case of error.
        !          3722:  */
        !          3723: int
        !          3724: xmlTextReaderNormalization(xmlTextReaderPtr reader) {
        !          3725:     if (reader == NULL)
        !          3726:        return(-1);
        !          3727:     return(1);
        !          3728: }
        !          3729: 
        !          3730: /************************************************************************
        !          3731:  *                                                                     *
        !          3732:  *                     Extensions to the base APIs                     *
        !          3733:  *                                                                     *
        !          3734:  ************************************************************************/
        !          3735: 
        !          3736: /**
        !          3737:  * xmlTextReaderSetParserProp:
        !          3738:  * @reader:  the xmlTextReaderPtr used
        !          3739:  * @prop:  the xmlParserProperties to set
        !          3740:  * @value:  usually 0 or 1 to (de)activate it
        !          3741:  *
        !          3742:  * Change the parser processing behaviour by changing some of its internal
        !          3743:  * properties. Note that some properties can only be changed before any
        !          3744:  * read has been done.
        !          3745:  *
        !          3746:  * Returns 0 if the call was successful, or -1 in case of error
        !          3747:  */
        !          3748: int
        !          3749: xmlTextReaderSetParserProp(xmlTextReaderPtr reader, int prop, int value) {
        !          3750:     xmlParserProperties p = (xmlParserProperties) prop;
        !          3751:     xmlParserCtxtPtr ctxt;
        !          3752: 
        !          3753:     if ((reader == NULL) || (reader->ctxt == NULL))
        !          3754:        return(-1);
        !          3755:     ctxt = reader->ctxt;
        !          3756: 
        !          3757:     switch (p) {
        !          3758:         case XML_PARSER_LOADDTD:
        !          3759:            if (value != 0) {
        !          3760:                if (ctxt->loadsubset == 0) {
        !          3761:                    if (reader->mode != XML_TEXTREADER_MODE_INITIAL)
        !          3762:                        return(-1);
        !          3763:                    ctxt->loadsubset = XML_DETECT_IDS;
        !          3764:                }
        !          3765:            } else {
        !          3766:                ctxt->loadsubset = 0;
        !          3767:            }
        !          3768:            return(0);
        !          3769:         case XML_PARSER_DEFAULTATTRS:
        !          3770:            if (value != 0) {
        !          3771:                ctxt->loadsubset |= XML_COMPLETE_ATTRS;
        !          3772:            } else {
        !          3773:                if (ctxt->loadsubset & XML_COMPLETE_ATTRS)
        !          3774:                    ctxt->loadsubset -= XML_COMPLETE_ATTRS;
        !          3775:            }
        !          3776:            return(0);
        !          3777:         case XML_PARSER_VALIDATE:
        !          3778:            if (value != 0) {
        !          3779:                ctxt->validate = 1;
        !          3780:                reader->validate = XML_TEXTREADER_VALIDATE_DTD;
        !          3781:            } else {
        !          3782:                ctxt->validate = 0;
        !          3783:            }
        !          3784:            return(0);
        !          3785:         case XML_PARSER_SUBST_ENTITIES:
        !          3786:            if (value != 0) {
        !          3787:                ctxt->replaceEntities = 1;
        !          3788:            } else {
        !          3789:                ctxt->replaceEntities = 0;
        !          3790:            }
        !          3791:            return(0);
        !          3792:     }
        !          3793:     return(-1);
        !          3794: }
        !          3795: 
        !          3796: /**
        !          3797:  * xmlTextReaderGetParserProp:
        !          3798:  * @reader:  the xmlTextReaderPtr used
        !          3799:  * @prop:  the xmlParserProperties to get
        !          3800:  *
        !          3801:  * Read the parser internal property.
        !          3802:  *
        !          3803:  * Returns the value, usually 0 or 1, or -1 in case of error.
        !          3804:  */
        !          3805: int
        !          3806: xmlTextReaderGetParserProp(xmlTextReaderPtr reader, int prop) {
        !          3807:     xmlParserProperties p = (xmlParserProperties) prop;
        !          3808:     xmlParserCtxtPtr ctxt;
        !          3809: 
        !          3810:     if ((reader == NULL) || (reader->ctxt == NULL))
        !          3811:        return(-1);
        !          3812:     ctxt = reader->ctxt;
        !          3813: 
        !          3814:     switch (p) {
        !          3815:         case XML_PARSER_LOADDTD:
        !          3816:            if ((ctxt->loadsubset != 0) || (ctxt->validate != 0))
        !          3817:                return(1);
        !          3818:            return(0);
        !          3819:         case XML_PARSER_DEFAULTATTRS:
        !          3820:            if (ctxt->loadsubset & XML_COMPLETE_ATTRS)
        !          3821:                return(1);
        !          3822:            return(0);
        !          3823:         case XML_PARSER_VALIDATE:
        !          3824:            return(reader->validate);
        !          3825:        case XML_PARSER_SUBST_ENTITIES:
        !          3826:            return(ctxt->replaceEntities);
        !          3827:     }
        !          3828:     return(-1);
        !          3829: }
        !          3830: 
        !          3831: 
        !          3832: /**
        !          3833:  * xmlTextReaderGetParserLineNumber:
        !          3834:  * @reader: the user data (XML reader context)
        !          3835:  *
        !          3836:  * Provide the line number of the current parsing point.
        !          3837:  *
        !          3838:  * Returns an int or 0 if not available
        !          3839:  */
        !          3840: int
        !          3841: xmlTextReaderGetParserLineNumber(xmlTextReaderPtr reader)
        !          3842: {
        !          3843:     if ((reader == NULL) || (reader->ctxt == NULL) ||
        !          3844:         (reader->ctxt->input == NULL)) {
        !          3845:         return (0);
        !          3846:     }
        !          3847:     return (reader->ctxt->input->line);
        !          3848: }
        !          3849: 
        !          3850: /**
        !          3851:  * xmlTextReaderGetParserColumnNumber:
        !          3852:  * @reader: the user data (XML reader context)
        !          3853:  *
        !          3854:  * Provide the column number of the current parsing point.
        !          3855:  *
        !          3856:  * Returns an int or 0 if not available
        !          3857:  */
        !          3858: int
        !          3859: xmlTextReaderGetParserColumnNumber(xmlTextReaderPtr reader)
        !          3860: {
        !          3861:     if ((reader == NULL) || (reader->ctxt == NULL) ||
        !          3862:         (reader->ctxt->input == NULL)) {
        !          3863:         return (0);
        !          3864:     }
        !          3865:     return (reader->ctxt->input->col);
        !          3866: }
        !          3867: 
        !          3868: /**
        !          3869:  * xmlTextReaderCurrentNode:
        !          3870:  * @reader:  the xmlTextReaderPtr used
        !          3871:  *
        !          3872:  * Hacking interface allowing to get the xmlNodePtr correponding to the
        !          3873:  * current node being accessed by the xmlTextReader. This is dangerous
        !          3874:  * because the underlying node may be destroyed on the next Reads.
        !          3875:  *
        !          3876:  * Returns the xmlNodePtr or NULL in case of error.
        !          3877:  */
        !          3878: xmlNodePtr
        !          3879: xmlTextReaderCurrentNode(xmlTextReaderPtr reader) {
        !          3880:     if (reader == NULL)
        !          3881:        return(NULL);
        !          3882: 
        !          3883:     if (reader->curnode != NULL)
        !          3884:        return(reader->curnode);
        !          3885:     return(reader->node);
        !          3886: }
        !          3887: 
        !          3888: /**
        !          3889:  * xmlTextReaderPreserve:
        !          3890:  * @reader:  the xmlTextReaderPtr used
        !          3891:  *
        !          3892:  * This tells the XML Reader to preserve the current node.
        !          3893:  * The caller must also use xmlTextReaderCurrentDoc() to
        !          3894:  * keep an handle on the resulting document once parsing has finished
        !          3895:  *
        !          3896:  * Returns the xmlNodePtr or NULL in case of error.
        !          3897:  */
        !          3898: xmlNodePtr
        !          3899: xmlTextReaderPreserve(xmlTextReaderPtr reader) {
        !          3900:     xmlNodePtr cur, parent;
        !          3901: 
        !          3902:     if (reader == NULL)
        !          3903:        return(NULL);
        !          3904: 
        !          3905:     if (reader->curnode != NULL)
        !          3906:         cur = reader->curnode;
        !          3907:     else
        !          3908:         cur = reader->node;
        !          3909:     if (cur == NULL)
        !          3910:         return(NULL);
        !          3911: 
        !          3912:     if ((cur->type != XML_DOCUMENT_NODE) && (cur->type != XML_DTD_NODE)) {
        !          3913:        cur->extra |= NODE_IS_PRESERVED;
        !          3914:        cur->extra |= NODE_IS_SPRESERVED;
        !          3915:     }
        !          3916:     reader->preserves++;
        !          3917: 
        !          3918:     parent = cur->parent;;
        !          3919:     while (parent != NULL) {
        !          3920:         if (parent->type == XML_ELEMENT_NODE)
        !          3921:            parent->extra |= NODE_IS_PRESERVED;
        !          3922:        parent = parent->parent;
        !          3923:     }
        !          3924:     return(cur);
        !          3925: }
        !          3926: 
        !          3927: #ifdef LIBXML_PATTERN_ENABLED
        !          3928: /**
        !          3929:  * xmlTextReaderPreservePattern:
        !          3930:  * @reader:  the xmlTextReaderPtr used
        !          3931:  * @pattern:  an XPath subset pattern
        !          3932:  * @namespaces: the prefix definitions, array of [URI, prefix] or NULL
        !          3933:  *
        !          3934:  * This tells the XML Reader to preserve all nodes matched by the
        !          3935:  * pattern. The caller must also use xmlTextReaderCurrentDoc() to
        !          3936:  * keep an handle on the resulting document once parsing has finished
        !          3937:  *
        !          3938:  * Returns a positive number in case of success and -1 in case of error
        !          3939:  */
        !          3940: int
        !          3941: xmlTextReaderPreservePattern(xmlTextReaderPtr reader, const xmlChar *pattern,
        !          3942:                              const xmlChar **namespaces)
        !          3943: {
        !          3944:     xmlPatternPtr comp;
        !          3945: 
        !          3946:     if ((reader == NULL) || (pattern == NULL))
        !          3947:        return(-1);
        !          3948: 
        !          3949:     comp = xmlPatterncompile(pattern, reader->dict, 0, namespaces);
        !          3950:     if (comp == NULL)
        !          3951:         return(-1);
        !          3952: 
        !          3953:     if (reader->patternMax <= 0) {
        !          3954:        reader->patternMax = 4;
        !          3955:        reader->patternTab = (xmlPatternPtr *) xmlMalloc(reader->patternMax *
        !          3956:                                              sizeof(reader->patternTab[0]));
        !          3957:         if (reader->patternTab == NULL) {
        !          3958:             xmlGenericError(xmlGenericErrorContext, "xmlMalloc failed !\n");
        !          3959:             return (-1);
        !          3960:         }
        !          3961:     }
        !          3962:     if (reader->patternNr >= reader->patternMax) {
        !          3963:         xmlPatternPtr *tmp;
        !          3964:         reader->patternMax *= 2;
        !          3965:        tmp = (xmlPatternPtr *) xmlRealloc(reader->patternTab,
        !          3966:                                       reader->patternMax *
        !          3967:                                       sizeof(reader->patternTab[0]));
        !          3968:         if (tmp == NULL) {
        !          3969:             xmlGenericError(xmlGenericErrorContext, "xmlRealloc failed !\n");
        !          3970:            reader->patternMax /= 2;
        !          3971:             return (-1);
        !          3972:         }
        !          3973:        reader->patternTab = tmp;
        !          3974:     }
        !          3975:     reader->patternTab[reader->patternNr] = comp;
        !          3976:     return(reader->patternNr++);
        !          3977: }
        !          3978: #endif
        !          3979: 
        !          3980: /**
        !          3981:  * xmlTextReaderCurrentDoc:
        !          3982:  * @reader:  the xmlTextReaderPtr used
        !          3983:  *
        !          3984:  * Hacking interface allowing to get the xmlDocPtr correponding to the
        !          3985:  * current document being accessed by the xmlTextReader.
        !          3986:  * NOTE: as a result of this call, the reader will not destroy the
        !          3987:  *       associated XML document and calling xmlFreeDoc() on the result
        !          3988:  *       is needed once the reader parsing has finished.
        !          3989:  *
        !          3990:  * Returns the xmlDocPtr or NULL in case of error.
        !          3991:  */
        !          3992: xmlDocPtr
        !          3993: xmlTextReaderCurrentDoc(xmlTextReaderPtr reader) {
        !          3994:     if (reader == NULL)
        !          3995:        return(NULL);
        !          3996:     if (reader->doc != NULL)
        !          3997:         return(reader->doc);
        !          3998:     if ((reader->ctxt == NULL) || (reader->ctxt->myDoc == NULL))
        !          3999:        return(NULL);
        !          4000: 
        !          4001:     reader->preserve = 1;
        !          4002:     return(reader->ctxt->myDoc);
        !          4003: }
        !          4004: 
        !          4005: #ifdef LIBXML_SCHEMAS_ENABLED
        !          4006: static char *xmlTextReaderBuildMessage(const char *msg, va_list ap);
        !          4007: 
        !          4008: static void XMLCDECL
        !          4009: xmlTextReaderValidityError(void *ctxt, const char *msg, ...);
        !          4010: 
        !          4011: static void XMLCDECL
        !          4012: xmlTextReaderValidityWarning(void *ctxt, const char *msg, ...);
        !          4013: 
        !          4014: static void XMLCDECL
        !          4015: xmlTextReaderValidityErrorRelay(void *ctx, const char *msg, ...)
        !          4016: {
        !          4017:     xmlTextReaderPtr reader = (xmlTextReaderPtr) ctx;
        !          4018: 
        !          4019:     char *str;
        !          4020: 
        !          4021:     va_list ap;
        !          4022: 
        !          4023:     va_start(ap, msg);
        !          4024:     str = xmlTextReaderBuildMessage(msg, ap);
        !          4025:     if (!reader->errorFunc) {
        !          4026:         xmlTextReaderValidityError(ctx, "%s", str);
        !          4027:     } else {
        !          4028:         reader->errorFunc(reader->errorFuncArg, str,
        !          4029:                           XML_PARSER_SEVERITY_VALIDITY_ERROR,
        !          4030:                           NULL /* locator */ );
        !          4031:     }
        !          4032:     if (str != NULL)
        !          4033:         xmlFree(str);
        !          4034:     va_end(ap);
        !          4035: }
        !          4036: 
        !          4037: static void XMLCDECL
        !          4038: xmlTextReaderValidityWarningRelay(void *ctx, const char *msg, ...)
        !          4039: {
        !          4040:     xmlTextReaderPtr reader = (xmlTextReaderPtr) ctx;
        !          4041: 
        !          4042:     char *str;
        !          4043: 
        !          4044:     va_list ap;
        !          4045: 
        !          4046:     va_start(ap, msg);
        !          4047:     str = xmlTextReaderBuildMessage(msg, ap);
        !          4048:     if (!reader->errorFunc) {
        !          4049:         xmlTextReaderValidityWarning(ctx, "%s", str);
        !          4050:     } else {
        !          4051:         reader->errorFunc(reader->errorFuncArg, str,
        !          4052:                           XML_PARSER_SEVERITY_VALIDITY_WARNING,
        !          4053:                           NULL /* locator */ );
        !          4054:     }
        !          4055:     if (str != NULL)
        !          4056:         xmlFree(str);
        !          4057:     va_end(ap);
        !          4058: }
        !          4059: 
        !          4060: static void
        !          4061:   xmlTextReaderStructuredError(void *ctxt, xmlErrorPtr error);
        !          4062: 
        !          4063: static void
        !          4064: xmlTextReaderValidityStructuredRelay(void *userData, xmlErrorPtr error)
        !          4065: {
        !          4066:     xmlTextReaderPtr reader = (xmlTextReaderPtr) userData;
        !          4067: 
        !          4068:     if (reader->sErrorFunc) {
        !          4069:         reader->sErrorFunc(reader->errorFuncArg, error);
        !          4070:     } else {
        !          4071:         xmlTextReaderStructuredError(reader, error);
        !          4072:     }
        !          4073: }
        !          4074: /**
        !          4075:  * xmlTextReaderRelaxNGSetSchema:
        !          4076:  * @reader:  the xmlTextReaderPtr used
        !          4077:  * @schema:  a precompiled RelaxNG schema
        !          4078:  *
        !          4079:  * Use RelaxNG to validate the document as it is processed.
        !          4080:  * Activation is only possible before the first Read().
        !          4081:  * if @schema is NULL, then RelaxNG validation is desactivated.
        !          4082:  @ The @schema should not be freed until the reader is deallocated
        !          4083:  * or its use has been deactivated.
        !          4084:  *
        !          4085:  * Returns 0 in case the RelaxNG validation could be (des)activated and
        !          4086:  *         -1 in case of error.
        !          4087:  */
        !          4088: int
        !          4089: xmlTextReaderRelaxNGSetSchema(xmlTextReaderPtr reader, xmlRelaxNGPtr schema) {
        !          4090:     if (reader == NULL)
        !          4091:         return(-1);
        !          4092:     if (schema == NULL) {
        !          4093:         if (reader->rngSchemas != NULL) {
        !          4094:            xmlRelaxNGFree(reader->rngSchemas);
        !          4095:            reader->rngSchemas = NULL;
        !          4096:        }
        !          4097:         if (reader->rngValidCtxt != NULL) {
        !          4098:            xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);
        !          4099:            reader->rngValidCtxt = NULL;
        !          4100:         }
        !          4101:        return(0);
        !          4102:     }
        !          4103:     if (reader->mode != XML_TEXTREADER_MODE_INITIAL)
        !          4104:        return(-1);
        !          4105:     if (reader->rngSchemas != NULL) {
        !          4106:        xmlRelaxNGFree(reader->rngSchemas);
        !          4107:        reader->rngSchemas = NULL;
        !          4108:     }
        !          4109:     if (reader->rngValidCtxt != NULL) {
        !          4110:        xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);
        !          4111:        reader->rngValidCtxt = NULL;
        !          4112:     }
        !          4113:     reader->rngValidCtxt = xmlRelaxNGNewValidCtxt(schema);
        !          4114:     if (reader->rngValidCtxt == NULL)
        !          4115:         return(-1);
        !          4116:     if (reader->errorFunc != NULL) {
        !          4117:        xmlRelaxNGSetValidErrors(reader->rngValidCtxt,
        !          4118:                        xmlTextReaderValidityErrorRelay,
        !          4119:                        xmlTextReaderValidityWarningRelay,
        !          4120:                        reader);
        !          4121:     }
        !          4122:        if (reader->sErrorFunc != NULL) {
        !          4123:                xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,
        !          4124:                        xmlTextReaderValidityStructuredRelay,
        !          4125:                        reader);
        !          4126:     }
        !          4127:     reader->rngValidErrors = 0;
        !          4128:     reader->rngFullNode = NULL;
        !          4129:     reader->validate = XML_TEXTREADER_VALIDATE_RNG;
        !          4130:     return(0);
        !          4131: }
        !          4132: 
        !          4133: /**
        !          4134:  * xmlTextReaderSetSchema:
        !          4135:  * @reader:  the xmlTextReaderPtr used
        !          4136:  * @schema:  a precompiled Schema schema
        !          4137:  *
        !          4138:  * Use XSD Schema to validate the document as it is processed.
        !          4139:  * Activation is only possible before the first Read().
        !          4140:  * if @schema is NULL, then Schema validation is desactivated.
        !          4141:  @ The @schema should not be freed until the reader is deallocated
        !          4142:  * or its use has been deactivated.
        !          4143:  *
        !          4144:  * Returns 0 in case the Schema validation could be (des)activated and
        !          4145:  *         -1 in case of error.
        !          4146:  */
        !          4147: int
        !          4148: xmlTextReaderSetSchema(xmlTextReaderPtr reader, xmlSchemaPtr schema) {
        !          4149:     if (reader == NULL)
        !          4150:         return(-1);
        !          4151:     if (schema == NULL) {
        !          4152:        if (reader->xsdPlug != NULL) {
        !          4153:            xmlSchemaSAXUnplug(reader->xsdPlug);
        !          4154:            reader->xsdPlug = NULL;
        !          4155:        }
        !          4156:         if (reader->xsdValidCtxt != NULL) {
        !          4157:            if (! reader->xsdPreserveCtxt)
        !          4158:                xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
        !          4159:            reader->xsdValidCtxt = NULL;
        !          4160:         }
        !          4161:        reader->xsdPreserveCtxt = 0;
        !          4162:         if (reader->xsdSchemas != NULL) {
        !          4163:            xmlSchemaFree(reader->xsdSchemas);
        !          4164:            reader->xsdSchemas = NULL;
        !          4165:        }
        !          4166:        return(0);
        !          4167:     }
        !          4168:     if (reader->mode != XML_TEXTREADER_MODE_INITIAL)
        !          4169:        return(-1);
        !          4170:     if (reader->xsdPlug != NULL) {
        !          4171:        xmlSchemaSAXUnplug(reader->xsdPlug);
        !          4172:        reader->xsdPlug = NULL;
        !          4173:     }
        !          4174:     if (reader->xsdValidCtxt != NULL) {
        !          4175:        if (! reader->xsdPreserveCtxt)
        !          4176:            xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
        !          4177:        reader->xsdValidCtxt = NULL;
        !          4178:     }
        !          4179:     reader->xsdPreserveCtxt = 0;
        !          4180:     if (reader->xsdSchemas != NULL) {
        !          4181:        xmlSchemaFree(reader->xsdSchemas);
        !          4182:        reader->xsdSchemas = NULL;
        !          4183:     }
        !          4184:     reader->xsdValidCtxt = xmlSchemaNewValidCtxt(schema);
        !          4185:     if (reader->xsdValidCtxt == NULL) {
        !          4186:        xmlSchemaFree(reader->xsdSchemas);
        !          4187:        reader->xsdSchemas = NULL;
        !          4188:         return(-1);
        !          4189:     }
        !          4190:     reader->xsdPlug = xmlSchemaSAXPlug(reader->xsdValidCtxt,
        !          4191:                                        &(reader->ctxt->sax),
        !          4192:                                       &(reader->ctxt->userData));
        !          4193:     if (reader->xsdPlug == NULL) {
        !          4194:        xmlSchemaFree(reader->xsdSchemas);
        !          4195:        reader->xsdSchemas = NULL;
        !          4196:        xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
        !          4197:        reader->xsdValidCtxt = NULL;
        !          4198:        return(-1);
        !          4199:     }
        !          4200:     if (reader->errorFunc != NULL) {
        !          4201:        xmlSchemaSetValidErrors(reader->xsdValidCtxt,
        !          4202:                        xmlTextReaderValidityErrorRelay,
        !          4203:                        xmlTextReaderValidityWarningRelay,
        !          4204:                        reader);
        !          4205:     }
        !          4206:        if (reader->sErrorFunc != NULL) {
        !          4207:                xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt,
        !          4208:                        xmlTextReaderValidityStructuredRelay,
        !          4209:                        reader);
        !          4210:     }
        !          4211:     reader->xsdValidErrors = 0;
        !          4212:     reader->validate = XML_TEXTREADER_VALIDATE_XSD;
        !          4213:     return(0);
        !          4214: }
        !          4215: 
        !          4216: /**
        !          4217:  * xmlTextReaderRelaxNGValidate:
        !          4218:  * @reader:  the xmlTextReaderPtr used
        !          4219:  * @rng:  the path to a RelaxNG schema or NULL
        !          4220:  *
        !          4221:  * Use RelaxNG to validate the document as it is processed.
        !          4222:  * Activation is only possible before the first Read().
        !          4223:  * if @rng is NULL, then RelaxNG validation is deactivated.
        !          4224:  *
        !          4225:  * Returns 0 in case the RelaxNG validation could be (de)activated and
        !          4226:  *         -1 in case of error.
        !          4227:  */
        !          4228: int
        !          4229: xmlTextReaderRelaxNGValidate(xmlTextReaderPtr reader, const char *rng) {
        !          4230:     xmlRelaxNGParserCtxtPtr ctxt;
        !          4231: 
        !          4232:     if (reader == NULL)
        !          4233:         return(-1);
        !          4234: 
        !          4235:     if (rng == NULL) {
        !          4236:         if (reader->rngValidCtxt != NULL) {
        !          4237:            xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);
        !          4238:            reader->rngValidCtxt = NULL;
        !          4239:         }
        !          4240:         if (reader->rngSchemas != NULL) {
        !          4241:            xmlRelaxNGFree(reader->rngSchemas);
        !          4242:            reader->rngSchemas = NULL;
        !          4243:        }
        !          4244:        return(0);
        !          4245:     }
        !          4246:     if (reader->mode != XML_TEXTREADER_MODE_INITIAL)
        !          4247:        return(-1);
        !          4248:     if (reader->rngSchemas != NULL) {
        !          4249:        xmlRelaxNGFree(reader->rngSchemas);
        !          4250:        reader->rngSchemas = NULL;
        !          4251:     }
        !          4252:     if (reader->rngValidCtxt != NULL) {
        !          4253:        xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);
        !          4254:        reader->rngValidCtxt = NULL;
        !          4255:     }
        !          4256:     ctxt = xmlRelaxNGNewParserCtxt(rng);
        !          4257:     if (reader->errorFunc != NULL) {
        !          4258:        xmlRelaxNGSetParserErrors(ctxt,
        !          4259:                         xmlTextReaderValidityErrorRelay,
        !          4260:                         xmlTextReaderValidityWarningRelay,
        !          4261:                         reader);
        !          4262:     }
        !          4263:     if (reader->sErrorFunc != NULL) {
        !          4264:        xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,
        !          4265:                        xmlTextReaderValidityStructuredRelay,
        !          4266:                        reader);
        !          4267:     }
        !          4268:     reader->rngSchemas = xmlRelaxNGParse(ctxt);
        !          4269:     xmlRelaxNGFreeParserCtxt(ctxt);
        !          4270:     if (reader->rngSchemas == NULL)
        !          4271:         return(-1);
        !          4272:     reader->rngValidCtxt = xmlRelaxNGNewValidCtxt(reader->rngSchemas);
        !          4273:     if (reader->rngValidCtxt == NULL) {
        !          4274:        xmlRelaxNGFree(reader->rngSchemas);
        !          4275:        reader->rngSchemas = NULL;
        !          4276:         return(-1);
        !          4277:     }
        !          4278:     if (reader->errorFunc != NULL) {
        !          4279:        xmlRelaxNGSetValidErrors(reader->rngValidCtxt,
        !          4280:                         xmlTextReaderValidityErrorRelay,
        !          4281:                         xmlTextReaderValidityWarningRelay,
        !          4282:                         reader);
        !          4283:     }
        !          4284:        if (reader->sErrorFunc != NULL) {
        !          4285:                xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,
        !          4286:                        xmlTextReaderValidityStructuredRelay,
        !          4287:                        reader);
        !          4288:     }
        !          4289:     reader->rngValidErrors = 0;
        !          4290:     reader->rngFullNode = NULL;
        !          4291:     reader->validate = XML_TEXTREADER_VALIDATE_RNG;
        !          4292:     return(0);
        !          4293: }
        !          4294: 
        !          4295: /**
        !          4296:  * xmlTextReaderSchemaValidateInternal:
        !          4297:  * @reader:  the xmlTextReaderPtr used
        !          4298:  * @xsd:  the path to a W3C XSD schema or NULL
        !          4299:  * @ctxt: the XML Schema validation context or NULL
        !          4300:  * @options: options (not used yet)
        !          4301:  *
        !          4302:  * Validate the document as it is processed using XML Schema.
        !          4303:  * Activation is only possible before the first Read().
        !          4304:  * If both @xsd and @ctxt are NULL then XML Schema validation is deactivated.
        !          4305:  *
        !          4306:  * Returns 0 in case the schemas validation could be (de)activated and
        !          4307:  *         -1 in case of error.
        !          4308:  */
        !          4309: static int
        !          4310: xmlTextReaderSchemaValidateInternal(xmlTextReaderPtr reader,
        !          4311:                                    const char *xsd,
        !          4312:                                    xmlSchemaValidCtxtPtr ctxt,
        !          4313:                                    int options ATTRIBUTE_UNUSED)
        !          4314: {
        !          4315:     if (reader == NULL)
        !          4316:         return(-1);
        !          4317: 
        !          4318:     if ((xsd != NULL) && (ctxt != NULL))
        !          4319:        return(-1);
        !          4320: 
        !          4321:     if (((xsd != NULL) || (ctxt != NULL)) &&
        !          4322:        ((reader->mode != XML_TEXTREADER_MODE_INITIAL) ||
        !          4323:         (reader->ctxt == NULL)))
        !          4324:        return(-1);
        !          4325: 
        !          4326:     /* Cleanup previous validation stuff. */
        !          4327:     if (reader->xsdPlug != NULL) {
        !          4328:        xmlSchemaSAXUnplug(reader->xsdPlug);
        !          4329:        reader->xsdPlug = NULL;
        !          4330:     }
        !          4331:     if (reader->xsdValidCtxt != NULL) {
        !          4332:        if (! reader->xsdPreserveCtxt)
        !          4333:            xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
        !          4334:        reader->xsdValidCtxt = NULL;
        !          4335:     }
        !          4336:     reader->xsdPreserveCtxt = 0;
        !          4337:     if (reader->xsdSchemas != NULL) {
        !          4338:        xmlSchemaFree(reader->xsdSchemas);
        !          4339:        reader->xsdSchemas = NULL;
        !          4340:     }
        !          4341: 
        !          4342:     if ((xsd == NULL) && (ctxt == NULL)) {
        !          4343:        /* We just want to deactivate the validation, so get out. */
        !          4344:        return(0);
        !          4345:     }
        !          4346: 
        !          4347:     if (xsd != NULL) {
        !          4348:        xmlSchemaParserCtxtPtr pctxt;
        !          4349:        /* Parse the schema and create validation environment. */
        !          4350:        pctxt = xmlSchemaNewParserCtxt(xsd);
        !          4351:        if (reader->errorFunc != NULL) {
        !          4352:            xmlSchemaSetParserErrors(pctxt,
        !          4353:                xmlTextReaderValidityErrorRelay,
        !          4354:                xmlTextReaderValidityWarningRelay,
        !          4355:                reader);
        !          4356:        }
        !          4357:        reader->xsdSchemas = xmlSchemaParse(pctxt);
        !          4358:        xmlSchemaFreeParserCtxt(pctxt);
        !          4359:        if (reader->xsdSchemas == NULL)
        !          4360:            return(-1);
        !          4361:        reader->xsdValidCtxt = xmlSchemaNewValidCtxt(reader->xsdSchemas);
        !          4362:        if (reader->xsdValidCtxt == NULL) {
        !          4363:            xmlSchemaFree(reader->xsdSchemas);
        !          4364:            reader->xsdSchemas = NULL;
        !          4365:            return(-1);
        !          4366:        }
        !          4367:        reader->xsdPlug = xmlSchemaSAXPlug(reader->xsdValidCtxt,
        !          4368:            &(reader->ctxt->sax),
        !          4369:            &(reader->ctxt->userData));
        !          4370:        if (reader->xsdPlug == NULL) {
        !          4371:            xmlSchemaFree(reader->xsdSchemas);
        !          4372:            reader->xsdSchemas = NULL;
        !          4373:            xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
        !          4374:            reader->xsdValidCtxt = NULL;
        !          4375:            return(-1);
        !          4376:        }
        !          4377:     } else {
        !          4378:        /* Use the given validation context. */
        !          4379:        reader->xsdValidCtxt = ctxt;
        !          4380:        reader->xsdPreserveCtxt = 1;
        !          4381:        reader->xsdPlug = xmlSchemaSAXPlug(reader->xsdValidCtxt,
        !          4382:            &(reader->ctxt->sax),
        !          4383:            &(reader->ctxt->userData));
        !          4384:        if (reader->xsdPlug == NULL) {
        !          4385:            reader->xsdValidCtxt = NULL;
        !          4386:            reader->xsdPreserveCtxt = 0;
        !          4387:            return(-1);
        !          4388:        }
        !          4389:     }
        !          4390:     /*
        !          4391:     * Redirect the validation context's error channels to use
        !          4392:     * the reader channels.
        !          4393:     * TODO: In case the user provides the validation context we
        !          4394:     *   could make this redirection optional.
        !          4395:     */
        !          4396:     if (reader->errorFunc != NULL) {
        !          4397:        xmlSchemaSetValidErrors(reader->xsdValidCtxt,
        !          4398:                         xmlTextReaderValidityErrorRelay,
        !          4399:                         xmlTextReaderValidityWarningRelay,
        !          4400:                         reader);
        !          4401:     }
        !          4402:        if (reader->sErrorFunc != NULL) {
        !          4403:                xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt,
        !          4404:                        xmlTextReaderValidityStructuredRelay,
        !          4405:                        reader);
        !          4406:     }
        !          4407:     reader->xsdValidErrors = 0;
        !          4408:     reader->validate = XML_TEXTREADER_VALIDATE_XSD;
        !          4409:     return(0);
        !          4410: }
        !          4411: 
        !          4412: /**
        !          4413:  * xmlTextReaderSchemaValidateCtxt:
        !          4414:  * @reader:  the xmlTextReaderPtr used
        !          4415:  * @ctxt: the XML Schema validation context or NULL
        !          4416:  * @options: options (not used yet)
        !          4417:  *
        !          4418:  * Use W3C XSD schema context to validate the document as it is processed.
        !          4419:  * Activation is only possible before the first Read().
        !          4420:  * If @ctxt is NULL, then XML Schema validation is deactivated.
        !          4421:  *
        !          4422:  * Returns 0 in case the schemas validation could be (de)activated and
        !          4423:  *         -1 in case of error.
        !          4424:  */
        !          4425: int
        !          4426: xmlTextReaderSchemaValidateCtxt(xmlTextReaderPtr reader,
        !          4427:                                    xmlSchemaValidCtxtPtr ctxt,
        !          4428:                                    int options)
        !          4429: {
        !          4430:     return(xmlTextReaderSchemaValidateInternal(reader, NULL, ctxt, options));
        !          4431: }
        !          4432: 
        !          4433: /**
        !          4434:  * xmlTextReaderSchemaValidate:
        !          4435:  * @reader:  the xmlTextReaderPtr used
        !          4436:  * @xsd:  the path to a W3C XSD schema or NULL
        !          4437:  *
        !          4438:  * Use W3C XSD schema to validate the document as it is processed.
        !          4439:  * Activation is only possible before the first Read().
        !          4440:  * If @xsd is NULL, then XML Schema validation is deactivated.
        !          4441:  *
        !          4442:  * Returns 0 in case the schemas validation could be (de)activated and
        !          4443:  *         -1 in case of error.
        !          4444:  */
        !          4445: int
        !          4446: xmlTextReaderSchemaValidate(xmlTextReaderPtr reader, const char *xsd)
        !          4447: {
        !          4448:     return(xmlTextReaderSchemaValidateInternal(reader, xsd, NULL, 0));
        !          4449: }
        !          4450: #endif
        !          4451: 
        !          4452: /**
        !          4453:  * xmlTextReaderIsNamespaceDecl:
        !          4454:  * @reader: the xmlTextReaderPtr used
        !          4455:  *
        !          4456:  * Determine whether the current node is a namespace declaration
        !          4457:  * rather than a regular attribute.
        !          4458:  *
        !          4459:  * Returns 1 if the current node is a namespace declaration, 0 if it
        !          4460:  * is a regular attribute or other type of node, or -1 in case of
        !          4461:  * error.
        !          4462:  */
        !          4463: int
        !          4464: xmlTextReaderIsNamespaceDecl(xmlTextReaderPtr reader) {
        !          4465:     xmlNodePtr node;
        !          4466:     if (reader == NULL)
        !          4467:        return(-1);
        !          4468:     if (reader->node == NULL)
        !          4469:        return(-1);
        !          4470:     if (reader->curnode != NULL)
        !          4471:        node = reader->curnode;
        !          4472:     else
        !          4473:        node = reader->node;
        !          4474: 
        !          4475:     if (XML_NAMESPACE_DECL == node->type)
        !          4476:        return(1);
        !          4477:     else
        !          4478:        return(0);
        !          4479: }
        !          4480: 
        !          4481: /**
        !          4482:  * xmlTextReaderConstXmlVersion:
        !          4483:  * @reader:  the xmlTextReaderPtr used
        !          4484:  *
        !          4485:  * Determine the XML version of the document being read.
        !          4486:  *
        !          4487:  * Returns a string containing the XML version of the document or NULL
        !          4488:  * in case of error.  The string is deallocated with the reader.
        !          4489:  */
        !          4490: const xmlChar *
        !          4491: xmlTextReaderConstXmlVersion(xmlTextReaderPtr reader) {
        !          4492:     xmlDocPtr doc = NULL;
        !          4493:     if (reader == NULL)
        !          4494:        return(NULL);
        !          4495:     if (reader->doc != NULL)
        !          4496:         doc = reader->doc;
        !          4497:     else if (reader->ctxt != NULL)
        !          4498:        doc = reader->ctxt->myDoc;
        !          4499:     if (doc == NULL)
        !          4500:        return(NULL);
        !          4501: 
        !          4502:     if (doc->version == NULL)
        !          4503:        return(NULL);
        !          4504:     else
        !          4505:       return(CONSTSTR(doc->version));
        !          4506: }
        !          4507: 
        !          4508: /**
        !          4509:  * xmlTextReaderStandalone:
        !          4510:  * @reader:  the xmlTextReaderPtr used
        !          4511:  *
        !          4512:  * Determine the standalone status of the document being read.
        !          4513:  *
        !          4514:  * Returns 1 if the document was declared to be standalone, 0 if it
        !          4515:  * was declared to be not standalone, or -1 if the document did not
        !          4516:  * specify its standalone status or in case of error.
        !          4517:  */
        !          4518: int
        !          4519: xmlTextReaderStandalone(xmlTextReaderPtr reader) {
        !          4520:     xmlDocPtr doc = NULL;
        !          4521:     if (reader == NULL)
        !          4522:        return(-1);
        !          4523:     if (reader->doc != NULL)
        !          4524:         doc = reader->doc;
        !          4525:     else if (reader->ctxt != NULL)
        !          4526:        doc = reader->ctxt->myDoc;
        !          4527:     if (doc == NULL)
        !          4528:        return(-1);
        !          4529: 
        !          4530:     return(doc->standalone);
        !          4531: }
        !          4532: 
        !          4533: /************************************************************************
        !          4534:  *                                                                     *
        !          4535:  *                     Error Handling Extensions                       *
        !          4536:  *                                                                     *
        !          4537:  ************************************************************************/
        !          4538: 
        !          4539: /* helper to build a xmlMalloc'ed string from a format and va_list */
        !          4540: static char *
        !          4541: xmlTextReaderBuildMessage(const char *msg, va_list ap) {
        !          4542:     int size = 0;
        !          4543:     int chars;
        !          4544:     char *larger;
        !          4545:     char *str = NULL;
        !          4546:     va_list aq;
        !          4547: 
        !          4548:     while (1) {
        !          4549:         VA_COPY(aq, ap);
        !          4550:         chars = vsnprintf(str, size, msg, aq);
        !          4551:         va_end(aq);
        !          4552:         if (chars < 0) {
        !          4553:            xmlGenericError(xmlGenericErrorContext, "vsnprintf failed !\n");
        !          4554:            if (str)
        !          4555:                xmlFree(str);
        !          4556:            return NULL;
        !          4557:        }
        !          4558:        if ((chars < size) || (size == MAX_ERR_MSG_SIZE))
        !          4559:             break;
        !          4560:         if (chars < MAX_ERR_MSG_SIZE)
        !          4561:        size = chars + 1;
        !          4562:        else
        !          4563:                size = MAX_ERR_MSG_SIZE;
        !          4564:         if ((larger = (char *) xmlRealloc(str, size)) == NULL) {
        !          4565:            xmlGenericError(xmlGenericErrorContext, "xmlRealloc failed !\n");
        !          4566:            if (str)
        !          4567:                 xmlFree(str);
        !          4568:             return NULL;
        !          4569:         }
        !          4570:         str = larger;
        !          4571:     }
        !          4572: 
        !          4573:     return str;
        !          4574: }
        !          4575: 
        !          4576: /**
        !          4577:  * xmlTextReaderLocatorLineNumber:
        !          4578:  * @locator: the xmlTextReaderLocatorPtr used
        !          4579:  *
        !          4580:  * Obtain the line number for the given locator.
        !          4581:  *
        !          4582:  * Returns the line number or -1 in case of error.
        !          4583:  */
        !          4584: int
        !          4585: xmlTextReaderLocatorLineNumber(xmlTextReaderLocatorPtr locator) {
        !          4586:     /* we know that locator is a xmlParserCtxtPtr */
        !          4587:     xmlParserCtxtPtr ctx = (xmlParserCtxtPtr)locator;
        !          4588:     int ret = -1;
        !          4589: 
        !          4590:     if (locator == NULL)
        !          4591:         return(-1);
        !          4592:     if (ctx->node != NULL) {
        !          4593:        ret = xmlGetLineNo(ctx->node);
        !          4594:     }
        !          4595:     else {
        !          4596:        /* inspired from error.c */
        !          4597:        xmlParserInputPtr input;
        !          4598:        input = ctx->input;
        !          4599:        if ((input->filename == NULL) && (ctx->inputNr > 1))
        !          4600:            input = ctx->inputTab[ctx->inputNr - 2];
        !          4601:        if (input != NULL) {
        !          4602:            ret = input->line;
        !          4603:        }
        !          4604:        else {
        !          4605:            ret = -1;
        !          4606:        }
        !          4607:     }
        !          4608: 
        !          4609:     return ret;
        !          4610: }
        !          4611: 
        !          4612: /**
        !          4613:  * xmlTextReaderLocatorBaseURI:
        !          4614:  * @locator: the xmlTextReaderLocatorPtr used
        !          4615:  *
        !          4616:  * Obtain the base URI for the given locator.
        !          4617:  *
        !          4618:  * Returns the base URI or NULL in case of error,
        !          4619:  *    if non NULL it need to be freed by the caller.
        !          4620:  */
        !          4621: xmlChar *
        !          4622: xmlTextReaderLocatorBaseURI(xmlTextReaderLocatorPtr locator) {
        !          4623:     /* we know that locator is a xmlParserCtxtPtr */
        !          4624:     xmlParserCtxtPtr ctx = (xmlParserCtxtPtr)locator;
        !          4625:     xmlChar *ret = NULL;
        !          4626: 
        !          4627:     if (locator == NULL)
        !          4628:         return(NULL);
        !          4629:     if (ctx->node != NULL) {
        !          4630:        ret = xmlNodeGetBase(NULL,ctx->node);
        !          4631:     }
        !          4632:     else {
        !          4633:        /* inspired from error.c */
        !          4634:        xmlParserInputPtr input;
        !          4635:        input = ctx->input;
        !          4636:        if ((input->filename == NULL) && (ctx->inputNr > 1))
        !          4637:            input = ctx->inputTab[ctx->inputNr - 2];
        !          4638:        if (input != NULL) {
        !          4639:            ret = xmlStrdup(BAD_CAST input->filename);
        !          4640:        }
        !          4641:        else {
        !          4642:            ret = NULL;
        !          4643:        }
        !          4644:     }
        !          4645: 
        !          4646:     return ret;
        !          4647: }
        !          4648: 
        !          4649: static void
        !          4650: xmlTextReaderGenericError(void *ctxt, xmlParserSeverities severity,
        !          4651:                           char *str)
        !          4652: {
        !          4653:     xmlParserCtxtPtr ctx = (xmlParserCtxtPtr) ctxt;
        !          4654: 
        !          4655:     xmlTextReaderPtr reader = (xmlTextReaderPtr) ctx->_private;
        !          4656: 
        !          4657:     if (str != NULL) {
        !          4658:         if (reader->errorFunc)
        !          4659:             reader->errorFunc(reader->errorFuncArg, str, severity,
        !          4660:                               (xmlTextReaderLocatorPtr) ctx);
        !          4661:         xmlFree(str);
        !          4662:     }
        !          4663: }
        !          4664: 
        !          4665: static void
        !          4666: xmlTextReaderStructuredError(void *ctxt, xmlErrorPtr error)
        !          4667: {
        !          4668:     xmlParserCtxtPtr ctx = (xmlParserCtxtPtr) ctxt;
        !          4669: 
        !          4670:     xmlTextReaderPtr reader = (xmlTextReaderPtr) ctx->_private;
        !          4671: 
        !          4672:     if (error && reader->sErrorFunc) {
        !          4673:         reader->sErrorFunc(reader->errorFuncArg, (xmlErrorPtr) error);
        !          4674:     }
        !          4675: }
        !          4676: 
        !          4677: static void XMLCDECL
        !          4678: xmlTextReaderError(void *ctxt, const char *msg, ...)
        !          4679: {
        !          4680:     va_list ap;
        !          4681: 
        !          4682:     va_start(ap, msg);
        !          4683:     xmlTextReaderGenericError(ctxt,
        !          4684:                               XML_PARSER_SEVERITY_ERROR,
        !          4685:                               xmlTextReaderBuildMessage(msg, ap));
        !          4686:     va_end(ap);
        !          4687: 
        !          4688: }
        !          4689: 
        !          4690: static void XMLCDECL
        !          4691: xmlTextReaderWarning(void *ctxt, const char *msg, ...)
        !          4692: {
        !          4693:     va_list ap;
        !          4694: 
        !          4695:     va_start(ap, msg);
        !          4696:     xmlTextReaderGenericError(ctxt,
        !          4697:                               XML_PARSER_SEVERITY_WARNING,
        !          4698:                               xmlTextReaderBuildMessage(msg, ap));
        !          4699:     va_end(ap);
        !          4700: }
        !          4701: 
        !          4702: static void XMLCDECL
        !          4703: xmlTextReaderValidityError(void *ctxt, const char *msg, ...)
        !          4704: {
        !          4705:     va_list ap;
        !          4706: 
        !          4707:     int len = xmlStrlen((const xmlChar *) msg);
        !          4708: 
        !          4709:     if ((len > 1) && (msg[len - 2] != ':')) {
        !          4710:         /*
        !          4711:          * some callbacks only report locator information:
        !          4712:          * skip them (mimicking behaviour in error.c)
        !          4713:          */
        !          4714:         va_start(ap, msg);
        !          4715:         xmlTextReaderGenericError(ctxt,
        !          4716:                                   XML_PARSER_SEVERITY_VALIDITY_ERROR,
        !          4717:                                   xmlTextReaderBuildMessage(msg, ap));
        !          4718:         va_end(ap);
        !          4719:     }
        !          4720: }
        !          4721: 
        !          4722: static void XMLCDECL
        !          4723: xmlTextReaderValidityWarning(void *ctxt, const char *msg, ...)
        !          4724: {
        !          4725:     va_list ap;
        !          4726: 
        !          4727:     int len = xmlStrlen((const xmlChar *) msg);
        !          4728: 
        !          4729:     if ((len != 0) && (msg[len - 1] != ':')) {
        !          4730:         /*
        !          4731:          * some callbacks only report locator information:
        !          4732:          * skip them (mimicking behaviour in error.c)
        !          4733:          */
        !          4734:         va_start(ap, msg);
        !          4735:         xmlTextReaderGenericError(ctxt,
        !          4736:                                   XML_PARSER_SEVERITY_VALIDITY_WARNING,
        !          4737:                                   xmlTextReaderBuildMessage(msg, ap));
        !          4738:         va_end(ap);
        !          4739:     }
        !          4740: }
        !          4741: 
        !          4742: /**
        !          4743:  * xmlTextReaderSetErrorHandler:
        !          4744:  * @reader:  the xmlTextReaderPtr used
        !          4745:  * @f: the callback function to call on error and warnings
        !          4746:  * @arg:    a user argument to pass to the callback function
        !          4747:  *
        !          4748:  * Register a callback function that will be called on error and warnings.
        !          4749:  *
        !          4750:  * If @f is NULL, the default error and warning handlers are restored.
        !          4751:  */
        !          4752: void
        !          4753: xmlTextReaderSetErrorHandler(xmlTextReaderPtr reader,
        !          4754:                              xmlTextReaderErrorFunc f, void *arg)
        !          4755: {
        !          4756:     if (f != NULL) {
        !          4757:         reader->ctxt->sax->error = xmlTextReaderError;
        !          4758:         reader->ctxt->sax->serror = NULL;
        !          4759:         reader->ctxt->vctxt.error = xmlTextReaderValidityError;
        !          4760:         reader->ctxt->sax->warning = xmlTextReaderWarning;
        !          4761:         reader->ctxt->vctxt.warning = xmlTextReaderValidityWarning;
        !          4762:         reader->errorFunc = f;
        !          4763:         reader->sErrorFunc = NULL;
        !          4764:         reader->errorFuncArg = arg;
        !          4765: #ifdef LIBXML_SCHEMAS_ENABLED
        !          4766:         if (reader->rngValidCtxt) {
        !          4767:             xmlRelaxNGSetValidErrors(reader->rngValidCtxt,
        !          4768:                                      xmlTextReaderValidityErrorRelay,
        !          4769:                                      xmlTextReaderValidityWarningRelay,
        !          4770:                                      reader);
        !          4771:             xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt, NULL,
        !          4772:                                                reader);
        !          4773:         }
        !          4774:         if (reader->xsdValidCtxt) {
        !          4775:             xmlSchemaSetValidErrors(reader->xsdValidCtxt,
        !          4776:                                     xmlTextReaderValidityErrorRelay,
        !          4777:                                     xmlTextReaderValidityWarningRelay,
        !          4778:                                     reader);
        !          4779:             xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt, NULL,
        !          4780:                                               reader);
        !          4781:         }
        !          4782: #endif
        !          4783:     } else {
        !          4784:         /* restore defaults */
        !          4785:         reader->ctxt->sax->error = xmlParserError;
        !          4786:         reader->ctxt->vctxt.error = xmlParserValidityError;
        !          4787:         reader->ctxt->sax->warning = xmlParserWarning;
        !          4788:         reader->ctxt->vctxt.warning = xmlParserValidityWarning;
        !          4789:         reader->errorFunc = NULL;
        !          4790:         reader->sErrorFunc = NULL;
        !          4791:         reader->errorFuncArg = NULL;
        !          4792: #ifdef LIBXML_SCHEMAS_ENABLED
        !          4793:         if (reader->rngValidCtxt) {
        !          4794:             xmlRelaxNGSetValidErrors(reader->rngValidCtxt, NULL, NULL,
        !          4795:                                      reader);
        !          4796:             xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt, NULL,
        !          4797:                                                reader);
        !          4798:         }
        !          4799:         if (reader->xsdValidCtxt) {
        !          4800:             xmlSchemaSetValidErrors(reader->xsdValidCtxt, NULL, NULL,
        !          4801:                                     reader);
        !          4802:             xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt, NULL,
        !          4803:                                               reader);
        !          4804:         }
        !          4805: #endif
        !          4806:     }
        !          4807: }
        !          4808: 
        !          4809: /**
        !          4810: * xmlTextReaderSetStructuredErrorHandler:
        !          4811:  * @reader:  the xmlTextReaderPtr used
        !          4812:  * @f: the callback function to call on error and warnings
        !          4813:  * @arg:    a user argument to pass to the callback function
        !          4814:  *
        !          4815:  * Register a callback function that will be called on error and warnings.
        !          4816:  *
        !          4817:  * If @f is NULL, the default error and warning handlers are restored.
        !          4818:  */
        !          4819: void
        !          4820: xmlTextReaderSetStructuredErrorHandler(xmlTextReaderPtr reader,
        !          4821:                                        xmlStructuredErrorFunc f, void *arg)
        !          4822: {
        !          4823:     if (f != NULL) {
        !          4824:         reader->ctxt->sax->error = NULL;
        !          4825:         reader->ctxt->sax->serror = xmlTextReaderStructuredError;
        !          4826:         reader->ctxt->vctxt.error = xmlTextReaderValidityError;
        !          4827:         reader->ctxt->sax->warning = xmlTextReaderWarning;
        !          4828:         reader->ctxt->vctxt.warning = xmlTextReaderValidityWarning;
        !          4829:         reader->sErrorFunc = f;
        !          4830:         reader->errorFunc = NULL;
        !          4831:         reader->errorFuncArg = arg;
        !          4832: #ifdef LIBXML_SCHEMAS_ENABLED
        !          4833:         if (reader->rngValidCtxt) {
        !          4834:             xmlRelaxNGSetValidErrors(reader->rngValidCtxt, NULL, NULL,
        !          4835:                                      reader);
        !          4836:             xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,
        !          4837:                                         xmlTextReaderValidityStructuredRelay,
        !          4838:                                                reader);
        !          4839:         }
        !          4840:         if (reader->xsdValidCtxt) {
        !          4841:             xmlSchemaSetValidErrors(reader->xsdValidCtxt, NULL, NULL,
        !          4842:                                     reader);
        !          4843:             xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt,
        !          4844:                                        xmlTextReaderValidityStructuredRelay,
        !          4845:                                               reader);
        !          4846:         }
        !          4847: #endif
        !          4848:     } else {
        !          4849:         /* restore defaults */
        !          4850:         reader->ctxt->sax->error = xmlParserError;
        !          4851:         reader->ctxt->sax->serror = NULL;
        !          4852:         reader->ctxt->vctxt.error = xmlParserValidityError;
        !          4853:         reader->ctxt->sax->warning = xmlParserWarning;
        !          4854:         reader->ctxt->vctxt.warning = xmlParserValidityWarning;
        !          4855:         reader->errorFunc = NULL;
        !          4856:         reader->sErrorFunc = NULL;
        !          4857:         reader->errorFuncArg = NULL;
        !          4858: #ifdef LIBXML_SCHEMAS_ENABLED
        !          4859:         if (reader->rngValidCtxt) {
        !          4860:             xmlRelaxNGSetValidErrors(reader->rngValidCtxt, NULL, NULL,
        !          4861:                                      reader);
        !          4862:             xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt, NULL,
        !          4863:                                                reader);
        !          4864:         }
        !          4865:         if (reader->xsdValidCtxt) {
        !          4866:             xmlSchemaSetValidErrors(reader->xsdValidCtxt, NULL, NULL,
        !          4867:                                     reader);
        !          4868:             xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt, NULL,
        !          4869:                                               reader);
        !          4870:         }
        !          4871: #endif
        !          4872:     }
        !          4873: }
        !          4874: 
        !          4875: /**
        !          4876:  * xmlTextReaderIsValid:
        !          4877:  * @reader:  the xmlTextReaderPtr used
        !          4878:  *
        !          4879:  * Retrieve the validity status from the parser context
        !          4880:  *
        !          4881:  * Returns the flag value 1 if valid, 0 if no, and -1 in case of error
        !          4882:  */
        !          4883: int
        !          4884: xmlTextReaderIsValid(xmlTextReaderPtr reader)
        !          4885: {
        !          4886:     if (reader == NULL)
        !          4887:         return (-1);
        !          4888: #ifdef LIBXML_SCHEMAS_ENABLED
        !          4889:     if (reader->validate == XML_TEXTREADER_VALIDATE_RNG)
        !          4890:         return (reader->rngValidErrors == 0);
        !          4891:     if (reader->validate == XML_TEXTREADER_VALIDATE_XSD)
        !          4892:         return (reader->xsdValidErrors == 0);
        !          4893: #endif
        !          4894:     if ((reader->ctxt != NULL) && (reader->ctxt->validate == 1))
        !          4895:         return (reader->ctxt->valid);
        !          4896:     return (0);
        !          4897: }
        !          4898: 
        !          4899: /**
        !          4900:  * xmlTextReaderGetErrorHandler:
        !          4901:  * @reader:  the xmlTextReaderPtr used
        !          4902:  * @f: the callback function or NULL is no callback has been registered
        !          4903:  * @arg:    a user argument
        !          4904:  *
        !          4905:  * Retrieve the error callback function and user argument.
        !          4906:  */
        !          4907: void
        !          4908: xmlTextReaderGetErrorHandler(xmlTextReaderPtr reader,
        !          4909:                              xmlTextReaderErrorFunc * f, void **arg)
        !          4910: {
        !          4911:     if (f != NULL)
        !          4912:         *f = reader->errorFunc;
        !          4913:     if (arg != NULL)
        !          4914:         *arg = reader->errorFuncArg;
        !          4915: }
        !          4916: /************************************************************************
        !          4917:  *                                                                     *
        !          4918:  *     New set (2.6.0) of simpler and more flexible APIs               *
        !          4919:  *                                                                     *
        !          4920:  ************************************************************************/
        !          4921: 
        !          4922: /**
        !          4923:  * xmlTextReaderSetup:
        !          4924:  * @reader:  an XML reader
        !          4925:  * @input: xmlParserInputBufferPtr used to feed the reader, will
        !          4926:  *         be destroyed with it.
        !          4927:  * @URL:  the base URL to use for the document
        !          4928:  * @encoding:  the document encoding, or NULL
        !          4929:  * @options:  a combination of xmlParserOption
        !          4930:  *
        !          4931:  * Setup an XML reader with new options
        !          4932:  *
        !          4933:  * Returns 0 in case of success and -1 in case of error.
        !          4934:  */
        !          4935: int
        !          4936: xmlTextReaderSetup(xmlTextReaderPtr reader,
        !          4937:                    xmlParserInputBufferPtr input, const char *URL,
        !          4938:                    const char *encoding, int options)
        !          4939: {
        !          4940:     if (reader == NULL) {
        !          4941:         if (input != NULL)
        !          4942:            xmlFreeParserInputBuffer(input);
        !          4943:         return (-1);
        !          4944:     }
        !          4945: 
        !          4946:     /*
        !          4947:      * we force the generation of compact text nodes on the reader
        !          4948:      * since usr applications should never modify the tree
        !          4949:      */
        !          4950:     options |= XML_PARSE_COMPACT;
        !          4951: 
        !          4952:     reader->doc = NULL;
        !          4953:     reader->entNr = 0;
        !          4954:     reader->parserFlags = options;
        !          4955:     reader->validate = XML_TEXTREADER_NOT_VALIDATE;
        !          4956:     if ((input != NULL) && (reader->input != NULL) &&
        !          4957:         (reader->allocs & XML_TEXTREADER_INPUT)) {
        !          4958:        xmlFreeParserInputBuffer(reader->input);
        !          4959:        reader->input = NULL;
        !          4960:        reader->allocs -= XML_TEXTREADER_INPUT;
        !          4961:     }
        !          4962:     if (input != NULL) {
        !          4963:        reader->input = input;
        !          4964:        reader->allocs |= XML_TEXTREADER_INPUT;
        !          4965:     }
        !          4966:     if (reader->buffer == NULL)
        !          4967:         reader->buffer = xmlBufferCreateSize(100);
        !          4968:     if (reader->buffer == NULL) {
        !          4969:         xmlGenericError(xmlGenericErrorContext,
        !          4970:                         "xmlTextReaderSetup : malloc failed\n");
        !          4971:         return (-1);
        !          4972:     }
        !          4973:     if (reader->sax == NULL)
        !          4974:        reader->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
        !          4975:     if (reader->sax == NULL) {
        !          4976:         xmlGenericError(xmlGenericErrorContext,
        !          4977:                         "xmlTextReaderSetup : malloc failed\n");
        !          4978:         return (-1);
        !          4979:     }
        !          4980:     xmlSAXVersion(reader->sax, 2);
        !          4981:     reader->startElement = reader->sax->startElement;
        !          4982:     reader->sax->startElement = xmlTextReaderStartElement;
        !          4983:     reader->endElement = reader->sax->endElement;
        !          4984:     reader->sax->endElement = xmlTextReaderEndElement;
        !          4985: #ifdef LIBXML_SAX1_ENABLED
        !          4986:     if (reader->sax->initialized == XML_SAX2_MAGIC) {
        !          4987: #endif /* LIBXML_SAX1_ENABLED */
        !          4988:         reader->startElementNs = reader->sax->startElementNs;
        !          4989:         reader->sax->startElementNs = xmlTextReaderStartElementNs;
        !          4990:         reader->endElementNs = reader->sax->endElementNs;
        !          4991:         reader->sax->endElementNs = xmlTextReaderEndElementNs;
        !          4992: #ifdef LIBXML_SAX1_ENABLED
        !          4993:     } else {
        !          4994:         reader->startElementNs = NULL;
        !          4995:         reader->endElementNs = NULL;
        !          4996:     }
        !          4997: #endif /* LIBXML_SAX1_ENABLED */
        !          4998:     reader->characters = reader->sax->characters;
        !          4999:     reader->sax->characters = xmlTextReaderCharacters;
        !          5000:     reader->sax->ignorableWhitespace = xmlTextReaderCharacters;
        !          5001:     reader->cdataBlock = reader->sax->cdataBlock;
        !          5002:     reader->sax->cdataBlock = xmlTextReaderCDataBlock;
        !          5003: 
        !          5004:     reader->mode = XML_TEXTREADER_MODE_INITIAL;
        !          5005:     reader->node = NULL;
        !          5006:     reader->curnode = NULL;
        !          5007:     if (input != NULL) {
        !          5008:         if (reader->input->buffer->use < 4) {
        !          5009:             xmlParserInputBufferRead(input, 4);
        !          5010:         }
        !          5011:         if (reader->ctxt == NULL) {
        !          5012:             if (reader->input->buffer->use >= 4) {
        !          5013:                 reader->ctxt = xmlCreatePushParserCtxt(reader->sax, NULL,
        !          5014:                       (const char *) reader->input->buffer->content, 4, URL);
        !          5015:                 reader->base = 0;
        !          5016:                 reader->cur = 4;
        !          5017:             } else {
        !          5018:                 reader->ctxt =
        !          5019:                     xmlCreatePushParserCtxt(reader->sax, NULL, NULL, 0, URL);
        !          5020:                 reader->base = 0;
        !          5021:                 reader->cur = 0;
        !          5022:             }
        !          5023:         } else {
        !          5024:            xmlParserInputPtr inputStream;
        !          5025:            xmlParserInputBufferPtr buf;
        !          5026:            xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
        !          5027: 
        !          5028:            xmlCtxtReset(reader->ctxt);
        !          5029:            buf = xmlAllocParserInputBuffer(enc);
        !          5030:            if (buf == NULL) return(-1);
        !          5031:            inputStream = xmlNewInputStream(reader->ctxt);
        !          5032:            if (inputStream == NULL) {
        !          5033:                xmlFreeParserInputBuffer(buf);
        !          5034:                return(-1);
        !          5035:            }
        !          5036: 
        !          5037:            if (URL == NULL)
        !          5038:                inputStream->filename = NULL;
        !          5039:            else
        !          5040:                inputStream->filename = (char *)
        !          5041:                    xmlCanonicPath((const xmlChar *) URL);
        !          5042:            inputStream->buf = buf;
        !          5043:            inputStream->base = inputStream->buf->buffer->content;
        !          5044:            inputStream->cur = inputStream->buf->buffer->content;
        !          5045:            inputStream->end =
        !          5046:             &inputStream->buf->buffer->content[inputStream->buf->buffer->use];
        !          5047: 
        !          5048:            inputPush(reader->ctxt, inputStream);
        !          5049:            reader->cur = 0;
        !          5050:        }
        !          5051:         if (reader->ctxt == NULL) {
        !          5052:             xmlGenericError(xmlGenericErrorContext,
        !          5053:                             "xmlTextReaderSetup : malloc failed\n");
        !          5054:             return (-1);
        !          5055:         }
        !          5056:     }
        !          5057:     if (reader->dict != NULL) {
        !          5058:         if (reader->ctxt->dict != NULL) {
        !          5059:            if (reader->dict != reader->ctxt->dict) {
        !          5060:                xmlDictFree(reader->dict);
        !          5061:                reader->dict = reader->ctxt->dict;
        !          5062:            }
        !          5063:        } else {
        !          5064:            reader->ctxt->dict = reader->dict;
        !          5065:        }
        !          5066:     } else {
        !          5067:        if (reader->ctxt->dict == NULL)
        !          5068:            reader->ctxt->dict = xmlDictCreate();
        !          5069:         reader->dict = reader->ctxt->dict;
        !          5070:     }
        !          5071:     reader->ctxt->_private = reader;
        !          5072:     reader->ctxt->linenumbers = 1;
        !          5073:     reader->ctxt->dictNames = 1;
        !          5074:     /*
        !          5075:      * use the parser dictionnary to allocate all elements and attributes names
        !          5076:      */
        !          5077:     reader->ctxt->docdict = 1;
        !          5078:     reader->ctxt->parseMode = XML_PARSE_READER;
        !          5079: 
        !          5080: #ifdef LIBXML_XINCLUDE_ENABLED
        !          5081:     if (reader->xincctxt != NULL) {
        !          5082:        xmlXIncludeFreeContext(reader->xincctxt);
        !          5083:        reader->xincctxt = NULL;
        !          5084:     }
        !          5085:     if (options & XML_PARSE_XINCLUDE) {
        !          5086:         reader->xinclude = 1;
        !          5087:        reader->xinclude_name = xmlDictLookup(reader->dict, XINCLUDE_NODE, -1);
        !          5088:        options -= XML_PARSE_XINCLUDE;
        !          5089:     } else
        !          5090:         reader->xinclude = 0;
        !          5091:     reader->in_xinclude = 0;
        !          5092: #endif
        !          5093: #ifdef LIBXML_PATTERN_ENABLED
        !          5094:     if (reader->patternTab == NULL) {
        !          5095:         reader->patternNr = 0;
        !          5096:        reader->patternMax = 0;
        !          5097:     }
        !          5098:     while (reader->patternNr > 0) {
        !          5099:         reader->patternNr--;
        !          5100:        if (reader->patternTab[reader->patternNr] != NULL) {
        !          5101:            xmlFreePattern(reader->patternTab[reader->patternNr]);
        !          5102:             reader->patternTab[reader->patternNr] = NULL;
        !          5103:        }
        !          5104:     }
        !          5105: #endif
        !          5106: 
        !          5107:     if (options & XML_PARSE_DTDVALID)
        !          5108:         reader->validate = XML_TEXTREADER_VALIDATE_DTD;
        !          5109: 
        !          5110:     xmlCtxtUseOptions(reader->ctxt, options);
        !          5111:     if (encoding != NULL) {
        !          5112:         xmlCharEncodingHandlerPtr hdlr;
        !          5113: 
        !          5114:         hdlr = xmlFindCharEncodingHandler(encoding);
        !          5115:         if (hdlr != NULL)
        !          5116:             xmlSwitchToEncoding(reader->ctxt, hdlr);
        !          5117:     }
        !          5118:     if ((URL != NULL) && (reader->ctxt->input != NULL) &&
        !          5119:         (reader->ctxt->input->filename == NULL))
        !          5120:         reader->ctxt->input->filename = (char *)
        !          5121:             xmlStrdup((const xmlChar *) URL);
        !          5122: 
        !          5123:     reader->doc = NULL;
        !          5124: 
        !          5125:     return (0);
        !          5126: }
        !          5127: 
        !          5128: /**
        !          5129:  * xmlTextReaderByteConsumed:
        !          5130:  * @reader: an XML reader
        !          5131:  *
        !          5132:  * This function provides the current index of the parser used
        !          5133:  * by the reader, relative to the start of the current entity.
        !          5134:  * This function actually just wraps a call to xmlBytesConsumed()
        !          5135:  * for the parser context associated with the reader.
        !          5136:  * See xmlBytesConsumed() for more information.
        !          5137:  *
        !          5138:  * Returns the index in bytes from the beginning of the entity or -1
        !          5139:  *         in case the index could not be computed.
        !          5140:  */
        !          5141: long
        !          5142: xmlTextReaderByteConsumed(xmlTextReaderPtr reader) {
        !          5143:     if ((reader == NULL) || (reader->ctxt == NULL))
        !          5144:         return(-1);
        !          5145:     return(xmlByteConsumed(reader->ctxt));
        !          5146: }
        !          5147: 
        !          5148: 
        !          5149: /**
        !          5150:  * xmlReaderWalker:
        !          5151:  * @doc:  a preparsed document
        !          5152:  *
        !          5153:  * Create an xmltextReader for a preparsed document.
        !          5154:  *
        !          5155:  * Returns the new reader or NULL in case of error.
        !          5156:  */
        !          5157: xmlTextReaderPtr
        !          5158: xmlReaderWalker(xmlDocPtr doc)
        !          5159: {
        !          5160:     xmlTextReaderPtr ret;
        !          5161: 
        !          5162:     if (doc == NULL)
        !          5163:         return(NULL);
        !          5164: 
        !          5165:     ret = xmlMalloc(sizeof(xmlTextReader));
        !          5166:     if (ret == NULL) {
        !          5167:         xmlGenericError(xmlGenericErrorContext,
        !          5168:                "xmlNewTextReader : malloc failed\n");
        !          5169:        return(NULL);
        !          5170:     }
        !          5171:     memset(ret, 0, sizeof(xmlTextReader));
        !          5172:     ret->entNr = 0;
        !          5173:     ret->input = NULL;
        !          5174:     ret->mode = XML_TEXTREADER_MODE_INITIAL;
        !          5175:     ret->node = NULL;
        !          5176:     ret->curnode = NULL;
        !          5177:     ret->base = 0;
        !          5178:     ret->cur = 0;
        !          5179:     ret->allocs = XML_TEXTREADER_CTXT;
        !          5180:     ret->doc = doc;
        !          5181:     ret->state = XML_TEXTREADER_START;
        !          5182:     ret->dict = xmlDictCreate();
        !          5183:     return(ret);
        !          5184: }
        !          5185: 
        !          5186: /**
        !          5187:  * xmlReaderForDoc:
        !          5188:  * @cur:  a pointer to a zero terminated string
        !          5189:  * @URL:  the base URL to use for the document
        !          5190:  * @encoding:  the document encoding, or NULL
        !          5191:  * @options:  a combination of xmlParserOption
        !          5192:  *
        !          5193:  * Create an xmltextReader for an XML in-memory document.
        !          5194:  * The parsing flags @options are a combination of xmlParserOption.
        !          5195:  *
        !          5196:  * Returns the new reader or NULL in case of error.
        !          5197:  */
        !          5198: xmlTextReaderPtr
        !          5199: xmlReaderForDoc(const xmlChar * cur, const char *URL, const char *encoding,
        !          5200:                 int options)
        !          5201: {
        !          5202:     int len;
        !          5203: 
        !          5204:     if (cur == NULL)
        !          5205:         return (NULL);
        !          5206:     len = xmlStrlen(cur);
        !          5207: 
        !          5208:     return (xmlReaderForMemory
        !          5209:             ((const char *) cur, len, URL, encoding, options));
        !          5210: }
        !          5211: 
        !          5212: /**
        !          5213:  * xmlReaderForFile:
        !          5214:  * @filename:  a file or URL
        !          5215:  * @encoding:  the document encoding, or NULL
        !          5216:  * @options:  a combination of xmlParserOption
        !          5217:  *
        !          5218:  * parse an XML file from the filesystem or the network.
        !          5219:  * The parsing flags @options are a combination of xmlParserOption.
        !          5220:  *
        !          5221:  * Returns the new reader or NULL in case of error.
        !          5222:  */
        !          5223: xmlTextReaderPtr
        !          5224: xmlReaderForFile(const char *filename, const char *encoding, int options)
        !          5225: {
        !          5226:     xmlTextReaderPtr reader;
        !          5227: 
        !          5228:     reader = xmlNewTextReaderFilename(filename);
        !          5229:     if (reader == NULL)
        !          5230:         return (NULL);
        !          5231:     xmlTextReaderSetup(reader, NULL, NULL, encoding, options);
        !          5232:     return (reader);
        !          5233: }
        !          5234: 
        !          5235: /**
        !          5236:  * xmlReaderForMemory:
        !          5237:  * @buffer:  a pointer to a char array
        !          5238:  * @size:  the size of the array
        !          5239:  * @URL:  the base URL to use for the document
        !          5240:  * @encoding:  the document encoding, or NULL
        !          5241:  * @options:  a combination of xmlParserOption
        !          5242:  *
        !          5243:  * Create an xmltextReader for an XML in-memory document.
        !          5244:  * The parsing flags @options are a combination of xmlParserOption.
        !          5245:  *
        !          5246:  * Returns the new reader or NULL in case of error.
        !          5247:  */
        !          5248: xmlTextReaderPtr
        !          5249: xmlReaderForMemory(const char *buffer, int size, const char *URL,
        !          5250:                    const char *encoding, int options)
        !          5251: {
        !          5252:     xmlTextReaderPtr reader;
        !          5253:     xmlParserInputBufferPtr buf;
        !          5254: 
        !          5255:     buf = xmlParserInputBufferCreateStatic(buffer, size,
        !          5256:                                       XML_CHAR_ENCODING_NONE);
        !          5257:     if (buf == NULL) {
        !          5258:         return (NULL);
        !          5259:     }
        !          5260:     reader = xmlNewTextReader(buf, URL);
        !          5261:     if (reader == NULL) {
        !          5262:         xmlFreeParserInputBuffer(buf);
        !          5263:         return (NULL);
        !          5264:     }
        !          5265:     reader->allocs |= XML_TEXTREADER_INPUT;
        !          5266:     xmlTextReaderSetup(reader, NULL, URL, encoding, options);
        !          5267:     return (reader);
        !          5268: }
        !          5269: 
        !          5270: /**
        !          5271:  * xmlReaderForFd:
        !          5272:  * @fd:  an open file descriptor
        !          5273:  * @URL:  the base URL to use for the document
        !          5274:  * @encoding:  the document encoding, or NULL
        !          5275:  * @options:  a combination of xmlParserOption
        !          5276:  *
        !          5277:  * Create an xmltextReader for an XML from a file descriptor.
        !          5278:  * The parsing flags @options are a combination of xmlParserOption.
        !          5279:  * NOTE that the file descriptor will not be closed when the
        !          5280:  *      reader is closed or reset.
        !          5281:  *
        !          5282:  * Returns the new reader or NULL in case of error.
        !          5283:  */
        !          5284: xmlTextReaderPtr
        !          5285: xmlReaderForFd(int fd, const char *URL, const char *encoding, int options)
        !          5286: {
        !          5287:     xmlTextReaderPtr reader;
        !          5288:     xmlParserInputBufferPtr input;
        !          5289: 
        !          5290:     if (fd < 0)
        !          5291:         return (NULL);
        !          5292: 
        !          5293:     input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
        !          5294:     if (input == NULL)
        !          5295:         return (NULL);
        !          5296:     input->closecallback = NULL;
        !          5297:     reader = xmlNewTextReader(input, URL);
        !          5298:     if (reader == NULL) {
        !          5299:         xmlFreeParserInputBuffer(input);
        !          5300:         return (NULL);
        !          5301:     }
        !          5302:     reader->allocs |= XML_TEXTREADER_INPUT;
        !          5303:     xmlTextReaderSetup(reader, NULL, URL, encoding, options);
        !          5304:     return (reader);
        !          5305: }
        !          5306: 
        !          5307: /**
        !          5308:  * xmlReaderForIO:
        !          5309:  * @ioread:  an I/O read function
        !          5310:  * @ioclose:  an I/O close function
        !          5311:  * @ioctx:  an I/O handler
        !          5312:  * @URL:  the base URL to use for the document
        !          5313:  * @encoding:  the document encoding, or NULL
        !          5314:  * @options:  a combination of xmlParserOption
        !          5315:  *
        !          5316:  * Create an xmltextReader for an XML document from I/O functions and source.
        !          5317:  * The parsing flags @options are a combination of xmlParserOption.
        !          5318:  *
        !          5319:  * Returns the new reader or NULL in case of error.
        !          5320:  */
        !          5321: xmlTextReaderPtr
        !          5322: xmlReaderForIO(xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
        !          5323:                void *ioctx, const char *URL, const char *encoding,
        !          5324:                int options)
        !          5325: {
        !          5326:     xmlTextReaderPtr reader;
        !          5327:     xmlParserInputBufferPtr input;
        !          5328: 
        !          5329:     if (ioread == NULL)
        !          5330:         return (NULL);
        !          5331: 
        !          5332:     input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
        !          5333:                                          XML_CHAR_ENCODING_NONE);
        !          5334:     if (input == NULL)
        !          5335:         return (NULL);
        !          5336:     reader = xmlNewTextReader(input, URL);
        !          5337:     if (reader == NULL) {
        !          5338:         xmlFreeParserInputBuffer(input);
        !          5339:         return (NULL);
        !          5340:     }
        !          5341:     reader->allocs |= XML_TEXTREADER_INPUT;
        !          5342:     xmlTextReaderSetup(reader, NULL, URL, encoding, options);
        !          5343:     return (reader);
        !          5344: }
        !          5345: 
        !          5346: /**
        !          5347:  * xmlReaderNewWalker:
        !          5348:  * @reader:  an XML reader
        !          5349:  * @doc:  a preparsed document
        !          5350:  *
        !          5351:  * Setup an xmltextReader to parse a preparsed XML document.
        !          5352:  * This reuses the existing @reader xmlTextReader.
        !          5353:  *
        !          5354:  * Returns 0 in case of success and -1 in case of error
        !          5355:  */
        !          5356: int
        !          5357: xmlReaderNewWalker(xmlTextReaderPtr reader, xmlDocPtr doc)
        !          5358: {
        !          5359:     if (doc == NULL)
        !          5360:         return (-1);
        !          5361:     if (reader == NULL)
        !          5362:         return (-1);
        !          5363: 
        !          5364:     if (reader->input != NULL) {
        !          5365:         xmlFreeParserInputBuffer(reader->input);
        !          5366:     }
        !          5367:     if (reader->ctxt != NULL) {
        !          5368:        xmlCtxtReset(reader->ctxt);
        !          5369:     }
        !          5370: 
        !          5371:     reader->entNr = 0;
        !          5372:     reader->input = NULL;
        !          5373:     reader->mode = XML_TEXTREADER_MODE_INITIAL;
        !          5374:     reader->node = NULL;
        !          5375:     reader->curnode = NULL;
        !          5376:     reader->base = 0;
        !          5377:     reader->cur = 0;
        !          5378:     reader->allocs = XML_TEXTREADER_CTXT;
        !          5379:     reader->doc = doc;
        !          5380:     reader->state = XML_TEXTREADER_START;
        !          5381:     if (reader->dict == NULL) {
        !          5382:         if ((reader->ctxt != NULL) && (reader->ctxt->dict != NULL))
        !          5383:            reader->dict = reader->ctxt->dict;
        !          5384:        else
        !          5385:            reader->dict = xmlDictCreate();
        !          5386:     }
        !          5387:     return(0);
        !          5388: }
        !          5389: 
        !          5390: /**
        !          5391:  * xmlReaderNewDoc:
        !          5392:  * @reader:  an XML reader
        !          5393:  * @cur:  a pointer to a zero terminated string
        !          5394:  * @URL:  the base URL to use for the document
        !          5395:  * @encoding:  the document encoding, or NULL
        !          5396:  * @options:  a combination of xmlParserOption
        !          5397:  *
        !          5398:  * Setup an xmltextReader to parse an XML in-memory document.
        !          5399:  * The parsing flags @options are a combination of xmlParserOption.
        !          5400:  * This reuses the existing @reader xmlTextReader.
        !          5401:  *
        !          5402:  * Returns 0 in case of success and -1 in case of error
        !          5403:  */
        !          5404: int
        !          5405: xmlReaderNewDoc(xmlTextReaderPtr reader, const xmlChar * cur,
        !          5406:                 const char *URL, const char *encoding, int options)
        !          5407: {
        !          5408: 
        !          5409:     int len;
        !          5410: 
        !          5411:     if (cur == NULL)
        !          5412:         return (-1);
        !          5413:     if (reader == NULL)
        !          5414:         return (-1);
        !          5415: 
        !          5416:     len = xmlStrlen(cur);
        !          5417:     return (xmlReaderNewMemory(reader, (const char *)cur, len,
        !          5418:                                URL, encoding, options));
        !          5419: }
        !          5420: 
        !          5421: /**
        !          5422:  * xmlReaderNewFile:
        !          5423:  * @reader:  an XML reader
        !          5424:  * @filename:  a file or URL
        !          5425:  * @encoding:  the document encoding, or NULL
        !          5426:  * @options:  a combination of xmlParserOption
        !          5427:  *
        !          5428:  * parse an XML file from the filesystem or the network.
        !          5429:  * The parsing flags @options are a combination of xmlParserOption.
        !          5430:  * This reuses the existing @reader xmlTextReader.
        !          5431:  *
        !          5432:  * Returns 0 in case of success and -1 in case of error
        !          5433:  */
        !          5434: int
        !          5435: xmlReaderNewFile(xmlTextReaderPtr reader, const char *filename,
        !          5436:                  const char *encoding, int options)
        !          5437: {
        !          5438:     xmlParserInputBufferPtr input;
        !          5439: 
        !          5440:     if (filename == NULL)
        !          5441:         return (-1);
        !          5442:     if (reader == NULL)
        !          5443:         return (-1);
        !          5444: 
        !          5445:     input =
        !          5446:         xmlParserInputBufferCreateFilename(filename,
        !          5447:                                            XML_CHAR_ENCODING_NONE);
        !          5448:     if (input == NULL)
        !          5449:         return (-1);
        !          5450:     return (xmlTextReaderSetup(reader, input, filename, encoding, options));
        !          5451: }
        !          5452: 
        !          5453: /**
        !          5454:  * xmlReaderNewMemory:
        !          5455:  * @reader:  an XML reader
        !          5456:  * @buffer:  a pointer to a char array
        !          5457:  * @size:  the size of the array
        !          5458:  * @URL:  the base URL to use for the document
        !          5459:  * @encoding:  the document encoding, or NULL
        !          5460:  * @options:  a combination of xmlParserOption
        !          5461:  *
        !          5462:  * Setup an xmltextReader to parse an XML in-memory document.
        !          5463:  * The parsing flags @options are a combination of xmlParserOption.
        !          5464:  * This reuses the existing @reader xmlTextReader.
        !          5465:  *
        !          5466:  * Returns 0 in case of success and -1 in case of error
        !          5467:  */
        !          5468: int
        !          5469: xmlReaderNewMemory(xmlTextReaderPtr reader, const char *buffer, int size,
        !          5470:                    const char *URL, const char *encoding, int options)
        !          5471: {
        !          5472:     xmlParserInputBufferPtr input;
        !          5473: 
        !          5474:     if (reader == NULL)
        !          5475:         return (-1);
        !          5476:     if (buffer == NULL)
        !          5477:         return (-1);
        !          5478: 
        !          5479:     input = xmlParserInputBufferCreateStatic(buffer, size,
        !          5480:                                       XML_CHAR_ENCODING_NONE);
        !          5481:     if (input == NULL) {
        !          5482:         return (-1);
        !          5483:     }
        !          5484:     return (xmlTextReaderSetup(reader, input, URL, encoding, options));
        !          5485: }
        !          5486: 
        !          5487: /**
        !          5488:  * xmlReaderNewFd:
        !          5489:  * @reader:  an XML reader
        !          5490:  * @fd:  an open file descriptor
        !          5491:  * @URL:  the base URL to use for the document
        !          5492:  * @encoding:  the document encoding, or NULL
        !          5493:  * @options:  a combination of xmlParserOption
        !          5494:  *
        !          5495:  * Setup an xmltextReader to parse an XML from a file descriptor.
        !          5496:  * NOTE that the file descriptor will not be closed when the
        !          5497:  *      reader is closed or reset.
        !          5498:  * The parsing flags @options are a combination of xmlParserOption.
        !          5499:  * This reuses the existing @reader xmlTextReader.
        !          5500:  *
        !          5501:  * Returns 0 in case of success and -1 in case of error
        !          5502:  */
        !          5503: int
        !          5504: xmlReaderNewFd(xmlTextReaderPtr reader, int fd,
        !          5505:                const char *URL, const char *encoding, int options)
        !          5506: {
        !          5507:     xmlParserInputBufferPtr input;
        !          5508: 
        !          5509:     if (fd < 0)
        !          5510:         return (-1);
        !          5511:     if (reader == NULL)
        !          5512:         return (-1);
        !          5513: 
        !          5514:     input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
        !          5515:     if (input == NULL)
        !          5516:         return (-1);
        !          5517:     input->closecallback = NULL;
        !          5518:     return (xmlTextReaderSetup(reader, input, URL, encoding, options));
        !          5519: }
        !          5520: 
        !          5521: /**
        !          5522:  * xmlReaderNewIO:
        !          5523:  * @reader:  an XML reader
        !          5524:  * @ioread:  an I/O read function
        !          5525:  * @ioclose:  an I/O close function
        !          5526:  * @ioctx:  an I/O handler
        !          5527:  * @URL:  the base URL to use for the document
        !          5528:  * @encoding:  the document encoding, or NULL
        !          5529:  * @options:  a combination of xmlParserOption
        !          5530:  *
        !          5531:  * Setup an xmltextReader to parse an XML document from I/O functions
        !          5532:  * and source.
        !          5533:  * The parsing flags @options are a combination of xmlParserOption.
        !          5534:  * This reuses the existing @reader xmlTextReader.
        !          5535:  *
        !          5536:  * Returns 0 in case of success and -1 in case of error
        !          5537:  */
        !          5538: int
        !          5539: xmlReaderNewIO(xmlTextReaderPtr reader, xmlInputReadCallback ioread,
        !          5540:                xmlInputCloseCallback ioclose, void *ioctx,
        !          5541:                const char *URL, const char *encoding, int options)
        !          5542: {
        !          5543:     xmlParserInputBufferPtr input;
        !          5544: 
        !          5545:     if (ioread == NULL)
        !          5546:         return (-1);
        !          5547:     if (reader == NULL)
        !          5548:         return (-1);
        !          5549: 
        !          5550:     input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
        !          5551:                                          XML_CHAR_ENCODING_NONE);
        !          5552:     if (input == NULL)
        !          5553:         return (-1);
        !          5554:     return (xmlTextReaderSetup(reader, input, URL, encoding, options));
        !          5555: }
        !          5556: /************************************************************************
        !          5557:  *                                                                     *
        !          5558:  *                     Utilities                                       *
        !          5559:  *                                                                     *
        !          5560:  ************************************************************************/
        !          5561: #ifdef NOT_USED_YET
        !          5562: 
        !          5563: /**
        !          5564:  * xmlBase64Decode:
        !          5565:  * @in:  the input buffer
        !          5566:  * @inlen:  the size of the input (in), the size read from it (out)
        !          5567:  * @to:  the output buffer
        !          5568:  * @tolen:  the size of the output (in), the size written to (out)
        !          5569:  *
        !          5570:  * Base64 decoder, reads from @in and save in @to
        !          5571:  * TODO: tell jody when this is actually exported
        !          5572:  *
        !          5573:  * Returns 0 if all the input was consumer, 1 if the Base64 end was reached,
        !          5574:  *         2 if there wasn't enough space on the output or -1 in case of error.
        !          5575:  */
        !          5576: static int
        !          5577: xmlBase64Decode(const unsigned char *in, unsigned long *inlen,
        !          5578:                 unsigned char *to, unsigned long *tolen)
        !          5579: {
        !          5580:     unsigned long incur;        /* current index in in[] */
        !          5581: 
        !          5582:     unsigned long inblk;        /* last block index in in[] */
        !          5583: 
        !          5584:     unsigned long outcur;       /* current index in out[] */
        !          5585: 
        !          5586:     unsigned long inmax;        /* size of in[] */
        !          5587: 
        !          5588:     unsigned long outmax;       /* size of out[] */
        !          5589: 
        !          5590:     unsigned char cur;          /* the current value read from in[] */
        !          5591: 
        !          5592:     unsigned char intmp[4], outtmp[4];  /* temporary buffers for the convert */
        !          5593: 
        !          5594:     int nbintmp;                /* number of byte in intmp[] */
        !          5595: 
        !          5596:     int is_ignore;              /* cur should be ignored */
        !          5597: 
        !          5598:     int is_end = 0;             /* the end of the base64 was found */
        !          5599: 
        !          5600:     int retval = 1;
        !          5601: 
        !          5602:     int i;
        !          5603: 
        !          5604:     if ((in == NULL) || (inlen == NULL) || (to == NULL) || (tolen == NULL))
        !          5605:         return (-1);
        !          5606: 
        !          5607:     incur = 0;
        !          5608:     inblk = 0;
        !          5609:     outcur = 0;
        !          5610:     inmax = *inlen;
        !          5611:     outmax = *tolen;
        !          5612:     nbintmp = 0;
        !          5613: 
        !          5614:     while (1) {
        !          5615:         if (incur >= inmax)
        !          5616:             break;
        !          5617:         cur = in[incur++];
        !          5618:         is_ignore = 0;
        !          5619:         if ((cur >= 'A') && (cur <= 'Z'))
        !          5620:             cur = cur - 'A';
        !          5621:         else if ((cur >= 'a') && (cur <= 'z'))
        !          5622:             cur = cur - 'a' + 26;
        !          5623:         else if ((cur >= '0') && (cur <= '9'))
        !          5624:             cur = cur - '0' + 52;
        !          5625:         else if (cur == '+')
        !          5626:             cur = 62;
        !          5627:         else if (cur == '/')
        !          5628:             cur = 63;
        !          5629:         else if (cur == '.')
        !          5630:             cur = 0;
        !          5631:         else if (cur == '=')    /*no op , end of the base64 stream */
        !          5632:             is_end = 1;
        !          5633:         else {
        !          5634:             is_ignore = 1;
        !          5635:             if (nbintmp == 0)
        !          5636:                 inblk = incur;
        !          5637:         }
        !          5638: 
        !          5639:         if (!is_ignore) {
        !          5640:             int nbouttmp = 3;
        !          5641: 
        !          5642:             int is_break = 0;
        !          5643: 
        !          5644:             if (is_end) {
        !          5645:                 if (nbintmp == 0)
        !          5646:                     break;
        !          5647:                 if ((nbintmp == 1) || (nbintmp == 2))
        !          5648:                     nbouttmp = 1;
        !          5649:                 else
        !          5650:                     nbouttmp = 2;
        !          5651:                 nbintmp = 3;
        !          5652:                 is_break = 1;
        !          5653:             }
        !          5654:             intmp[nbintmp++] = cur;
        !          5655:             /*
        !          5656:              * if intmp is full, push the 4byte sequence as a 3 byte
        !          5657:              * sequence out
        !          5658:              */
        !          5659:             if (nbintmp == 4) {
        !          5660:                 nbintmp = 0;
        !          5661:                 outtmp[0] = (intmp[0] << 2) | ((intmp[1] & 0x30) >> 4);
        !          5662:                 outtmp[1] =
        !          5663:                     ((intmp[1] & 0x0F) << 4) | ((intmp[2] & 0x3C) >> 2);
        !          5664:                 outtmp[2] = ((intmp[2] & 0x03) << 6) | (intmp[3] & 0x3F);
        !          5665:                 if (outcur + 3 >= outmax) {
        !          5666:                     retval = 2;
        !          5667:                     break;
        !          5668:                 }
        !          5669: 
        !          5670:                 for (i = 0; i < nbouttmp; i++)
        !          5671:                     to[outcur++] = outtmp[i];
        !          5672:                 inblk = incur;
        !          5673:             }
        !          5674: 
        !          5675:             if (is_break) {
        !          5676:                 retval = 0;
        !          5677:                 break;
        !          5678:             }
        !          5679:         }
        !          5680:     }
        !          5681: 
        !          5682:     *tolen = outcur;
        !          5683:     *inlen = inblk;
        !          5684:     return (retval);
        !          5685: }
        !          5686: 
        !          5687: /*
        !          5688:  * Test routine for the xmlBase64Decode function
        !          5689:  */
        !          5690: #if 0
        !          5691: int
        !          5692: main(int argc, char **argv)
        !          5693: {
        !          5694:     char *input = "  VW4 gcGV0        \n      aXQgdGVzdCAuCg== ";
        !          5695: 
        !          5696:     char output[100];
        !          5697: 
        !          5698:     char output2[100];
        !          5699: 
        !          5700:     char output3[100];
        !          5701: 
        !          5702:     unsigned long inlen = strlen(input);
        !          5703: 
        !          5704:     unsigned long outlen = 100;
        !          5705: 
        !          5706:     int ret;
        !          5707: 
        !          5708:     unsigned long cons, tmp, tmp2, prod;
        !          5709: 
        !          5710:     /*
        !          5711:      * Direct
        !          5712:      */
        !          5713:     ret = xmlBase64Decode(input, &inlen, output, &outlen);
        !          5714: 
        !          5715:     output[outlen] = 0;
        !          5716:     printf("ret: %d, inlen: %ld , outlen: %ld, output: '%s'\n", ret, inlen,
        !          5717:            outlen, output)indent: Standard input:179: Error:Unmatched #endif
        !          5718: ;
        !          5719: 
        !          5720:     /*
        !          5721:      * output chunking
        !          5722:      */
        !          5723:     cons = 0;
        !          5724:     prod = 0;
        !          5725:     while (cons < inlen) {
        !          5726:         tmp = 5;
        !          5727:         tmp2 = inlen - cons;
        !          5728: 
        !          5729:         printf("%ld %ld\n", cons, prod);
        !          5730:         ret = xmlBase64Decode(&input[cons], &tmp2, &output2[prod], &tmp);
        !          5731:         cons += tmp2;
        !          5732:         prod += tmp;
        !          5733:         printf("%ld %ld\n", cons, prod);
        !          5734:     }
        !          5735:     output2[outlen] = 0;
        !          5736:     printf("ret: %d, cons: %ld , prod: %ld, output: '%s'\n", ret, cons,
        !          5737:            prod, output2);
        !          5738: 
        !          5739:     /*
        !          5740:      * input chunking
        !          5741:      */
        !          5742:     cons = 0;
        !          5743:     prod = 0;
        !          5744:     while (cons < inlen) {
        !          5745:         tmp = 100 - prod;
        !          5746:         tmp2 = inlen - cons;
        !          5747:         if (tmp2 > 5)
        !          5748:             tmp2 = 5;
        !          5749: 
        !          5750:         printf("%ld %ld\n", cons, prod);
        !          5751:         ret = xmlBase64Decode(&input[cons], &tmp2, &output3[prod], &tmp);
        !          5752:         cons += tmp2;
        !          5753:         prod += tmp;
        !          5754:         printf("%ld %ld\n", cons, prod);
        !          5755:     }
        !          5756:     output3[outlen] = 0;
        !          5757:     printf("ret: %d, cons: %ld , prod: %ld, output: '%s'\n", ret, cons,
        !          5758:            prod, output3);
        !          5759:     return (0);
        !          5760: 
        !          5761: }
        !          5762: #endif
        !          5763: #endif /* NOT_USED_YET */
        !          5764: #define bottom_xmlreader
        !          5765: #include "elfgcchack.h"
        !          5766: #endif /* LIBXML_READER_ENABLED */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>