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

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

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