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