Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenxmlwriter.c
Go to the documentation of this file.
00001 00002 /* 00003 * xmlwriter.c: XML text writer implementation 00004 * 00005 * For license and disclaimer see the license and disclaimer of 00006 * libxml2. 00007 * 00008 * alfred@mickautsch.de 00009 */ 00010 00011 #define IN_LIBXML 00012 #include "libxml.h" 00013 #include <string.h> 00014 00015 #include <libxml/xmlmemory.h> 00016 #include <libxml/parser.h> 00017 #include <libxml/uri.h> 00018 #include <libxml/HTMLtree.h> 00019 00020 #ifdef LIBXML_WRITER_ENABLED 00021 00022 #include <libxml/xmlwriter.h> 00023 00024 #define B64LINELEN 72 00025 #define B64CRLF "\r\n" 00026 00027 /* 00028 * The following VA_COPY was coded following an example in 00029 * the Samba project. It may not be sufficient for some 00030 * esoteric implementations of va_list (i.e. it may need 00031 * something involving a memcpy) but (hopefully) will be 00032 * sufficient for libxml2. 00033 */ 00034 #ifndef VA_COPY 00035 #ifdef HAVE_VA_COPY 00036 #define VA_COPY(dest, src) va_copy(dest, src) 00037 #else 00038 #ifdef HAVE___VA_COPY 00039 #define VA_COPY(dest,src) __va_copy(dest, src) 00040 #else 00041 #define VA_COPY(dest,src) (dest) = (src) 00042 #endif 00043 #endif 00044 #endif 00045 00046 /* 00047 * Types are kept private 00048 */ 00049 typedef enum { 00050 XML_TEXTWRITER_NONE = 0, 00051 XML_TEXTWRITER_NAME, 00052 XML_TEXTWRITER_ATTRIBUTE, 00053 XML_TEXTWRITER_TEXT, 00054 XML_TEXTWRITER_PI, 00055 XML_TEXTWRITER_PI_TEXT, 00056 XML_TEXTWRITER_CDATA, 00057 XML_TEXTWRITER_DTD, 00058 XML_TEXTWRITER_DTD_TEXT, 00059 XML_TEXTWRITER_DTD_ELEM, 00060 XML_TEXTWRITER_DTD_ELEM_TEXT, 00061 XML_TEXTWRITER_DTD_ATTL, 00062 XML_TEXTWRITER_DTD_ATTL_TEXT, 00063 XML_TEXTWRITER_DTD_ENTY, /* entity */ 00064 XML_TEXTWRITER_DTD_ENTY_TEXT, 00065 XML_TEXTWRITER_DTD_PENT, /* parameter entity */ 00066 XML_TEXTWRITER_COMMENT 00067 } xmlTextWriterState; 00068 00069 typedef struct _xmlTextWriterStackEntry xmlTextWriterStackEntry; 00070 00071 struct _xmlTextWriterStackEntry { 00072 xmlChar *name; 00073 xmlTextWriterState state; 00074 }; 00075 00076 typedef struct _xmlTextWriterNsStackEntry xmlTextWriterNsStackEntry; 00077 struct _xmlTextWriterNsStackEntry { 00078 xmlChar *prefix; 00079 xmlChar *uri; 00080 xmlLinkPtr elem; 00081 }; 00082 00083 struct _xmlTextWriter { 00084 xmlOutputBufferPtr out; /* output buffer */ 00085 xmlListPtr nodes; /* element name stack */ 00086 xmlListPtr nsstack; /* name spaces stack */ 00087 int level; 00088 int indent; /* enable indent */ 00089 int doindent; /* internal indent flag */ 00090 xmlChar *ichar; /* indent character */ 00091 char qchar; /* character used for quoting attribute values */ 00092 xmlParserCtxtPtr ctxt; 00093 int no_doc_free; 00094 xmlDocPtr doc; 00095 }; 00096 00097 static void xmlFreeTextWriterStackEntry(xmlLinkPtr lk); 00098 static int xmlCmpTextWriterStackEntry(const void *data0, 00099 const void *data1); 00100 static int xmlTextWriterOutputNSDecl(xmlTextWriterPtr writer); 00101 static void xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk); 00102 static int xmlCmpTextWriterNsStackEntry(const void *data0, 00103 const void *data1); 00104 static int xmlTextWriterWriteDocCallback(void *context, 00105 const xmlChar * str, int len); 00106 static int xmlTextWriterCloseDocCallback(void *context); 00107 00108 static xmlChar *xmlTextWriterVSprintf(const char *format, va_list argptr); 00109 static int xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len, 00110 const unsigned char *data); 00111 static void xmlTextWriterStartDocumentCallback(void *ctx); 00112 static int xmlTextWriterWriteIndent(xmlTextWriterPtr writer); 00113 static int 00114 xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer, 00115 xmlTextWriterStackEntry * p); 00116 00125 static void 00126 xmlWriterErrMsg(xmlTextWriterPtr ctxt, xmlParserErrors error, 00127 const char *msg) 00128 { 00129 if (ctxt != NULL) { 00130 __xmlRaiseError(NULL, NULL, NULL, ctxt->ctxt, 00131 NULL, XML_FROM_WRITER, error, XML_ERR_FATAL, 00132 NULL, 0, NULL, NULL, NULL, 0, 0, "%s", msg); 00133 } else { 00134 __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_WRITER, error, 00135 XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0, "%s", msg); 00136 } 00137 } 00138 00148 static void 00149 xmlWriterErrMsgInt(xmlTextWriterPtr ctxt, xmlParserErrors error, 00150 const char *msg, int val) 00151 { 00152 if (ctxt != NULL) { 00153 __xmlRaiseError(NULL, NULL, NULL, ctxt->ctxt, 00154 NULL, XML_FROM_WRITER, error, XML_ERR_FATAL, 00155 NULL, 0, NULL, NULL, NULL, val, 0, msg, val); 00156 } else { 00157 __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_WRITER, error, 00158 XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, val, 0, msg, val); 00159 } 00160 } 00161 00172 xmlTextWriterPtr 00173 xmlNewTextWriter(xmlOutputBufferPtr out) 00174 { 00175 xmlTextWriterPtr ret; 00176 00177 ret = (xmlTextWriterPtr) xmlMalloc(sizeof(xmlTextWriter)); 00178 if (ret == NULL) { 00179 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY, 00180 "xmlNewTextWriter : out of memory!\n"); 00181 return NULL; 00182 } 00183 memset(ret, 0, (size_t) sizeof(xmlTextWriter)); 00184 00185 ret->nodes = xmlListCreate((xmlListDeallocator) 00186 xmlFreeTextWriterStackEntry, 00187 (xmlListDataCompare) 00188 xmlCmpTextWriterStackEntry); 00189 if (ret->nodes == NULL) { 00190 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY, 00191 "xmlNewTextWriter : out of memory!\n"); 00192 xmlFree(ret); 00193 return NULL; 00194 } 00195 00196 ret->nsstack = xmlListCreate((xmlListDeallocator) 00197 xmlFreeTextWriterNsStackEntry, 00198 (xmlListDataCompare) 00199 xmlCmpTextWriterNsStackEntry); 00200 if (ret->nsstack == NULL) { 00201 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY, 00202 "xmlNewTextWriter : out of memory!\n"); 00203 xmlListDelete(ret->nodes); 00204 xmlFree(ret); 00205 return NULL; 00206 } 00207 00208 ret->out = out; 00209 ret->ichar = xmlStrdup(BAD_CAST " "); 00210 ret->qchar = '"'; 00211 00212 if (!ret->ichar) { 00213 xmlListDelete(ret->nodes); 00214 xmlListDelete(ret->nsstack); 00215 xmlFree(ret); 00216 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY, 00217 "xmlNewTextWriter : out of memory!\n"); 00218 return NULL; 00219 } 00220 00221 ret->doc = xmlNewDoc(NULL); 00222 00223 ret->no_doc_free = 0; 00224 00225 return ret; 00226 } 00227 00237 xmlTextWriterPtr 00238 xmlNewTextWriterFilename(const char *uri, int compression) 00239 { 00240 xmlTextWriterPtr ret; 00241 xmlOutputBufferPtr out; 00242 00243 out = xmlOutputBufferCreateFilename(uri, NULL, compression); 00244 if (out == NULL) { 00245 xmlWriterErrMsg(NULL, XML_IO_EIO, 00246 "xmlNewTextWriterFilename : cannot open uri\n"); 00247 return NULL; 00248 } 00249 00250 ret = xmlNewTextWriter(out); 00251 if (ret == NULL) { 00252 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY, 00253 "xmlNewTextWriterFilename : out of memory!\n"); 00254 xmlOutputBufferClose(out); 00255 return NULL; 00256 } 00257 00258 ret->indent = 0; 00259 ret->doindent = 0; 00260 return ret; 00261 } 00262 00273 xmlTextWriterPtr 00274 xmlNewTextWriterMemory(xmlBufferPtr buf, int compression ATTRIBUTE_UNUSED) 00275 { 00276 xmlTextWriterPtr ret; 00277 xmlOutputBufferPtr out; 00278 00279 /*::todo handle compression */ 00280 out = xmlOutputBufferCreateBuffer(buf, NULL); 00281 00282 if (out == NULL) { 00283 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY, 00284 "xmlNewTextWriterMemory : out of memory!\n"); 00285 return NULL; 00286 } 00287 00288 ret = xmlNewTextWriter(out); 00289 if (ret == NULL) { 00290 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY, 00291 "xmlNewTextWriterMemory : out of memory!\n"); 00292 xmlOutputBufferClose(out); 00293 return NULL; 00294 } 00295 00296 return ret; 00297 } 00298 00311 xmlTextWriterPtr 00312 xmlNewTextWriterPushParser(xmlParserCtxtPtr ctxt, 00313 int compression ATTRIBUTE_UNUSED) 00314 { 00315 xmlTextWriterPtr ret; 00316 xmlOutputBufferPtr out; 00317 00318 if (ctxt == NULL) { 00319 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR, 00320 "xmlNewTextWriterPushParser : invalid context!\n"); 00321 return NULL; 00322 } 00323 00324 out = xmlOutputBufferCreateIO((xmlOutputWriteCallback) 00325 xmlTextWriterWriteDocCallback, 00326 (xmlOutputCloseCallback) 00327 xmlTextWriterCloseDocCallback, 00328 (void *) ctxt, NULL); 00329 if (out == NULL) { 00330 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR, 00331 "xmlNewTextWriterPushParser : error at xmlOutputBufferCreateIO!\n"); 00332 return NULL; 00333 } 00334 00335 ret = xmlNewTextWriter(out); 00336 if (ret == NULL) { 00337 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR, 00338 "xmlNewTextWriterPushParser : error at xmlNewTextWriter!\n"); 00339 xmlOutputBufferClose(out); 00340 return NULL; 00341 } 00342 00343 ret->ctxt = ctxt; 00344 00345 return ret; 00346 } 00347 00357 xmlTextWriterPtr 00358 xmlNewTextWriterDoc(xmlDocPtr * doc, int compression) 00359 { 00360 xmlTextWriterPtr ret; 00361 xmlSAXHandler saxHandler; 00362 xmlParserCtxtPtr ctxt; 00363 00364 memset(&saxHandler, '\0', sizeof(saxHandler)); 00365 xmlSAX2InitDefaultSAXHandler(&saxHandler, 1); 00366 saxHandler.startDocument = xmlTextWriterStartDocumentCallback; 00367 saxHandler.startElement = xmlSAX2StartElement; 00368 saxHandler.endElement = xmlSAX2EndElement; 00369 00370 ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL); 00371 if (ctxt == NULL) { 00372 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR, 00373 "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n"); 00374 return NULL; 00375 } 00376 /* 00377 * For some reason this seems to completely break if node names 00378 * are interned. 00379 */ 00380 ctxt->dictNames = 0; 00381 00382 ctxt->myDoc = xmlNewDoc(BAD_CAST XML_DEFAULT_VERSION); 00383 if (ctxt->myDoc == NULL) { 00384 xmlFreeParserCtxt(ctxt); 00385 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR, 00386 "xmlNewTextWriterDoc : error at xmlNewDoc!\n"); 00387 return NULL; 00388 } 00389 00390 ret = xmlNewTextWriterPushParser(ctxt, compression); 00391 if (ret == NULL) { 00392 xmlFreeDoc(ctxt->myDoc); 00393 xmlFreeParserCtxt(ctxt); 00394 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR, 00395 "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n"); 00396 return NULL; 00397 } 00398 00399 xmlSetDocCompressMode(ctxt->myDoc, compression); 00400 00401 if (doc != NULL) { 00402 *doc = ctxt->myDoc; 00403 ret->no_doc_free = 1; 00404 } 00405 00406 return ret; 00407 } 00408 00420 xmlTextWriterPtr 00421 xmlNewTextWriterTree(xmlDocPtr doc, xmlNodePtr node, int compression) 00422 { 00423 xmlTextWriterPtr ret; 00424 xmlSAXHandler saxHandler; 00425 xmlParserCtxtPtr ctxt; 00426 00427 if (doc == NULL) { 00428 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR, 00429 "xmlNewTextWriterTree : invalid document tree!\n"); 00430 return NULL; 00431 } 00432 00433 memset(&saxHandler, '\0', sizeof(saxHandler)); 00434 xmlSAX2InitDefaultSAXHandler(&saxHandler, 1); 00435 saxHandler.startDocument = xmlTextWriterStartDocumentCallback; 00436 saxHandler.startElement = xmlSAX2StartElement; 00437 saxHandler.endElement = xmlSAX2EndElement; 00438 00439 ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL); 00440 if (ctxt == NULL) { 00441 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR, 00442 "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n"); 00443 return NULL; 00444 } 00445 /* 00446 * For some reason this seems to completely break if node names 00447 * are interned. 00448 */ 00449 ctxt->dictNames = 0; 00450 00451 ret = xmlNewTextWriterPushParser(ctxt, compression); 00452 if (ret == NULL) { 00453 xmlFreeParserCtxt(ctxt); 00454 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR, 00455 "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n"); 00456 return NULL; 00457 } 00458 00459 ctxt->myDoc = doc; 00460 ctxt->node = node; 00461 ret->no_doc_free = 1; 00462 00463 xmlSetDocCompressMode(doc, compression); 00464 00465 return ret; 00466 } 00467 00474 void 00475 xmlFreeTextWriter(xmlTextWriterPtr writer) 00476 { 00477 if (writer == NULL) 00478 return; 00479 00480 if (writer->out != NULL) 00481 xmlOutputBufferClose(writer->out); 00482 00483 if (writer->nodes != NULL) 00484 xmlListDelete(writer->nodes); 00485 00486 if (writer->nsstack != NULL) 00487 xmlListDelete(writer->nsstack); 00488 00489 if (writer->ctxt != NULL) { 00490 if ((writer->ctxt->myDoc != NULL) && (writer->no_doc_free == 0)) { 00491 xmlFreeDoc(writer->ctxt->myDoc); 00492 writer->ctxt->myDoc = NULL; 00493 } 00494 xmlFreeParserCtxt(writer->ctxt); 00495 } 00496 00497 if (writer->doc != NULL) 00498 xmlFreeDoc(writer->doc); 00499 00500 if (writer->ichar != NULL) 00501 xmlFree(writer->ichar); 00502 xmlFree(writer); 00503 } 00504 00516 int 00517 xmlTextWriterStartDocument(xmlTextWriterPtr writer, const char *version, 00518 const char *encoding, const char *standalone) 00519 { 00520 int count; 00521 int sum; 00522 xmlLinkPtr lk; 00523 xmlCharEncodingHandlerPtr encoder; 00524 00525 if ((writer == NULL) || (writer->out == NULL)) { 00526 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 00527 "xmlTextWriterStartDocument : invalid writer!\n"); 00528 return -1; 00529 } 00530 00531 lk = xmlListFront(writer->nodes); 00532 if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) { 00533 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 00534 "xmlTextWriterStartDocument : not allowed in this context!\n"); 00535 return -1; 00536 } 00537 00538 encoder = NULL; 00539 if (encoding != NULL) { 00540 encoder = xmlFindCharEncodingHandler(encoding); 00541 if (encoder == NULL) { 00542 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 00543 "xmlTextWriterStartDocument : out of memory!\n"); 00544 return -1; 00545 } 00546 } 00547 00548 writer->out->encoder = encoder; 00549 if (encoder != NULL) { 00550 if (writer->out->conv == NULL) { 00551 writer->out->conv = xmlBufferCreateSize(4000); 00552 } 00553 xmlCharEncOutFunc(encoder, writer->out->conv, NULL); 00554 if ((writer->doc != NULL) && (writer->doc->encoding == NULL)) 00555 writer->doc->encoding = xmlStrdup((xmlChar *)writer->out->encoder->name); 00556 } else 00557 writer->out->conv = NULL; 00558 00559 sum = 0; 00560 count = xmlOutputBufferWriteString(writer->out, "<?xml version="); 00561 if (count < 0) 00562 return -1; 00563 sum += count; 00564 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 00565 if (count < 0) 00566 return -1; 00567 sum += count; 00568 if (version != 0) 00569 count = xmlOutputBufferWriteString(writer->out, version); 00570 else 00571 count = xmlOutputBufferWriteString(writer->out, "1.0"); 00572 if (count < 0) 00573 return -1; 00574 sum += count; 00575 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 00576 if (count < 0) 00577 return -1; 00578 sum += count; 00579 if (writer->out->encoder != 0) { 00580 count = xmlOutputBufferWriteString(writer->out, " encoding="); 00581 if (count < 0) 00582 return -1; 00583 sum += count; 00584 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 00585 if (count < 0) 00586 return -1; 00587 sum += count; 00588 count = 00589 xmlOutputBufferWriteString(writer->out, 00590 writer->out->encoder->name); 00591 if (count < 0) 00592 return -1; 00593 sum += count; 00594 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 00595 if (count < 0) 00596 return -1; 00597 sum += count; 00598 } 00599 00600 if (standalone != 0) { 00601 count = xmlOutputBufferWriteString(writer->out, " standalone="); 00602 if (count < 0) 00603 return -1; 00604 sum += count; 00605 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 00606 if (count < 0) 00607 return -1; 00608 sum += count; 00609 count = xmlOutputBufferWriteString(writer->out, standalone); 00610 if (count < 0) 00611 return -1; 00612 sum += count; 00613 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 00614 if (count < 0) 00615 return -1; 00616 sum += count; 00617 } 00618 00619 count = xmlOutputBufferWriteString(writer->out, "?>\n"); 00620 if (count < 0) 00621 return -1; 00622 sum += count; 00623 00624 return sum; 00625 } 00626 00636 int 00637 xmlTextWriterEndDocument(xmlTextWriterPtr writer) 00638 { 00639 int count; 00640 int sum; 00641 xmlLinkPtr lk; 00642 xmlTextWriterStackEntry *p; 00643 00644 if (writer == NULL) { 00645 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 00646 "xmlTextWriterEndDocument : invalid writer!\n"); 00647 return -1; 00648 } 00649 00650 sum = 0; 00651 while ((lk = xmlListFront(writer->nodes)) != NULL) { 00652 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 00653 if (p == 0) 00654 break; 00655 switch (p->state) { 00656 case XML_TEXTWRITER_NAME: 00657 case XML_TEXTWRITER_ATTRIBUTE: 00658 case XML_TEXTWRITER_TEXT: 00659 count = xmlTextWriterEndElement(writer); 00660 if (count < 0) 00661 return -1; 00662 sum += count; 00663 break; 00664 case XML_TEXTWRITER_PI: 00665 case XML_TEXTWRITER_PI_TEXT: 00666 count = xmlTextWriterEndPI(writer); 00667 if (count < 0) 00668 return -1; 00669 sum += count; 00670 break; 00671 case XML_TEXTWRITER_CDATA: 00672 count = xmlTextWriterEndCDATA(writer); 00673 if (count < 0) 00674 return -1; 00675 sum += count; 00676 break; 00677 case XML_TEXTWRITER_DTD: 00678 case XML_TEXTWRITER_DTD_TEXT: 00679 case XML_TEXTWRITER_DTD_ELEM: 00680 case XML_TEXTWRITER_DTD_ELEM_TEXT: 00681 case XML_TEXTWRITER_DTD_ATTL: 00682 case XML_TEXTWRITER_DTD_ATTL_TEXT: 00683 case XML_TEXTWRITER_DTD_ENTY: 00684 case XML_TEXTWRITER_DTD_ENTY_TEXT: 00685 case XML_TEXTWRITER_DTD_PENT: 00686 count = xmlTextWriterEndDTD(writer); 00687 if (count < 0) 00688 return -1; 00689 sum += count; 00690 break; 00691 case XML_TEXTWRITER_COMMENT: 00692 count = xmlTextWriterEndComment(writer); 00693 if (count < 0) 00694 return -1; 00695 sum += count; 00696 break; 00697 default: 00698 break; 00699 } 00700 } 00701 00702 if (!writer->indent) { 00703 count = xmlOutputBufferWriteString(writer->out, "\n"); 00704 if (count < 0) 00705 return -1; 00706 sum += count; 00707 } 00708 00709 sum += xmlTextWriterFlush(writer); 00710 00711 return sum; 00712 } 00713 00722 int 00723 xmlTextWriterStartComment(xmlTextWriterPtr writer) 00724 { 00725 int count; 00726 int sum; 00727 xmlLinkPtr lk; 00728 xmlTextWriterStackEntry *p; 00729 00730 if (writer == NULL) { 00731 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 00732 "xmlTextWriterStartComment : invalid writer!\n"); 00733 return -1; 00734 } 00735 00736 sum = 0; 00737 lk = xmlListFront(writer->nodes); 00738 if (lk != 0) { 00739 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 00740 if (p != 0) { 00741 switch (p->state) { 00742 case XML_TEXTWRITER_TEXT: 00743 case XML_TEXTWRITER_NONE: 00744 break; 00745 case XML_TEXTWRITER_NAME: 00746 /* Output namespace declarations */ 00747 count = xmlTextWriterOutputNSDecl(writer); 00748 if (count < 0) 00749 return -1; 00750 sum += count; 00751 count = xmlOutputBufferWriteString(writer->out, ">"); 00752 if (count < 0) 00753 return -1; 00754 sum += count; 00755 if (writer->indent) { 00756 count = 00757 xmlOutputBufferWriteString(writer->out, "\n"); 00758 if (count < 0) 00759 return -1; 00760 sum += count; 00761 } 00762 p->state = XML_TEXTWRITER_TEXT; 00763 break; 00764 default: 00765 return -1; 00766 } 00767 } 00768 } 00769 00770 p = (xmlTextWriterStackEntry *) 00771 xmlMalloc(sizeof(xmlTextWriterStackEntry)); 00772 if (p == 0) { 00773 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 00774 "xmlTextWriterStartElement : out of memory!\n"); 00775 return -1; 00776 } 00777 00778 p->name = NULL; 00779 p->state = XML_TEXTWRITER_COMMENT; 00780 00781 xmlListPushFront(writer->nodes, p); 00782 00783 if (writer->indent) { 00784 count = xmlTextWriterWriteIndent(writer); 00785 if (count < 0) 00786 return -1; 00787 sum += count; 00788 } 00789 00790 count = xmlOutputBufferWriteString(writer->out, "<!--"); 00791 if (count < 0) 00792 return -1; 00793 sum += count; 00794 00795 return sum; 00796 } 00797 00806 int 00807 xmlTextWriterEndComment(xmlTextWriterPtr writer) 00808 { 00809 int count; 00810 int sum; 00811 xmlLinkPtr lk; 00812 xmlTextWriterStackEntry *p; 00813 00814 if (writer == NULL) { 00815 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 00816 "xmlTextWriterEndComment : invalid writer!\n"); 00817 return -1; 00818 } 00819 00820 lk = xmlListFront(writer->nodes); 00821 if (lk == 0) { 00822 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 00823 "xmlTextWriterEndComment : not allowed in this context!\n"); 00824 return -1; 00825 } 00826 00827 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 00828 if (p == 0) 00829 return -1; 00830 00831 sum = 0; 00832 switch (p->state) { 00833 case XML_TEXTWRITER_COMMENT: 00834 count = xmlOutputBufferWriteString(writer->out, "-->"); 00835 if (count < 0) 00836 return -1; 00837 sum += count; 00838 break; 00839 default: 00840 return -1; 00841 } 00842 00843 if (writer->indent) { 00844 count = xmlOutputBufferWriteString(writer->out, "\n"); 00845 if (count < 0) 00846 return -1; 00847 sum += count; 00848 } 00849 00850 xmlListPopFront(writer->nodes); 00851 return sum; 00852 } 00853 00864 int XMLCDECL 00865 xmlTextWriterWriteFormatComment(xmlTextWriterPtr writer, 00866 const char *format, ...) 00867 { 00868 int rc; 00869 va_list ap; 00870 00871 va_start(ap, format); 00872 00873 rc = xmlTextWriterWriteVFormatComment(writer, format, ap); 00874 00875 va_end(ap); 00876 return rc; 00877 } 00878 00889 int 00890 xmlTextWriterWriteVFormatComment(xmlTextWriterPtr writer, 00891 const char *format, va_list argptr) 00892 { 00893 int rc; 00894 xmlChar *buf; 00895 00896 if (writer == NULL) { 00897 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 00898 "xmlTextWriterWriteVFormatComment : invalid writer!\n"); 00899 return -1; 00900 } 00901 00902 buf = xmlTextWriterVSprintf(format, argptr); 00903 if (buf == NULL) 00904 return -1; 00905 00906 rc = xmlTextWriterWriteComment(writer, buf); 00907 00908 xmlFree(buf); 00909 return rc; 00910 } 00911 00921 int 00922 xmlTextWriterWriteComment(xmlTextWriterPtr writer, const xmlChar * content) 00923 { 00924 int count; 00925 int sum; 00926 00927 sum = 0; 00928 count = xmlTextWriterStartComment(writer); 00929 if (count < 0) 00930 return -1; 00931 sum += count; 00932 count = xmlTextWriterWriteString(writer, content); 00933 if (count < 0) 00934 return -1; 00935 sum += count; 00936 count = xmlTextWriterEndComment(writer); 00937 if (count < 0) 00938 return -1; 00939 sum += count; 00940 00941 return sum; 00942 } 00943 00953 int 00954 xmlTextWriterStartElement(xmlTextWriterPtr writer, const xmlChar * name) 00955 { 00956 int count; 00957 int sum; 00958 xmlLinkPtr lk; 00959 xmlTextWriterStackEntry *p; 00960 00961 if ((writer == NULL) || (name == NULL) || (*name == '\0')) 00962 return -1; 00963 00964 sum = 0; 00965 lk = xmlListFront(writer->nodes); 00966 if (lk != 0) { 00967 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 00968 if (p != 0) { 00969 switch (p->state) { 00970 case XML_TEXTWRITER_PI: 00971 case XML_TEXTWRITER_PI_TEXT: 00972 return -1; 00973 case XML_TEXTWRITER_NONE: 00974 break; 00975 case XML_TEXTWRITER_ATTRIBUTE: 00976 count = xmlTextWriterEndAttribute(writer); 00977 if (count < 0) 00978 return -1; 00979 sum += count; 00980 /* fallthrough */ 00981 case XML_TEXTWRITER_NAME: 00982 /* Output namespace declarations */ 00983 count = xmlTextWriterOutputNSDecl(writer); 00984 if (count < 0) 00985 return -1; 00986 sum += count; 00987 count = xmlOutputBufferWriteString(writer->out, ">"); 00988 if (count < 0) 00989 return -1; 00990 sum += count; 00991 if (writer->indent) 00992 count = 00993 xmlOutputBufferWriteString(writer->out, "\n"); 00994 p->state = XML_TEXTWRITER_TEXT; 00995 break; 00996 default: 00997 break; 00998 } 00999 } 01000 } 01001 01002 p = (xmlTextWriterStackEntry *) 01003 xmlMalloc(sizeof(xmlTextWriterStackEntry)); 01004 if (p == 0) { 01005 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 01006 "xmlTextWriterStartElement : out of memory!\n"); 01007 return -1; 01008 } 01009 01010 p->name = xmlStrdup(name); 01011 if (p->name == 0) { 01012 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 01013 "xmlTextWriterStartElement : out of memory!\n"); 01014 xmlFree(p); 01015 return -1; 01016 } 01017 p->state = XML_TEXTWRITER_NAME; 01018 01019 xmlListPushFront(writer->nodes, p); 01020 01021 if (writer->indent) { 01022 count = xmlTextWriterWriteIndent(writer); 01023 sum += count; 01024 } 01025 01026 count = xmlOutputBufferWriteString(writer->out, "<"); 01027 if (count < 0) 01028 return -1; 01029 sum += count; 01030 count = 01031 xmlOutputBufferWriteString(writer->out, (const char *) p->name); 01032 if (count < 0) 01033 return -1; 01034 sum += count; 01035 01036 return sum; 01037 } 01038 01050 int 01051 xmlTextWriterStartElementNS(xmlTextWriterPtr writer, 01052 const xmlChar * prefix, const xmlChar * name, 01053 const xmlChar * namespaceURI) 01054 { 01055 int count; 01056 int sum; 01057 xmlChar *buf; 01058 01059 if ((writer == NULL) || (name == NULL) || (*name == '\0')) 01060 return -1; 01061 01062 buf = NULL; 01063 if (prefix != 0) { 01064 buf = xmlStrdup(prefix); 01065 buf = xmlStrcat(buf, BAD_CAST ":"); 01066 } 01067 buf = xmlStrcat(buf, name); 01068 01069 sum = 0; 01070 count = xmlTextWriterStartElement(writer, buf); 01071 xmlFree(buf); 01072 if (count < 0) 01073 return -1; 01074 sum += count; 01075 01076 if (namespaceURI != 0) { 01077 xmlTextWriterNsStackEntry *p = (xmlTextWriterNsStackEntry *) 01078 xmlMalloc(sizeof(xmlTextWriterNsStackEntry)); 01079 if (p == 0) { 01080 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 01081 "xmlTextWriterStartElementNS : out of memory!\n"); 01082 return -1; 01083 } 01084 01085 buf = xmlStrdup(BAD_CAST "xmlns"); 01086 if (prefix != 0) { 01087 buf = xmlStrcat(buf, BAD_CAST ":"); 01088 buf = xmlStrcat(buf, prefix); 01089 } 01090 01091 p->prefix = buf; 01092 p->uri = xmlStrdup(namespaceURI); 01093 if (p->uri == 0) { 01094 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 01095 "xmlTextWriterStartElementNS : out of memory!\n"); 01096 xmlFree(p); 01097 return -1; 01098 } 01099 p->elem = xmlListFront(writer->nodes); 01100 01101 xmlListPushFront(writer->nsstack, p); 01102 } 01103 01104 return sum; 01105 } 01106 01115 int 01116 xmlTextWriterEndElement(xmlTextWriterPtr writer) 01117 { 01118 int count; 01119 int sum; 01120 xmlLinkPtr lk; 01121 xmlTextWriterStackEntry *p; 01122 01123 if (writer == NULL) 01124 return -1; 01125 01126 lk = xmlListFront(writer->nodes); 01127 if (lk == 0) { 01128 xmlListDelete(writer->nsstack); 01129 writer->nsstack = NULL; 01130 return -1; 01131 } 01132 01133 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 01134 if (p == 0) { 01135 xmlListDelete(writer->nsstack); 01136 writer->nsstack = NULL; 01137 return -1; 01138 } 01139 01140 sum = 0; 01141 switch (p->state) { 01142 case XML_TEXTWRITER_ATTRIBUTE: 01143 count = xmlTextWriterEndAttribute(writer); 01144 if (count < 0) { 01145 xmlListDelete(writer->nsstack); 01146 writer->nsstack = NULL; 01147 return -1; 01148 } 01149 sum += count; 01150 /* fallthrough */ 01151 case XML_TEXTWRITER_NAME: 01152 /* Output namespace declarations */ 01153 count = xmlTextWriterOutputNSDecl(writer); 01154 if (count < 0) 01155 return -1; 01156 sum += count; 01157 01158 if (writer->indent) /* next element needs indent */ 01159 writer->doindent = 1; 01160 count = xmlOutputBufferWriteString(writer->out, "/>"); 01161 if (count < 0) 01162 return -1; 01163 sum += count; 01164 break; 01165 case XML_TEXTWRITER_TEXT: 01166 if ((writer->indent) && (writer->doindent)) { 01167 count = xmlTextWriterWriteIndent(writer); 01168 sum += count; 01169 writer->doindent = 1; 01170 } else 01171 writer->doindent = 1; 01172 count = xmlOutputBufferWriteString(writer->out, "</"); 01173 if (count < 0) 01174 return -1; 01175 sum += count; 01176 count = xmlOutputBufferWriteString(writer->out, 01177 (const char *) p->name); 01178 if (count < 0) 01179 return -1; 01180 sum += count; 01181 count = xmlOutputBufferWriteString(writer->out, ">"); 01182 if (count < 0) 01183 return -1; 01184 sum += count; 01185 break; 01186 default: 01187 return -1; 01188 } 01189 01190 if (writer->indent) { 01191 count = xmlOutputBufferWriteString(writer->out, "\n"); 01192 sum += count; 01193 } 01194 01195 xmlListPopFront(writer->nodes); 01196 return sum; 01197 } 01198 01207 int 01208 xmlTextWriterFullEndElement(xmlTextWriterPtr writer) 01209 { 01210 int count; 01211 int sum; 01212 xmlLinkPtr lk; 01213 xmlTextWriterStackEntry *p; 01214 01215 if (writer == NULL) 01216 return -1; 01217 01218 lk = xmlListFront(writer->nodes); 01219 if (lk == 0) 01220 return -1; 01221 01222 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 01223 if (p == 0) 01224 return -1; 01225 01226 sum = 0; 01227 switch (p->state) { 01228 case XML_TEXTWRITER_ATTRIBUTE: 01229 count = xmlTextWriterEndAttribute(writer); 01230 if (count < 0) 01231 return -1; 01232 sum += count; 01233 /* fallthrough */ 01234 case XML_TEXTWRITER_NAME: 01235 /* Output namespace declarations */ 01236 count = xmlTextWriterOutputNSDecl(writer); 01237 if (count < 0) 01238 return -1; 01239 sum += count; 01240 01241 count = xmlOutputBufferWriteString(writer->out, ">"); 01242 if (count < 0) 01243 return -1; 01244 sum += count; 01245 if (writer->indent) 01246 writer->doindent = 0; 01247 /* fallthrough */ 01248 case XML_TEXTWRITER_TEXT: 01249 if ((writer->indent) && (writer->doindent)) { 01250 count = xmlTextWriterWriteIndent(writer); 01251 sum += count; 01252 writer->doindent = 1; 01253 } else 01254 writer->doindent = 1; 01255 count = xmlOutputBufferWriteString(writer->out, "</"); 01256 if (count < 0) 01257 return -1; 01258 sum += count; 01259 count = xmlOutputBufferWriteString(writer->out, 01260 (const char *) p->name); 01261 if (count < 0) 01262 return -1; 01263 sum += count; 01264 count = xmlOutputBufferWriteString(writer->out, ">"); 01265 if (count < 0) 01266 return -1; 01267 sum += count; 01268 break; 01269 default: 01270 return -1; 01271 } 01272 01273 if (writer->indent) { 01274 count = xmlOutputBufferWriteString(writer->out, "\n"); 01275 sum += count; 01276 } 01277 01278 xmlListPopFront(writer->nodes); 01279 return sum; 01280 } 01281 01292 int XMLCDECL 01293 xmlTextWriterWriteFormatRaw(xmlTextWriterPtr writer, const char *format, 01294 ...) 01295 { 01296 int rc; 01297 va_list ap; 01298 01299 va_start(ap, format); 01300 01301 rc = xmlTextWriterWriteVFormatRaw(writer, format, ap); 01302 01303 va_end(ap); 01304 return rc; 01305 } 01306 01317 int 01318 xmlTextWriterWriteVFormatRaw(xmlTextWriterPtr writer, const char *format, 01319 va_list argptr) 01320 { 01321 int rc; 01322 xmlChar *buf; 01323 01324 if (writer == NULL) 01325 return -1; 01326 01327 buf = xmlTextWriterVSprintf(format, argptr); 01328 if (buf == NULL) 01329 return -1; 01330 01331 rc = xmlTextWriterWriteRaw(writer, buf); 01332 01333 xmlFree(buf); 01334 return rc; 01335 } 01336 01348 int 01349 xmlTextWriterWriteRawLen(xmlTextWriterPtr writer, const xmlChar * content, 01350 int len) 01351 { 01352 int count; 01353 int sum; 01354 xmlLinkPtr lk; 01355 xmlTextWriterStackEntry *p; 01356 01357 if (writer == NULL) { 01358 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 01359 "xmlTextWriterWriteRawLen : invalid writer!\n"); 01360 return -1; 01361 } 01362 01363 if ((content == NULL) || (len < 0)) { 01364 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 01365 "xmlTextWriterWriteRawLen : invalid content!\n"); 01366 return -1; 01367 } 01368 01369 sum = 0; 01370 lk = xmlListFront(writer->nodes); 01371 if (lk != 0) { 01372 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 01373 count = xmlTextWriterHandleStateDependencies(writer, p); 01374 if (count < 0) 01375 return -1; 01376 sum += count; 01377 } 01378 01379 if (writer->indent) 01380 writer->doindent = 0; 01381 01382 if (content != NULL) { 01383 count = 01384 xmlOutputBufferWrite(writer->out, len, (const char *) content); 01385 if (count < 0) 01386 return -1; 01387 sum += count; 01388 } 01389 01390 return sum; 01391 } 01392 01402 int 01403 xmlTextWriterWriteRaw(xmlTextWriterPtr writer, const xmlChar * content) 01404 { 01405 return xmlTextWriterWriteRawLen(writer, content, xmlStrlen(content)); 01406 } 01407 01418 int XMLCDECL 01419 xmlTextWriterWriteFormatString(xmlTextWriterPtr writer, const char *format, 01420 ...) 01421 { 01422 int rc; 01423 va_list ap; 01424 01425 if ((writer == NULL) || (format == NULL)) 01426 return -1; 01427 01428 va_start(ap, format); 01429 01430 rc = xmlTextWriterWriteVFormatString(writer, format, ap); 01431 01432 va_end(ap); 01433 return rc; 01434 } 01435 01446 int 01447 xmlTextWriterWriteVFormatString(xmlTextWriterPtr writer, 01448 const char *format, va_list argptr) 01449 { 01450 int rc; 01451 xmlChar *buf; 01452 01453 if ((writer == NULL) || (format == NULL)) 01454 return -1; 01455 01456 buf = xmlTextWriterVSprintf(format, argptr); 01457 if (buf == NULL) 01458 return -1; 01459 01460 rc = xmlTextWriterWriteString(writer, buf); 01461 01462 xmlFree(buf); 01463 return rc; 01464 } 01465 01475 int 01476 xmlTextWriterWriteString(xmlTextWriterPtr writer, const xmlChar * content) 01477 { 01478 int count; 01479 int sum; 01480 xmlLinkPtr lk; 01481 xmlTextWriterStackEntry *p; 01482 xmlChar *buf; 01483 01484 if ((writer == NULL) || (content == NULL)) 01485 return -1; 01486 01487 sum = 0; 01488 buf = (xmlChar *) content; 01489 lk = xmlListFront(writer->nodes); 01490 if (lk != 0) { 01491 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 01492 if (p != 0) { 01493 switch (p->state) { 01494 case XML_TEXTWRITER_NAME: 01495 case XML_TEXTWRITER_TEXT: 01496 #if 0 01497 buf = NULL; 01498 xmlOutputBufferWriteEscape(writer->out, content, NULL); 01499 #endif 01500 buf = xmlEncodeSpecialChars(NULL, content); 01501 break; 01502 case XML_TEXTWRITER_ATTRIBUTE: 01503 buf = NULL; 01504 xmlAttrSerializeTxtContent(writer->out->buffer, writer->doc, 01505 NULL, content); 01506 break; 01507 default: 01508 break; 01509 } 01510 } 01511 } 01512 01513 if (buf != NULL) { 01514 count = xmlTextWriterWriteRaw(writer, buf); 01515 01516 if (buf != content) /* buf was allocated by us, so free it */ 01517 xmlFree(buf); 01518 01519 if (count < 0) 01520 return -1; 01521 sum += count; 01522 } 01523 01524 return sum; 01525 } 01526 01538 static int 01539 xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len, 01540 const unsigned char *data) 01541 { 01542 static unsigned char dtable[64] = 01543 {'A','B','C','D','E','F','G','H','I','J','K','L','M', 01544 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z', 01545 'a','b','c','d','e','f','g','h','i','j','k','l','m', 01546 'n','o','p','q','r','s','t','u','v','w','x','y','z', 01547 '0','1','2','3','4','5','6','7','8','9','+','/'}; 01548 01549 int i; 01550 int linelen; 01551 int count; 01552 int sum; 01553 01554 if ((out == NULL) || (len < 0) || (data == NULL)) 01555 return(-1); 01556 01557 linelen = 0; 01558 sum = 0; 01559 01560 i = 0; 01561 while (1) { 01562 unsigned char igroup[3]; 01563 unsigned char ogroup[4]; 01564 int c; 01565 int n; 01566 01567 igroup[0] = igroup[1] = igroup[2] = 0; 01568 for (n = 0; n < 3 && i < len; n++, i++) { 01569 c = data[i]; 01570 igroup[n] = (unsigned char) c; 01571 } 01572 01573 if (n > 0) { 01574 ogroup[0] = dtable[igroup[0] >> 2]; 01575 ogroup[1] = dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)]; 01576 ogroup[2] = 01577 dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)]; 01578 ogroup[3] = dtable[igroup[2] & 0x3F]; 01579 01580 if (n < 3) { 01581 ogroup[3] = '='; 01582 if (n < 2) { 01583 ogroup[2] = '='; 01584 } 01585 } 01586 01587 if (linelen >= B64LINELEN) { 01588 count = xmlOutputBufferWrite(out, 2, B64CRLF); 01589 if (count == -1) 01590 return -1; 01591 sum += count; 01592 linelen = 0; 01593 } 01594 count = xmlOutputBufferWrite(out, 4, (const char *) ogroup); 01595 if (count == -1) 01596 return -1; 01597 sum += count; 01598 01599 linelen += 4; 01600 } 01601 01602 if (i >= len) 01603 break; 01604 } 01605 01606 return sum; 01607 } 01608 01620 int 01621 xmlTextWriterWriteBase64(xmlTextWriterPtr writer, const char *data, 01622 int start, int len) 01623 { 01624 int count; 01625 int sum; 01626 xmlLinkPtr lk; 01627 xmlTextWriterStackEntry *p; 01628 01629 if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0)) 01630 return -1; 01631 01632 sum = 0; 01633 lk = xmlListFront(writer->nodes); 01634 if (lk != 0) { 01635 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 01636 if (p != 0) { 01637 count = xmlTextWriterHandleStateDependencies(writer, p); 01638 if (count < 0) 01639 return -1; 01640 sum += count; 01641 } 01642 } 01643 01644 if (writer->indent) 01645 writer->doindent = 0; 01646 01647 count = 01648 xmlOutputBufferWriteBase64(writer->out, len, 01649 (unsigned char *) data + start); 01650 if (count < 0) 01651 return -1; 01652 sum += count; 01653 01654 return sum; 01655 } 01656 01669 static int 01670 xmlOutputBufferWriteBinHex(xmlOutputBufferPtr out, 01671 int len, const unsigned char *data) 01672 { 01673 int count; 01674 int sum; 01675 static char hex[16] = 01676 {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; 01677 int i; 01678 01679 if ((out == NULL) || (data == NULL) || (len < 0)) { 01680 return -1; 01681 } 01682 01683 sum = 0; 01684 for (i = 0; i < len; i++) { 01685 count = 01686 xmlOutputBufferWrite(out, 1, 01687 (const char *) &hex[data[i] >> 4]); 01688 if (count == -1) 01689 return -1; 01690 sum += count; 01691 count = 01692 xmlOutputBufferWrite(out, 1, 01693 (const char *) &hex[data[i] & 0xF]); 01694 if (count == -1) 01695 return -1; 01696 sum += count; 01697 } 01698 01699 return sum; 01700 } 01701 01713 int 01714 xmlTextWriterWriteBinHex(xmlTextWriterPtr writer, const char *data, 01715 int start, int len) 01716 { 01717 int count; 01718 int sum; 01719 xmlLinkPtr lk; 01720 xmlTextWriterStackEntry *p; 01721 01722 if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0)) 01723 return -1; 01724 01725 sum = 0; 01726 lk = xmlListFront(writer->nodes); 01727 if (lk != 0) { 01728 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 01729 if (p != 0) { 01730 count = xmlTextWriterHandleStateDependencies(writer, p); 01731 if (count < 0) 01732 return -1; 01733 sum += count; 01734 } 01735 } 01736 01737 if (writer->indent) 01738 writer->doindent = 0; 01739 01740 count = 01741 xmlOutputBufferWriteBinHex(writer->out, len, 01742 (unsigned char *) data + start); 01743 if (count < 0) 01744 return -1; 01745 sum += count; 01746 01747 return sum; 01748 } 01749 01759 int 01760 xmlTextWriterStartAttribute(xmlTextWriterPtr writer, const xmlChar * name) 01761 { 01762 int count; 01763 int sum; 01764 xmlLinkPtr lk; 01765 xmlTextWriterStackEntry *p; 01766 01767 if ((writer == NULL) || (name == NULL) || (*name == '\0')) 01768 return -1; 01769 01770 sum = 0; 01771 lk = xmlListFront(writer->nodes); 01772 if (lk == 0) 01773 return -1; 01774 01775 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 01776 if (p == 0) 01777 return -1; 01778 01779 switch (p->state) { 01780 case XML_TEXTWRITER_ATTRIBUTE: 01781 count = xmlTextWriterEndAttribute(writer); 01782 if (count < 0) 01783 return -1; 01784 sum += count; 01785 /* fallthrough */ 01786 case XML_TEXTWRITER_NAME: 01787 count = xmlOutputBufferWriteString(writer->out, " "); 01788 if (count < 0) 01789 return -1; 01790 sum += count; 01791 count = 01792 xmlOutputBufferWriteString(writer->out, 01793 (const char *) name); 01794 if (count < 0) 01795 return -1; 01796 sum += count; 01797 count = xmlOutputBufferWriteString(writer->out, "="); 01798 if (count < 0) 01799 return -1; 01800 sum += count; 01801 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 01802 if (count < 0) 01803 return -1; 01804 sum += count; 01805 p->state = XML_TEXTWRITER_ATTRIBUTE; 01806 break; 01807 default: 01808 return -1; 01809 } 01810 01811 return sum; 01812 } 01813 01825 int 01826 xmlTextWriterStartAttributeNS(xmlTextWriterPtr writer, 01827 const xmlChar * prefix, const xmlChar * name, 01828 const xmlChar * namespaceURI) 01829 { 01830 int count; 01831 int sum; 01832 xmlChar *buf; 01833 xmlTextWriterNsStackEntry *p; 01834 01835 if ((writer == NULL) || (name == NULL) || (*name == '\0')) 01836 return -1; 01837 01838 /* Handle namespace first in case of error */ 01839 if (namespaceURI != 0) { 01840 xmlTextWriterNsStackEntry nsentry, *curns; 01841 01842 buf = xmlStrdup(BAD_CAST "xmlns"); 01843 if (prefix != 0) { 01844 buf = xmlStrcat(buf, BAD_CAST ":"); 01845 buf = xmlStrcat(buf, prefix); 01846 } 01847 01848 nsentry.prefix = buf; 01849 nsentry.uri = (xmlChar *)namespaceURI; 01850 nsentry.elem = xmlListFront(writer->nodes); 01851 01852 curns = (xmlTextWriterNsStackEntry *)xmlListSearch(writer->nsstack, 01853 (void *)&nsentry); 01854 if ((curns != NULL)) { 01855 xmlFree(buf); 01856 if (xmlStrcmp(curns->uri, namespaceURI) == 0) { 01857 /* Namespace already defined on element skip */ 01858 buf = NULL; 01859 } else { 01860 /* Prefix mismatch so error out */ 01861 return -1; 01862 } 01863 } 01864 01865 /* Do not add namespace decl to list - it is already there */ 01866 if (buf != NULL) { 01867 p = (xmlTextWriterNsStackEntry *) 01868 xmlMalloc(sizeof(xmlTextWriterNsStackEntry)); 01869 if (p == 0) { 01870 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 01871 "xmlTextWriterStartAttributeNS : out of memory!\n"); 01872 return -1; 01873 } 01874 01875 p->prefix = buf; 01876 p->uri = xmlStrdup(namespaceURI); 01877 if (p->uri == 0) { 01878 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 01879 "xmlTextWriterStartAttributeNS : out of memory!\n"); 01880 xmlFree(p); 01881 return -1; 01882 } 01883 p->elem = xmlListFront(writer->nodes); 01884 01885 xmlListPushFront(writer->nsstack, p); 01886 } 01887 } 01888 01889 buf = NULL; 01890 if (prefix != 0) { 01891 buf = xmlStrdup(prefix); 01892 buf = xmlStrcat(buf, BAD_CAST ":"); 01893 } 01894 buf = xmlStrcat(buf, name); 01895 01896 sum = 0; 01897 count = xmlTextWriterStartAttribute(writer, buf); 01898 xmlFree(buf); 01899 if (count < 0) 01900 return -1; 01901 sum += count; 01902 01903 return sum; 01904 } 01905 01914 int 01915 xmlTextWriterEndAttribute(xmlTextWriterPtr writer) 01916 { 01917 int count; 01918 int sum; 01919 xmlLinkPtr lk; 01920 xmlTextWriterStackEntry *p; 01921 01922 if (writer == NULL) 01923 return -1; 01924 01925 lk = xmlListFront(writer->nodes); 01926 if (lk == 0) { 01927 return -1; 01928 } 01929 01930 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 01931 if (p == 0) { 01932 return -1; 01933 } 01934 01935 sum = 0; 01936 switch (p->state) { 01937 case XML_TEXTWRITER_ATTRIBUTE: 01938 p->state = XML_TEXTWRITER_NAME; 01939 01940 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 01941 if (count < 0) { 01942 return -1; 01943 } 01944 sum += count; 01945 break; 01946 default: 01947 return -1; 01948 } 01949 01950 return sum; 01951 } 01952 01964 int XMLCDECL 01965 xmlTextWriterWriteFormatAttribute(xmlTextWriterPtr writer, 01966 const xmlChar * name, const char *format, 01967 ...) 01968 { 01969 int rc; 01970 va_list ap; 01971 01972 va_start(ap, format); 01973 01974 rc = xmlTextWriterWriteVFormatAttribute(writer, name, format, ap); 01975 01976 va_end(ap); 01977 return rc; 01978 } 01979 01991 int 01992 xmlTextWriterWriteVFormatAttribute(xmlTextWriterPtr writer, 01993 const xmlChar * name, 01994 const char *format, va_list argptr) 01995 { 01996 int rc; 01997 xmlChar *buf; 01998 01999 if (writer == NULL) 02000 return -1; 02001 02002 buf = xmlTextWriterVSprintf(format, argptr); 02003 if (buf == NULL) 02004 return -1; 02005 02006 rc = xmlTextWriterWriteAttribute(writer, name, buf); 02007 02008 xmlFree(buf); 02009 return rc; 02010 } 02011 02022 int 02023 xmlTextWriterWriteAttribute(xmlTextWriterPtr writer, const xmlChar * name, 02024 const xmlChar * content) 02025 { 02026 int count; 02027 int sum; 02028 02029 sum = 0; 02030 count = xmlTextWriterStartAttribute(writer, name); 02031 if (count < 0) 02032 return -1; 02033 sum += count; 02034 count = xmlTextWriterWriteString(writer, content); 02035 if (count < 0) 02036 return -1; 02037 sum += count; 02038 count = xmlTextWriterEndAttribute(writer); 02039 if (count < 0) 02040 return -1; 02041 sum += count; 02042 02043 return sum; 02044 } 02045 02059 int XMLCDECL 02060 xmlTextWriterWriteFormatAttributeNS(xmlTextWriterPtr writer, 02061 const xmlChar * prefix, 02062 const xmlChar * name, 02063 const xmlChar * namespaceURI, 02064 const char *format, ...) 02065 { 02066 int rc; 02067 va_list ap; 02068 02069 va_start(ap, format); 02070 02071 rc = xmlTextWriterWriteVFormatAttributeNS(writer, prefix, name, 02072 namespaceURI, format, ap); 02073 02074 va_end(ap); 02075 return rc; 02076 } 02077 02091 int 02092 xmlTextWriterWriteVFormatAttributeNS(xmlTextWriterPtr writer, 02093 const xmlChar * prefix, 02094 const xmlChar * name, 02095 const xmlChar * namespaceURI, 02096 const char *format, va_list argptr) 02097 { 02098 int rc; 02099 xmlChar *buf; 02100 02101 if (writer == NULL) 02102 return -1; 02103 02104 buf = xmlTextWriterVSprintf(format, argptr); 02105 if (buf == NULL) 02106 return -1; 02107 02108 rc = xmlTextWriterWriteAttributeNS(writer, prefix, name, namespaceURI, 02109 buf); 02110 02111 xmlFree(buf); 02112 return rc; 02113 } 02114 02127 int 02128 xmlTextWriterWriteAttributeNS(xmlTextWriterPtr writer, 02129 const xmlChar * prefix, const xmlChar * name, 02130 const xmlChar * namespaceURI, 02131 const xmlChar * content) 02132 { 02133 int count; 02134 int sum; 02135 02136 if ((writer == NULL) || (name == NULL) || (*name == '\0')) 02137 return -1; 02138 02139 sum = 0; 02140 count = xmlTextWriterStartAttributeNS(writer, prefix, name, namespaceURI); 02141 if (count < 0) 02142 return -1; 02143 sum += count; 02144 count = xmlTextWriterWriteString(writer, content); 02145 if (count < 0) 02146 return -1; 02147 sum += count; 02148 count = xmlTextWriterEndAttribute(writer); 02149 if (count < 0) 02150 return -1; 02151 sum += count; 02152 02153 return sum; 02154 } 02155 02167 int XMLCDECL 02168 xmlTextWriterWriteFormatElement(xmlTextWriterPtr writer, 02169 const xmlChar * name, const char *format, 02170 ...) 02171 { 02172 int rc; 02173 va_list ap; 02174 02175 va_start(ap, format); 02176 02177 rc = xmlTextWriterWriteVFormatElement(writer, name, format, ap); 02178 02179 va_end(ap); 02180 return rc; 02181 } 02182 02194 int 02195 xmlTextWriterWriteVFormatElement(xmlTextWriterPtr writer, 02196 const xmlChar * name, const char *format, 02197 va_list argptr) 02198 { 02199 int rc; 02200 xmlChar *buf; 02201 02202 if (writer == NULL) 02203 return -1; 02204 02205 buf = xmlTextWriterVSprintf(format, argptr); 02206 if (buf == NULL) 02207 return -1; 02208 02209 rc = xmlTextWriterWriteElement(writer, name, buf); 02210 02211 xmlFree(buf); 02212 return rc; 02213 } 02214 02225 int 02226 xmlTextWriterWriteElement(xmlTextWriterPtr writer, const xmlChar * name, 02227 const xmlChar * content) 02228 { 02229 int count; 02230 int sum; 02231 02232 sum = 0; 02233 count = xmlTextWriterStartElement(writer, name); 02234 if (count == -1) 02235 return -1; 02236 sum += count; 02237 count = xmlTextWriterWriteString(writer, content); 02238 if (count == -1) 02239 return -1; 02240 sum += count; 02241 count = xmlTextWriterEndElement(writer); 02242 if (count == -1) 02243 return -1; 02244 sum += count; 02245 02246 return sum; 02247 } 02248 02262 int XMLCDECL 02263 xmlTextWriterWriteFormatElementNS(xmlTextWriterPtr writer, 02264 const xmlChar * prefix, 02265 const xmlChar * name, 02266 const xmlChar * namespaceURI, 02267 const char *format, ...) 02268 { 02269 int rc; 02270 va_list ap; 02271 02272 va_start(ap, format); 02273 02274 rc = xmlTextWriterWriteVFormatElementNS(writer, prefix, name, 02275 namespaceURI, format, ap); 02276 02277 va_end(ap); 02278 return rc; 02279 } 02280 02294 int 02295 xmlTextWriterWriteVFormatElementNS(xmlTextWriterPtr writer, 02296 const xmlChar * prefix, 02297 const xmlChar * name, 02298 const xmlChar * namespaceURI, 02299 const char *format, va_list argptr) 02300 { 02301 int rc; 02302 xmlChar *buf; 02303 02304 if (writer == NULL) 02305 return -1; 02306 02307 buf = xmlTextWriterVSprintf(format, argptr); 02308 if (buf == NULL) 02309 return -1; 02310 02311 rc = xmlTextWriterWriteElementNS(writer, prefix, name, namespaceURI, 02312 buf); 02313 02314 xmlFree(buf); 02315 return rc; 02316 } 02317 02330 int 02331 xmlTextWriterWriteElementNS(xmlTextWriterPtr writer, 02332 const xmlChar * prefix, const xmlChar * name, 02333 const xmlChar * namespaceURI, 02334 const xmlChar * content) 02335 { 02336 int count; 02337 int sum; 02338 02339 if ((writer == NULL) || (name == NULL) || (*name == '\0')) 02340 return -1; 02341 02342 sum = 0; 02343 count = 02344 xmlTextWriterStartElementNS(writer, prefix, name, namespaceURI); 02345 if (count < 0) 02346 return -1; 02347 sum += count; 02348 count = xmlTextWriterWriteString(writer, content); 02349 if (count == -1) 02350 return -1; 02351 sum += count; 02352 count = xmlTextWriterEndElement(writer); 02353 if (count == -1) 02354 return -1; 02355 sum += count; 02356 02357 return sum; 02358 } 02359 02369 int 02370 xmlTextWriterStartPI(xmlTextWriterPtr writer, const xmlChar * target) 02371 { 02372 int count; 02373 int sum; 02374 xmlLinkPtr lk; 02375 xmlTextWriterStackEntry *p; 02376 02377 if ((writer == NULL) || (target == NULL) || (*target == '\0')) 02378 return -1; 02379 02380 if (xmlStrcasecmp(target, (const xmlChar *) "xml") == 0) { 02381 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 02382 "xmlTextWriterStartPI : target name [Xx][Mm][Ll] is reserved for xml standardization!\n"); 02383 return -1; 02384 } 02385 02386 sum = 0; 02387 lk = xmlListFront(writer->nodes); 02388 if (lk != 0) { 02389 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 02390 if (p != 0) { 02391 switch (p->state) { 02392 case XML_TEXTWRITER_ATTRIBUTE: 02393 count = xmlTextWriterEndAttribute(writer); 02394 if (count < 0) 02395 return -1; 02396 sum += count; 02397 /* fallthrough */ 02398 case XML_TEXTWRITER_NAME: 02399 /* Output namespace declarations */ 02400 count = xmlTextWriterOutputNSDecl(writer); 02401 if (count < 0) 02402 return -1; 02403 sum += count; 02404 count = xmlOutputBufferWriteString(writer->out, ">"); 02405 if (count < 0) 02406 return -1; 02407 sum += count; 02408 p->state = XML_TEXTWRITER_TEXT; 02409 break; 02410 case XML_TEXTWRITER_NONE: 02411 case XML_TEXTWRITER_TEXT: 02412 case XML_TEXTWRITER_DTD: 02413 break; 02414 case XML_TEXTWRITER_PI: 02415 case XML_TEXTWRITER_PI_TEXT: 02416 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 02417 "xmlTextWriterStartPI : nested PI!\n"); 02418 return -1; 02419 default: 02420 return -1; 02421 } 02422 } 02423 } 02424 02425 p = (xmlTextWriterStackEntry *) 02426 xmlMalloc(sizeof(xmlTextWriterStackEntry)); 02427 if (p == 0) { 02428 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 02429 "xmlTextWriterStartPI : out of memory!\n"); 02430 return -1; 02431 } 02432 02433 p->name = xmlStrdup(target); 02434 if (p->name == 0) { 02435 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 02436 "xmlTextWriterStartPI : out of memory!\n"); 02437 xmlFree(p); 02438 return -1; 02439 } 02440 p->state = XML_TEXTWRITER_PI; 02441 02442 xmlListPushFront(writer->nodes, p); 02443 02444 count = xmlOutputBufferWriteString(writer->out, "<?"); 02445 if (count < 0) 02446 return -1; 02447 sum += count; 02448 count = 02449 xmlOutputBufferWriteString(writer->out, (const char *) p->name); 02450 if (count < 0) 02451 return -1; 02452 sum += count; 02453 02454 return sum; 02455 } 02456 02465 int 02466 xmlTextWriterEndPI(xmlTextWriterPtr writer) 02467 { 02468 int count; 02469 int sum; 02470 xmlLinkPtr lk; 02471 xmlTextWriterStackEntry *p; 02472 02473 if (writer == NULL) 02474 return -1; 02475 02476 lk = xmlListFront(writer->nodes); 02477 if (lk == 0) 02478 return 0; 02479 02480 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 02481 if (p == 0) 02482 return 0; 02483 02484 sum = 0; 02485 switch (p->state) { 02486 case XML_TEXTWRITER_PI: 02487 case XML_TEXTWRITER_PI_TEXT: 02488 count = xmlOutputBufferWriteString(writer->out, "?>"); 02489 if (count < 0) 02490 return -1; 02491 sum += count; 02492 break; 02493 default: 02494 return -1; 02495 } 02496 02497 if (writer->indent) { 02498 count = xmlOutputBufferWriteString(writer->out, "\n"); 02499 if (count < 0) 02500 return -1; 02501 sum += count; 02502 } 02503 02504 xmlListPopFront(writer->nodes); 02505 return sum; 02506 } 02507 02519 int XMLCDECL 02520 xmlTextWriterWriteFormatPI(xmlTextWriterPtr writer, const xmlChar * target, 02521 const char *format, ...) 02522 { 02523 int rc; 02524 va_list ap; 02525 02526 va_start(ap, format); 02527 02528 rc = xmlTextWriterWriteVFormatPI(writer, target, format, ap); 02529 02530 va_end(ap); 02531 return rc; 02532 } 02533 02545 int 02546 xmlTextWriterWriteVFormatPI(xmlTextWriterPtr writer, 02547 const xmlChar * target, const char *format, 02548 va_list argptr) 02549 { 02550 int rc; 02551 xmlChar *buf; 02552 02553 if (writer == NULL) 02554 return -1; 02555 02556 buf = xmlTextWriterVSprintf(format, argptr); 02557 if (buf == NULL) 02558 return -1; 02559 02560 rc = xmlTextWriterWritePI(writer, target, buf); 02561 02562 xmlFree(buf); 02563 return rc; 02564 } 02565 02576 int 02577 xmlTextWriterWritePI(xmlTextWriterPtr writer, const xmlChar * target, 02578 const xmlChar * content) 02579 { 02580 int count; 02581 int sum; 02582 02583 sum = 0; 02584 count = xmlTextWriterStartPI(writer, target); 02585 if (count == -1) 02586 return -1; 02587 sum += count; 02588 if (content != 0) { 02589 count = xmlTextWriterWriteString(writer, content); 02590 if (count == -1) 02591 return -1; 02592 sum += count; 02593 } 02594 count = xmlTextWriterEndPI(writer); 02595 if (count == -1) 02596 return -1; 02597 sum += count; 02598 02599 return sum; 02600 } 02601 02610 int 02611 xmlTextWriterStartCDATA(xmlTextWriterPtr writer) 02612 { 02613 int count; 02614 int sum; 02615 xmlLinkPtr lk; 02616 xmlTextWriterStackEntry *p; 02617 02618 if (writer == NULL) 02619 return -1; 02620 02621 sum = 0; 02622 lk = xmlListFront(writer->nodes); 02623 if (lk != 0) { 02624 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 02625 if (p != 0) { 02626 switch (p->state) { 02627 case XML_TEXTWRITER_NONE: 02628 case XML_TEXTWRITER_TEXT: 02629 case XML_TEXTWRITER_PI: 02630 case XML_TEXTWRITER_PI_TEXT: 02631 break; 02632 case XML_TEXTWRITER_ATTRIBUTE: 02633 count = xmlTextWriterEndAttribute(writer); 02634 if (count < 0) 02635 return -1; 02636 sum += count; 02637 /* fallthrough */ 02638 case XML_TEXTWRITER_NAME: 02639 /* Output namespace declarations */ 02640 count = xmlTextWriterOutputNSDecl(writer); 02641 if (count < 0) 02642 return -1; 02643 sum += count; 02644 count = xmlOutputBufferWriteString(writer->out, ">"); 02645 if (count < 0) 02646 return -1; 02647 sum += count; 02648 p->state = XML_TEXTWRITER_TEXT; 02649 break; 02650 case XML_TEXTWRITER_CDATA: 02651 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 02652 "xmlTextWriterStartCDATA : CDATA not allowed in this context!\n"); 02653 return -1; 02654 default: 02655 return -1; 02656 } 02657 } 02658 } 02659 02660 p = (xmlTextWriterStackEntry *) 02661 xmlMalloc(sizeof(xmlTextWriterStackEntry)); 02662 if (p == 0) { 02663 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 02664 "xmlTextWriterStartCDATA : out of memory!\n"); 02665 return -1; 02666 } 02667 02668 p->name = NULL; 02669 p->state = XML_TEXTWRITER_CDATA; 02670 02671 xmlListPushFront(writer->nodes, p); 02672 02673 count = xmlOutputBufferWriteString(writer->out, "<![CDATA["); 02674 if (count < 0) 02675 return -1; 02676 sum += count; 02677 02678 return sum; 02679 } 02680 02689 int 02690 xmlTextWriterEndCDATA(xmlTextWriterPtr writer) 02691 { 02692 int count; 02693 int sum; 02694 xmlLinkPtr lk; 02695 xmlTextWriterStackEntry *p; 02696 02697 if (writer == NULL) 02698 return -1; 02699 02700 lk = xmlListFront(writer->nodes); 02701 if (lk == 0) 02702 return -1; 02703 02704 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 02705 if (p == 0) 02706 return -1; 02707 02708 sum = 0; 02709 switch (p->state) { 02710 case XML_TEXTWRITER_CDATA: 02711 count = xmlOutputBufferWriteString(writer->out, "]]>"); 02712 if (count < 0) 02713 return -1; 02714 sum += count; 02715 break; 02716 default: 02717 return -1; 02718 } 02719 02720 xmlListPopFront(writer->nodes); 02721 return sum; 02722 } 02723 02734 int XMLCDECL 02735 xmlTextWriterWriteFormatCDATA(xmlTextWriterPtr writer, const char *format, 02736 ...) 02737 { 02738 int rc; 02739 va_list ap; 02740 02741 va_start(ap, format); 02742 02743 rc = xmlTextWriterWriteVFormatCDATA(writer, format, ap); 02744 02745 va_end(ap); 02746 return rc; 02747 } 02748 02759 int 02760 xmlTextWriterWriteVFormatCDATA(xmlTextWriterPtr writer, const char *format, 02761 va_list argptr) 02762 { 02763 int rc; 02764 xmlChar *buf; 02765 02766 if (writer == NULL) 02767 return -1; 02768 02769 buf = xmlTextWriterVSprintf(format, argptr); 02770 if (buf == NULL) 02771 return -1; 02772 02773 rc = xmlTextWriterWriteCDATA(writer, buf); 02774 02775 xmlFree(buf); 02776 return rc; 02777 } 02778 02788 int 02789 xmlTextWriterWriteCDATA(xmlTextWriterPtr writer, const xmlChar * content) 02790 { 02791 int count; 02792 int sum; 02793 02794 sum = 0; 02795 count = xmlTextWriterStartCDATA(writer); 02796 if (count == -1) 02797 return -1; 02798 sum += count; 02799 if (content != 0) { 02800 count = xmlTextWriterWriteString(writer, content); 02801 if (count == -1) 02802 return -1; 02803 sum += count; 02804 } 02805 count = xmlTextWriterEndCDATA(writer); 02806 if (count == -1) 02807 return -1; 02808 sum += count; 02809 02810 return sum; 02811 } 02812 02824 int 02825 xmlTextWriterStartDTD(xmlTextWriterPtr writer, 02826 const xmlChar * name, 02827 const xmlChar * pubid, const xmlChar * sysid) 02828 { 02829 int count; 02830 int sum; 02831 xmlLinkPtr lk; 02832 xmlTextWriterStackEntry *p; 02833 02834 if (writer == NULL || name == NULL || *name == '\0') 02835 return -1; 02836 02837 sum = 0; 02838 lk = xmlListFront(writer->nodes); 02839 if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) { 02840 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 02841 "xmlTextWriterStartDTD : DTD allowed only in prolog!\n"); 02842 return -1; 02843 } 02844 02845 p = (xmlTextWriterStackEntry *) 02846 xmlMalloc(sizeof(xmlTextWriterStackEntry)); 02847 if (p == 0) { 02848 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 02849 "xmlTextWriterStartDTD : out of memory!\n"); 02850 return -1; 02851 } 02852 02853 p->name = xmlStrdup(name); 02854 if (p->name == 0) { 02855 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 02856 "xmlTextWriterStartDTD : out of memory!\n"); 02857 xmlFree(p); 02858 return -1; 02859 } 02860 p->state = XML_TEXTWRITER_DTD; 02861 02862 xmlListPushFront(writer->nodes, p); 02863 02864 count = xmlOutputBufferWriteString(writer->out, "<!DOCTYPE "); 02865 if (count < 0) 02866 return -1; 02867 sum += count; 02868 count = xmlOutputBufferWriteString(writer->out, (const char *) name); 02869 if (count < 0) 02870 return -1; 02871 sum += count; 02872 02873 if (pubid != 0) { 02874 if (sysid == 0) { 02875 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 02876 "xmlTextWriterStartDTD : system identifier needed!\n"); 02877 return -1; 02878 } 02879 02880 if (writer->indent) 02881 count = xmlOutputBufferWrite(writer->out, 1, "\n"); 02882 else 02883 count = xmlOutputBufferWrite(writer->out, 1, " "); 02884 if (count < 0) 02885 return -1; 02886 sum += count; 02887 02888 count = xmlOutputBufferWriteString(writer->out, "PUBLIC "); 02889 if (count < 0) 02890 return -1; 02891 sum += count; 02892 02893 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 02894 if (count < 0) 02895 return -1; 02896 sum += count; 02897 02898 count = 02899 xmlOutputBufferWriteString(writer->out, (const char *) pubid); 02900 if (count < 0) 02901 return -1; 02902 sum += count; 02903 02904 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 02905 if (count < 0) 02906 return -1; 02907 sum += count; 02908 } 02909 02910 if (sysid != 0) { 02911 if (pubid == 0) { 02912 if (writer->indent) 02913 count = xmlOutputBufferWrite(writer->out, 1, "\n"); 02914 else 02915 count = xmlOutputBufferWrite(writer->out, 1, " "); 02916 if (count < 0) 02917 return -1; 02918 sum += count; 02919 count = xmlOutputBufferWriteString(writer->out, "SYSTEM "); 02920 if (count < 0) 02921 return -1; 02922 sum += count; 02923 } else { 02924 if (writer->indent) 02925 count = xmlOutputBufferWriteString(writer->out, "\n "); 02926 else 02927 count = xmlOutputBufferWrite(writer->out, 1, " "); 02928 if (count < 0) 02929 return -1; 02930 sum += count; 02931 } 02932 02933 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 02934 if (count < 0) 02935 return -1; 02936 sum += count; 02937 02938 count = 02939 xmlOutputBufferWriteString(writer->out, (const char *) sysid); 02940 if (count < 0) 02941 return -1; 02942 sum += count; 02943 02944 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 02945 if (count < 0) 02946 return -1; 02947 sum += count; 02948 } 02949 02950 return sum; 02951 } 02952 02961 int 02962 xmlTextWriterEndDTD(xmlTextWriterPtr writer) 02963 { 02964 int loop; 02965 int count; 02966 int sum; 02967 xmlLinkPtr lk; 02968 xmlTextWriterStackEntry *p; 02969 02970 if (writer == NULL) 02971 return -1; 02972 02973 sum = 0; 02974 loop = 1; 02975 while (loop) { 02976 lk = xmlListFront(writer->nodes); 02977 if (lk == NULL) 02978 break; 02979 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 02980 if (p == 0) 02981 break; 02982 switch (p->state) { 02983 case XML_TEXTWRITER_DTD_TEXT: 02984 count = xmlOutputBufferWriteString(writer->out, "]"); 02985 if (count < 0) 02986 return -1; 02987 sum += count; 02988 /* fallthrough */ 02989 case XML_TEXTWRITER_DTD: 02990 count = xmlOutputBufferWriteString(writer->out, ">"); 02991 02992 if (writer->indent) { 02993 if (count < 0) 02994 return -1; 02995 sum += count; 02996 count = xmlOutputBufferWriteString(writer->out, "\n"); 02997 } 02998 02999 xmlListPopFront(writer->nodes); 03000 break; 03001 case XML_TEXTWRITER_DTD_ELEM: 03002 case XML_TEXTWRITER_DTD_ELEM_TEXT: 03003 count = xmlTextWriterEndDTDElement(writer); 03004 break; 03005 case XML_TEXTWRITER_DTD_ATTL: 03006 case XML_TEXTWRITER_DTD_ATTL_TEXT: 03007 count = xmlTextWriterEndDTDAttlist(writer); 03008 break; 03009 case XML_TEXTWRITER_DTD_ENTY: 03010 case XML_TEXTWRITER_DTD_PENT: 03011 case XML_TEXTWRITER_DTD_ENTY_TEXT: 03012 count = xmlTextWriterEndDTDEntity(writer); 03013 break; 03014 case XML_TEXTWRITER_COMMENT: 03015 count = xmlTextWriterEndComment(writer); 03016 break; 03017 default: 03018 loop = 0; 03019 continue; 03020 } 03021 03022 if (count < 0) 03023 return -1; 03024 sum += count; 03025 } 03026 03027 return sum; 03028 } 03029 03043 int XMLCDECL 03044 xmlTextWriterWriteFormatDTD(xmlTextWriterPtr writer, 03045 const xmlChar * name, 03046 const xmlChar * pubid, 03047 const xmlChar * sysid, const char *format, ...) 03048 { 03049 int rc; 03050 va_list ap; 03051 03052 va_start(ap, format); 03053 03054 rc = xmlTextWriterWriteVFormatDTD(writer, name, pubid, sysid, format, 03055 ap); 03056 03057 va_end(ap); 03058 return rc; 03059 } 03060 03074 int 03075 xmlTextWriterWriteVFormatDTD(xmlTextWriterPtr writer, 03076 const xmlChar * name, 03077 const xmlChar * pubid, 03078 const xmlChar * sysid, 03079 const char *format, va_list argptr) 03080 { 03081 int rc; 03082 xmlChar *buf; 03083 03084 if (writer == NULL) 03085 return -1; 03086 03087 buf = xmlTextWriterVSprintf(format, argptr); 03088 if (buf == NULL) 03089 return -1; 03090 03091 rc = xmlTextWriterWriteDTD(writer, name, pubid, sysid, buf); 03092 03093 xmlFree(buf); 03094 return rc; 03095 } 03096 03109 int 03110 xmlTextWriterWriteDTD(xmlTextWriterPtr writer, 03111 const xmlChar * name, 03112 const xmlChar * pubid, 03113 const xmlChar * sysid, const xmlChar * subset) 03114 { 03115 int count; 03116 int sum; 03117 03118 sum = 0; 03119 count = xmlTextWriterStartDTD(writer, name, pubid, sysid); 03120 if (count == -1) 03121 return -1; 03122 sum += count; 03123 if (subset != 0) { 03124 count = xmlTextWriterWriteString(writer, subset); 03125 if (count == -1) 03126 return -1; 03127 sum += count; 03128 } 03129 count = xmlTextWriterEndDTD(writer); 03130 if (count == -1) 03131 return -1; 03132 sum += count; 03133 03134 return sum; 03135 } 03136 03146 int 03147 xmlTextWriterStartDTDElement(xmlTextWriterPtr writer, const xmlChar * name) 03148 { 03149 int count; 03150 int sum; 03151 xmlLinkPtr lk; 03152 xmlTextWriterStackEntry *p; 03153 03154 if (writer == NULL || name == NULL || *name == '\0') 03155 return -1; 03156 03157 sum = 0; 03158 lk = xmlListFront(writer->nodes); 03159 if (lk == 0) { 03160 return -1; 03161 } 03162 03163 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 03164 if (p != 0) { 03165 switch (p->state) { 03166 case XML_TEXTWRITER_DTD: 03167 count = xmlOutputBufferWriteString(writer->out, " ["); 03168 if (count < 0) 03169 return -1; 03170 sum += count; 03171 if (writer->indent) { 03172 count = xmlOutputBufferWriteString(writer->out, "\n"); 03173 if (count < 0) 03174 return -1; 03175 sum += count; 03176 } 03177 p->state = XML_TEXTWRITER_DTD_TEXT; 03178 /* fallthrough */ 03179 case XML_TEXTWRITER_DTD_TEXT: 03180 case XML_TEXTWRITER_NONE: 03181 break; 03182 default: 03183 return -1; 03184 } 03185 } 03186 03187 p = (xmlTextWriterStackEntry *) 03188 xmlMalloc(sizeof(xmlTextWriterStackEntry)); 03189 if (p == 0) { 03190 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 03191 "xmlTextWriterStartDTDElement : out of memory!\n"); 03192 return -1; 03193 } 03194 03195 p->name = xmlStrdup(name); 03196 if (p->name == 0) { 03197 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 03198 "xmlTextWriterStartDTDElement : out of memory!\n"); 03199 xmlFree(p); 03200 return -1; 03201 } 03202 p->state = XML_TEXTWRITER_DTD_ELEM; 03203 03204 xmlListPushFront(writer->nodes, p); 03205 03206 if (writer->indent) { 03207 count = xmlTextWriterWriteIndent(writer); 03208 if (count < 0) 03209 return -1; 03210 sum += count; 03211 } 03212 03213 count = xmlOutputBufferWriteString(writer->out, "<!ELEMENT "); 03214 if (count < 0) 03215 return -1; 03216 sum += count; 03217 count = xmlOutputBufferWriteString(writer->out, (const char *) name); 03218 if (count < 0) 03219 return -1; 03220 sum += count; 03221 03222 return sum; 03223 } 03224 03233 int 03234 xmlTextWriterEndDTDElement(xmlTextWriterPtr writer) 03235 { 03236 int count; 03237 int sum; 03238 xmlLinkPtr lk; 03239 xmlTextWriterStackEntry *p; 03240 03241 if (writer == NULL) 03242 return -1; 03243 03244 sum = 0; 03245 lk = xmlListFront(writer->nodes); 03246 if (lk == 0) 03247 return -1; 03248 03249 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 03250 if (p == 0) 03251 return -1; 03252 03253 switch (p->state) { 03254 case XML_TEXTWRITER_DTD_ELEM: 03255 case XML_TEXTWRITER_DTD_ELEM_TEXT: 03256 count = xmlOutputBufferWriteString(writer->out, ">"); 03257 if (count < 0) 03258 return -1; 03259 sum += count; 03260 break; 03261 default: 03262 return -1; 03263 } 03264 03265 if (writer->indent) { 03266 count = xmlOutputBufferWriteString(writer->out, "\n"); 03267 if (count < 0) 03268 return -1; 03269 sum += count; 03270 } 03271 03272 xmlListPopFront(writer->nodes); 03273 return sum; 03274 } 03275 03287 int XMLCDECL 03288 xmlTextWriterWriteFormatDTDElement(xmlTextWriterPtr writer, 03289 const xmlChar * name, 03290 const char *format, ...) 03291 { 03292 int rc; 03293 va_list ap; 03294 03295 va_start(ap, format); 03296 03297 rc = xmlTextWriterWriteVFormatDTDElement(writer, name, format, ap); 03298 03299 va_end(ap); 03300 return rc; 03301 } 03302 03314 int 03315 xmlTextWriterWriteVFormatDTDElement(xmlTextWriterPtr writer, 03316 const xmlChar * name, 03317 const char *format, va_list argptr) 03318 { 03319 int rc; 03320 xmlChar *buf; 03321 03322 if (writer == NULL) 03323 return -1; 03324 03325 buf = xmlTextWriterVSprintf(format, argptr); 03326 if (buf == NULL) 03327 return -1; 03328 03329 rc = xmlTextWriterWriteDTDElement(writer, name, buf); 03330 03331 xmlFree(buf); 03332 return rc; 03333 } 03334 03345 int 03346 xmlTextWriterWriteDTDElement(xmlTextWriterPtr writer, 03347 const xmlChar * name, const xmlChar * content) 03348 { 03349 int count; 03350 int sum; 03351 03352 if (content == NULL) 03353 return -1; 03354 03355 sum = 0; 03356 count = xmlTextWriterStartDTDElement(writer, name); 03357 if (count == -1) 03358 return -1; 03359 sum += count; 03360 03361 count = xmlTextWriterWriteString(writer, content); 03362 if (count == -1) 03363 return -1; 03364 sum += count; 03365 03366 count = xmlTextWriterEndDTDElement(writer); 03367 if (count == -1) 03368 return -1; 03369 sum += count; 03370 03371 return sum; 03372 } 03373 03383 int 03384 xmlTextWriterStartDTDAttlist(xmlTextWriterPtr writer, const xmlChar * name) 03385 { 03386 int count; 03387 int sum; 03388 xmlLinkPtr lk; 03389 xmlTextWriterStackEntry *p; 03390 03391 if (writer == NULL || name == NULL || *name == '\0') 03392 return -1; 03393 03394 sum = 0; 03395 lk = xmlListFront(writer->nodes); 03396 if (lk == 0) { 03397 return -1; 03398 } 03399 03400 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 03401 if (p != 0) { 03402 switch (p->state) { 03403 case XML_TEXTWRITER_DTD: 03404 count = xmlOutputBufferWriteString(writer->out, " ["); 03405 if (count < 0) 03406 return -1; 03407 sum += count; 03408 if (writer->indent) { 03409 count = xmlOutputBufferWriteString(writer->out, "\n"); 03410 if (count < 0) 03411 return -1; 03412 sum += count; 03413 } 03414 p->state = XML_TEXTWRITER_DTD_TEXT; 03415 /* fallthrough */ 03416 case XML_TEXTWRITER_DTD_TEXT: 03417 case XML_TEXTWRITER_NONE: 03418 break; 03419 default: 03420 return -1; 03421 } 03422 } 03423 03424 p = (xmlTextWriterStackEntry *) 03425 xmlMalloc(sizeof(xmlTextWriterStackEntry)); 03426 if (p == 0) { 03427 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 03428 "xmlTextWriterStartDTDAttlist : out of memory!\n"); 03429 return -1; 03430 } 03431 03432 p->name = xmlStrdup(name); 03433 if (p->name == 0) { 03434 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 03435 "xmlTextWriterStartDTDAttlist : out of memory!\n"); 03436 xmlFree(p); 03437 return -1; 03438 } 03439 p->state = XML_TEXTWRITER_DTD_ATTL; 03440 03441 xmlListPushFront(writer->nodes, p); 03442 03443 if (writer->indent) { 03444 count = xmlTextWriterWriteIndent(writer); 03445 if (count < 0) 03446 return -1; 03447 sum += count; 03448 } 03449 03450 count = xmlOutputBufferWriteString(writer->out, "<!ATTLIST "); 03451 if (count < 0) 03452 return -1; 03453 sum += count; 03454 count = xmlOutputBufferWriteString(writer->out, (const char *) name); 03455 if (count < 0) 03456 return -1; 03457 sum += count; 03458 03459 return sum; 03460 } 03461 03470 int 03471 xmlTextWriterEndDTDAttlist(xmlTextWriterPtr writer) 03472 { 03473 int count; 03474 int sum; 03475 xmlLinkPtr lk; 03476 xmlTextWriterStackEntry *p; 03477 03478 if (writer == NULL) 03479 return -1; 03480 03481 sum = 0; 03482 lk = xmlListFront(writer->nodes); 03483 if (lk == 0) 03484 return -1; 03485 03486 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 03487 if (p == 0) 03488 return -1; 03489 03490 switch (p->state) { 03491 case XML_TEXTWRITER_DTD_ATTL: 03492 case XML_TEXTWRITER_DTD_ATTL_TEXT: 03493 count = xmlOutputBufferWriteString(writer->out, ">"); 03494 if (count < 0) 03495 return -1; 03496 sum += count; 03497 break; 03498 default: 03499 return -1; 03500 } 03501 03502 if (writer->indent) { 03503 count = xmlOutputBufferWriteString(writer->out, "\n"); 03504 if (count < 0) 03505 return -1; 03506 sum += count; 03507 } 03508 03509 xmlListPopFront(writer->nodes); 03510 return sum; 03511 } 03512 03524 int XMLCDECL 03525 xmlTextWriterWriteFormatDTDAttlist(xmlTextWriterPtr writer, 03526 const xmlChar * name, 03527 const char *format, ...) 03528 { 03529 int rc; 03530 va_list ap; 03531 03532 va_start(ap, format); 03533 03534 rc = xmlTextWriterWriteVFormatDTDAttlist(writer, name, format, ap); 03535 03536 va_end(ap); 03537 return rc; 03538 } 03539 03551 int 03552 xmlTextWriterWriteVFormatDTDAttlist(xmlTextWriterPtr writer, 03553 const xmlChar * name, 03554 const char *format, va_list argptr) 03555 { 03556 int rc; 03557 xmlChar *buf; 03558 03559 if (writer == NULL) 03560 return -1; 03561 03562 buf = xmlTextWriterVSprintf(format, argptr); 03563 if (buf == NULL) 03564 return -1; 03565 03566 rc = xmlTextWriterWriteDTDAttlist(writer, name, buf); 03567 03568 xmlFree(buf); 03569 return rc; 03570 } 03571 03582 int 03583 xmlTextWriterWriteDTDAttlist(xmlTextWriterPtr writer, 03584 const xmlChar * name, const xmlChar * content) 03585 { 03586 int count; 03587 int sum; 03588 03589 if (content == NULL) 03590 return -1; 03591 03592 sum = 0; 03593 count = xmlTextWriterStartDTDAttlist(writer, name); 03594 if (count == -1) 03595 return -1; 03596 sum += count; 03597 03598 count = xmlTextWriterWriteString(writer, content); 03599 if (count == -1) 03600 return -1; 03601 sum += count; 03602 03603 count = xmlTextWriterEndDTDAttlist(writer); 03604 if (count == -1) 03605 return -1; 03606 sum += count; 03607 03608 return sum; 03609 } 03610 03621 int 03622 xmlTextWriterStartDTDEntity(xmlTextWriterPtr writer, 03623 int pe, const xmlChar * name) 03624 { 03625 int count; 03626 int sum; 03627 xmlLinkPtr lk; 03628 xmlTextWriterStackEntry *p; 03629 03630 if (writer == NULL || name == NULL || *name == '\0') 03631 return -1; 03632 03633 sum = 0; 03634 lk = xmlListFront(writer->nodes); 03635 if (lk != 0) { 03636 03637 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 03638 if (p != 0) { 03639 switch (p->state) { 03640 case XML_TEXTWRITER_DTD: 03641 count = xmlOutputBufferWriteString(writer->out, " ["); 03642 if (count < 0) 03643 return -1; 03644 sum += count; 03645 if (writer->indent) { 03646 count = 03647 xmlOutputBufferWriteString(writer->out, "\n"); 03648 if (count < 0) 03649 return -1; 03650 sum += count; 03651 } 03652 p->state = XML_TEXTWRITER_DTD_TEXT; 03653 /* fallthrough */ 03654 case XML_TEXTWRITER_DTD_TEXT: 03655 case XML_TEXTWRITER_NONE: 03656 break; 03657 default: 03658 return -1; 03659 } 03660 } 03661 } 03662 03663 p = (xmlTextWriterStackEntry *) 03664 xmlMalloc(sizeof(xmlTextWriterStackEntry)); 03665 if (p == 0) { 03666 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 03667 "xmlTextWriterStartDTDElement : out of memory!\n"); 03668 return -1; 03669 } 03670 03671 p->name = xmlStrdup(name); 03672 if (p->name == 0) { 03673 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 03674 "xmlTextWriterStartDTDElement : out of memory!\n"); 03675 xmlFree(p); 03676 return -1; 03677 } 03678 03679 if (pe != 0) 03680 p->state = XML_TEXTWRITER_DTD_PENT; 03681 else 03682 p->state = XML_TEXTWRITER_DTD_ENTY; 03683 03684 xmlListPushFront(writer->nodes, p); 03685 03686 if (writer->indent) { 03687 count = xmlTextWriterWriteIndent(writer); 03688 if (count < 0) 03689 return -1; 03690 sum += count; 03691 } 03692 03693 count = xmlOutputBufferWriteString(writer->out, "<!ENTITY "); 03694 if (count < 0) 03695 return -1; 03696 sum += count; 03697 03698 if (pe != 0) { 03699 count = xmlOutputBufferWriteString(writer->out, "% "); 03700 if (count < 0) 03701 return -1; 03702 sum += count; 03703 } 03704 03705 count = xmlOutputBufferWriteString(writer->out, (const char *) name); 03706 if (count < 0) 03707 return -1; 03708 sum += count; 03709 03710 return sum; 03711 } 03712 03721 int 03722 xmlTextWriterEndDTDEntity(xmlTextWriterPtr writer) 03723 { 03724 int count; 03725 int sum; 03726 xmlLinkPtr lk; 03727 xmlTextWriterStackEntry *p; 03728 03729 if (writer == NULL) 03730 return -1; 03731 03732 sum = 0; 03733 lk = xmlListFront(writer->nodes); 03734 if (lk == 0) 03735 return -1; 03736 03737 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 03738 if (p == 0) 03739 return -1; 03740 03741 switch (p->state) { 03742 case XML_TEXTWRITER_DTD_ENTY_TEXT: 03743 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 03744 if (count < 0) 03745 return -1; 03746 sum += count; 03747 case XML_TEXTWRITER_DTD_ENTY: 03748 case XML_TEXTWRITER_DTD_PENT: 03749 count = xmlOutputBufferWriteString(writer->out, ">"); 03750 if (count < 0) 03751 return -1; 03752 sum += count; 03753 break; 03754 default: 03755 return -1; 03756 } 03757 03758 if (writer->indent) { 03759 count = xmlOutputBufferWriteString(writer->out, "\n"); 03760 if (count < 0) 03761 return -1; 03762 sum += count; 03763 } 03764 03765 xmlListPopFront(writer->nodes); 03766 return sum; 03767 } 03768 03781 int XMLCDECL 03782 xmlTextWriterWriteFormatDTDInternalEntity(xmlTextWriterPtr writer, 03783 int pe, 03784 const xmlChar * name, 03785 const char *format, ...) 03786 { 03787 int rc; 03788 va_list ap; 03789 03790 va_start(ap, format); 03791 03792 rc = xmlTextWriterWriteVFormatDTDInternalEntity(writer, pe, name, 03793 format, ap); 03794 03795 va_end(ap); 03796 return rc; 03797 } 03798 03811 int 03812 xmlTextWriterWriteVFormatDTDInternalEntity(xmlTextWriterPtr writer, 03813 int pe, 03814 const xmlChar * name, 03815 const char *format, 03816 va_list argptr) 03817 { 03818 int rc; 03819 xmlChar *buf; 03820 03821 if (writer == NULL) 03822 return -1; 03823 03824 buf = xmlTextWriterVSprintf(format, argptr); 03825 if (buf == NULL) 03826 return -1; 03827 03828 rc = xmlTextWriterWriteDTDInternalEntity(writer, pe, name, buf); 03829 03830 xmlFree(buf); 03831 return rc; 03832 } 03833 03848 int 03849 xmlTextWriterWriteDTDEntity(xmlTextWriterPtr writer, 03850 int pe, 03851 const xmlChar * name, 03852 const xmlChar * pubid, 03853 const xmlChar * sysid, 03854 const xmlChar * ndataid, 03855 const xmlChar * content) 03856 { 03857 if ((content == NULL) && (pubid == NULL) && (sysid == NULL)) 03858 return -1; 03859 if ((pe != 0) && (ndataid != NULL)) 03860 return -1; 03861 03862 if ((pubid == NULL) && (sysid == NULL)) 03863 return xmlTextWriterWriteDTDInternalEntity(writer, pe, name, 03864 content); 03865 03866 return xmlTextWriterWriteDTDExternalEntity(writer, pe, name, pubid, 03867 sysid, ndataid); 03868 } 03869 03881 int 03882 xmlTextWriterWriteDTDInternalEntity(xmlTextWriterPtr writer, 03883 int pe, 03884 const xmlChar * name, 03885 const xmlChar * content) 03886 { 03887 int count; 03888 int sum; 03889 03890 if ((name == NULL) || (*name == '\0') || (content == NULL)) 03891 return -1; 03892 03893 sum = 0; 03894 count = xmlTextWriterStartDTDEntity(writer, pe, name); 03895 if (count == -1) 03896 return -1; 03897 sum += count; 03898 03899 count = xmlTextWriterWriteString(writer, content); 03900 if (count == -1) 03901 return -1; 03902 sum += count; 03903 03904 count = xmlTextWriterEndDTDEntity(writer); 03905 if (count == -1) 03906 return -1; 03907 sum += count; 03908 03909 return sum; 03910 } 03911 03925 int 03926 xmlTextWriterWriteDTDExternalEntity(xmlTextWriterPtr writer, 03927 int pe, 03928 const xmlChar * name, 03929 const xmlChar * pubid, 03930 const xmlChar * sysid, 03931 const xmlChar * ndataid) 03932 { 03933 int count; 03934 int sum; 03935 03936 if (((pubid == NULL) && (sysid == NULL))) 03937 return -1; 03938 if ((pe != 0) && (ndataid != NULL)) 03939 return -1; 03940 03941 sum = 0; 03942 count = xmlTextWriterStartDTDEntity(writer, pe, name); 03943 if (count == -1) 03944 return -1; 03945 sum += count; 03946 03947 count = 03948 xmlTextWriterWriteDTDExternalEntityContents(writer, pubid, sysid, 03949 ndataid); 03950 if (count < 0) 03951 return -1; 03952 sum += count; 03953 03954 count = xmlTextWriterEndDTDEntity(writer); 03955 if (count == -1) 03956 return -1; 03957 sum += count; 03958 03959 return sum; 03960 } 03961 03973 int 03974 xmlTextWriterWriteDTDExternalEntityContents(xmlTextWriterPtr writer, 03975 const xmlChar * pubid, 03976 const xmlChar * sysid, 03977 const xmlChar * ndataid) 03978 { 03979 int count; 03980 int sum; 03981 xmlLinkPtr lk; 03982 xmlTextWriterStackEntry *p; 03983 03984 if (writer == NULL) { 03985 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 03986 "xmlTextWriterWriteDTDExternalEntityContents: xmlTextWriterPtr invalid!\n"); 03987 return -1; 03988 } 03989 03990 sum = 0; 03991 lk = xmlListFront(writer->nodes); 03992 if (lk == 0) { 03993 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 03994 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n"); 03995 return -1; 03996 } 03997 03998 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 03999 if (p == 0) 04000 return -1; 04001 04002 switch (p->state) { 04003 case XML_TEXTWRITER_DTD_ENTY: 04004 break; 04005 case XML_TEXTWRITER_DTD_PENT: 04006 if (ndataid != NULL) { 04007 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 04008 "xmlTextWriterWriteDTDExternalEntityContents: notation not allowed with parameter entities!\n"); 04009 return -1; 04010 } 04011 break; 04012 default: 04013 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 04014 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n"); 04015 return -1; 04016 } 04017 04018 if (pubid != 0) { 04019 if (sysid == 0) { 04020 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 04021 "xmlTextWriterWriteDTDExternalEntityContents: system identifier needed!\n"); 04022 return -1; 04023 } 04024 04025 count = xmlOutputBufferWriteString(writer->out, " PUBLIC "); 04026 if (count < 0) 04027 return -1; 04028 sum += count; 04029 04030 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 04031 if (count < 0) 04032 return -1; 04033 sum += count; 04034 04035 count = 04036 xmlOutputBufferWriteString(writer->out, (const char *) pubid); 04037 if (count < 0) 04038 return -1; 04039 sum += count; 04040 04041 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 04042 if (count < 0) 04043 return -1; 04044 sum += count; 04045 } 04046 04047 if (sysid != 0) { 04048 if (pubid == 0) { 04049 count = xmlOutputBufferWriteString(writer->out, " SYSTEM"); 04050 if (count < 0) 04051 return -1; 04052 sum += count; 04053 } 04054 04055 count = xmlOutputBufferWriteString(writer->out, " "); 04056 if (count < 0) 04057 return -1; 04058 sum += count; 04059 04060 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 04061 if (count < 0) 04062 return -1; 04063 sum += count; 04064 04065 count = 04066 xmlOutputBufferWriteString(writer->out, (const char *) sysid); 04067 if (count < 0) 04068 return -1; 04069 sum += count; 04070 04071 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 04072 if (count < 0) 04073 return -1; 04074 sum += count; 04075 } 04076 04077 if (ndataid != NULL) { 04078 count = xmlOutputBufferWriteString(writer->out, " NDATA "); 04079 if (count < 0) 04080 return -1; 04081 sum += count; 04082 04083 count = 04084 xmlOutputBufferWriteString(writer->out, 04085 (const char *) ndataid); 04086 if (count < 0) 04087 return -1; 04088 sum += count; 04089 } 04090 04091 return sum; 04092 } 04093 04105 int 04106 xmlTextWriterWriteDTDNotation(xmlTextWriterPtr writer, 04107 const xmlChar * name, 04108 const xmlChar * pubid, const xmlChar * sysid) 04109 { 04110 int count; 04111 int sum; 04112 xmlLinkPtr lk; 04113 xmlTextWriterStackEntry *p; 04114 04115 if (writer == NULL || name == NULL || *name == '\0') 04116 return -1; 04117 04118 sum = 0; 04119 lk = xmlListFront(writer->nodes); 04120 if (lk == 0) { 04121 return -1; 04122 } 04123 04124 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 04125 if (p != 0) { 04126 switch (p->state) { 04127 case XML_TEXTWRITER_DTD: 04128 count = xmlOutputBufferWriteString(writer->out, " ["); 04129 if (count < 0) 04130 return -1; 04131 sum += count; 04132 if (writer->indent) { 04133 count = xmlOutputBufferWriteString(writer->out, "\n"); 04134 if (count < 0) 04135 return -1; 04136 sum += count; 04137 } 04138 p->state = XML_TEXTWRITER_DTD_TEXT; 04139 /* fallthrough */ 04140 case XML_TEXTWRITER_DTD_TEXT: 04141 break; 04142 default: 04143 return -1; 04144 } 04145 } 04146 04147 if (writer->indent) { 04148 count = xmlTextWriterWriteIndent(writer); 04149 if (count < 0) 04150 return -1; 04151 sum += count; 04152 } 04153 04154 count = xmlOutputBufferWriteString(writer->out, "<!NOTATION "); 04155 if (count < 0) 04156 return -1; 04157 sum += count; 04158 count = xmlOutputBufferWriteString(writer->out, (const char *) name); 04159 if (count < 0) 04160 return -1; 04161 sum += count; 04162 04163 if (pubid != 0) { 04164 count = xmlOutputBufferWriteString(writer->out, " PUBLIC "); 04165 if (count < 0) 04166 return -1; 04167 sum += count; 04168 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 04169 if (count < 0) 04170 return -1; 04171 sum += count; 04172 count = 04173 xmlOutputBufferWriteString(writer->out, (const char *) pubid); 04174 if (count < 0) 04175 return -1; 04176 sum += count; 04177 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 04178 if (count < 0) 04179 return -1; 04180 sum += count; 04181 } 04182 04183 if (sysid != 0) { 04184 if (pubid == 0) { 04185 count = xmlOutputBufferWriteString(writer->out, " SYSTEM"); 04186 if (count < 0) 04187 return -1; 04188 sum += count; 04189 } 04190 count = xmlOutputBufferWriteString(writer->out, " "); 04191 if (count < 0) 04192 return -1; 04193 sum += count; 04194 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 04195 if (count < 0) 04196 return -1; 04197 sum += count; 04198 count = 04199 xmlOutputBufferWriteString(writer->out, (const char *) sysid); 04200 if (count < 0) 04201 return -1; 04202 sum += count; 04203 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 04204 if (count < 0) 04205 return -1; 04206 sum += count; 04207 } 04208 04209 count = xmlOutputBufferWriteString(writer->out, ">"); 04210 if (count < 0) 04211 return -1; 04212 sum += count; 04213 04214 return sum; 04215 } 04216 04225 int 04226 xmlTextWriterFlush(xmlTextWriterPtr writer) 04227 { 04228 int count; 04229 04230 if (writer == NULL) 04231 return -1; 04232 04233 if (writer->out == NULL) 04234 count = 0; 04235 else 04236 count = xmlOutputBufferFlush(writer->out); 04237 04238 return count; 04239 } 04240 04251 static void 04252 xmlFreeTextWriterStackEntry(xmlLinkPtr lk) 04253 { 04254 xmlTextWriterStackEntry *p; 04255 04256 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 04257 if (p == 0) 04258 return; 04259 04260 if (p->name != 0) 04261 xmlFree(p->name); 04262 xmlFree(p); 04263 } 04264 04274 static int 04275 xmlCmpTextWriterStackEntry(const void *data0, const void *data1) 04276 { 04277 xmlTextWriterStackEntry *p0; 04278 xmlTextWriterStackEntry *p1; 04279 04280 if (data0 == data1) 04281 return 0; 04282 04283 if (data0 == 0) 04284 return -1; 04285 04286 if (data1 == 0) 04287 return 1; 04288 04289 p0 = (xmlTextWriterStackEntry *) data0; 04290 p1 = (xmlTextWriterStackEntry *) data1; 04291 04292 return xmlStrcmp(p0->name, p1->name); 04293 } 04294 04305 static int 04306 xmlTextWriterOutputNSDecl(xmlTextWriterPtr writer) 04307 { 04308 xmlLinkPtr lk; 04309 xmlTextWriterNsStackEntry *np; 04310 int count; 04311 int sum; 04312 04313 sum = 0; 04314 while (!xmlListEmpty(writer->nsstack)) { 04315 xmlChar *namespaceURI = NULL; 04316 xmlChar *prefix = NULL; 04317 04318 lk = xmlListFront(writer->nsstack); 04319 np = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk); 04320 04321 if (np != 0) { 04322 namespaceURI = xmlStrdup(np->uri); 04323 prefix = xmlStrdup(np->prefix); 04324 } 04325 04326 xmlListPopFront(writer->nsstack); 04327 04328 if (np != 0) { 04329 count = xmlTextWriterWriteAttribute(writer, prefix, namespaceURI); 04330 xmlFree(namespaceURI); 04331 xmlFree(prefix); 04332 04333 if (count < 0) { 04334 xmlListDelete(writer->nsstack); 04335 writer->nsstack = NULL; 04336 return -1; 04337 } 04338 sum += count; 04339 } 04340 } 04341 return sum; 04342 } 04343 04350 static void 04351 xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk) 04352 { 04353 xmlTextWriterNsStackEntry *p; 04354 04355 p = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk); 04356 if (p == 0) 04357 return; 04358 04359 if (p->prefix != 0) 04360 xmlFree(p->prefix); 04361 if (p->uri != 0) 04362 xmlFree(p->uri); 04363 04364 xmlFree(p); 04365 } 04366 04376 static int 04377 xmlCmpTextWriterNsStackEntry(const void *data0, const void *data1) 04378 { 04379 xmlTextWriterNsStackEntry *p0; 04380 xmlTextWriterNsStackEntry *p1; 04381 int rc; 04382 04383 if (data0 == data1) 04384 return 0; 04385 04386 if (data0 == 0) 04387 return -1; 04388 04389 if (data1 == 0) 04390 return 1; 04391 04392 p0 = (xmlTextWriterNsStackEntry *) data0; 04393 p1 = (xmlTextWriterNsStackEntry *) data1; 04394 04395 rc = xmlStrcmp(p0->prefix, p1->prefix); 04396 04397 if ((rc != 0) || (p0->elem != p1->elem)) 04398 rc = -1; 04399 04400 return rc; 04401 } 04402 04413 static int 04414 xmlTextWriterWriteDocCallback(void *context, const xmlChar * str, int len) 04415 { 04416 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context; 04417 int rc; 04418 04419 if ((rc = xmlParseChunk(ctxt, (const char *) str, len, 0)) != 0) { 04420 xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR, 04421 "xmlTextWriterWriteDocCallback : XML error %d !\n", 04422 rc); 04423 return -1; 04424 } 04425 04426 return len; 04427 } 04428 04437 static int 04438 xmlTextWriterCloseDocCallback(void *context) 04439 { 04440 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context; 04441 int rc; 04442 04443 if ((rc = xmlParseChunk(ctxt, NULL, 0, 1)) != 0) { 04444 xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR, 04445 "xmlTextWriterWriteDocCallback : XML error %d !\n", 04446 rc); 04447 return -1; 04448 } 04449 04450 return 0; 04451 } 04452 04462 static xmlChar * 04463 xmlTextWriterVSprintf(const char *format, va_list argptr) 04464 { 04465 int size; 04466 int count; 04467 xmlChar *buf; 04468 va_list locarg; 04469 04470 size = BUFSIZ; 04471 buf = (xmlChar *) xmlMalloc(size); 04472 if (buf == NULL) { 04473 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY, 04474 "xmlTextWriterVSprintf : out of memory!\n"); 04475 return NULL; 04476 } 04477 04478 VA_COPY(locarg, argptr); 04479 while (((count = vsnprintf((char *) buf, size, format, locarg)) < 0) 04480 || (count == size - 1) || (count == size) || (count > size)) { 04481 va_end(locarg); 04482 xmlFree(buf); 04483 size += BUFSIZ; 04484 buf = (xmlChar *) xmlMalloc(size); 04485 if (buf == NULL) { 04486 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY, 04487 "xmlTextWriterVSprintf : out of memory!\n"); 04488 return NULL; 04489 } 04490 VA_COPY(locarg, argptr); 04491 } 04492 va_end(locarg); 04493 04494 return buf; 04495 } 04496 04503 static void 04504 xmlTextWriterStartDocumentCallback(void *ctx) 04505 { 04506 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 04507 xmlDocPtr doc; 04508 04509 if (ctxt->html) { 04510 #ifdef LIBXML_HTML_ENABLED 04511 if (ctxt->myDoc == NULL) 04512 ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL); 04513 if (ctxt->myDoc == NULL) { 04514 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 04515 ctxt->sax->error(ctxt->userData, 04516 "SAX.startDocument(): out of memory\n"); 04517 ctxt->errNo = XML_ERR_NO_MEMORY; 04518 ctxt->instate = XML_PARSER_EOF; 04519 ctxt->disableSAX = 1; 04520 return; 04521 } 04522 #else 04523 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR, 04524 "libxml2 built without HTML support\n"); 04525 ctxt->errNo = XML_ERR_INTERNAL_ERROR; 04526 ctxt->instate = XML_PARSER_EOF; 04527 ctxt->disableSAX = 1; 04528 return; 04529 #endif 04530 } else { 04531 doc = ctxt->myDoc; 04532 if (doc == NULL) 04533 doc = ctxt->myDoc = xmlNewDoc(ctxt->version); 04534 if (doc != NULL) { 04535 if (doc->children == NULL) { 04536 if (ctxt->encoding != NULL) 04537 doc->encoding = xmlStrdup(ctxt->encoding); 04538 else 04539 doc->encoding = NULL; 04540 doc->standalone = ctxt->standalone; 04541 } 04542 } else { 04543 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 04544 ctxt->sax->error(ctxt->userData, 04545 "SAX.startDocument(): out of memory\n"); 04546 ctxt->errNo = XML_ERR_NO_MEMORY; 04547 ctxt->instate = XML_PARSER_EOF; 04548 ctxt->disableSAX = 1; 04549 return; 04550 } 04551 } 04552 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) && 04553 (ctxt->input != NULL) && (ctxt->input->filename != NULL)) { 04554 ctxt->myDoc->URL = 04555 xmlCanonicPath((const xmlChar *) ctxt->input->filename); 04556 if (ctxt->myDoc->URL == NULL) 04557 ctxt->myDoc->URL = 04558 xmlStrdup((const xmlChar *) ctxt->input->filename); 04559 } 04560 } 04561 04571 int 04572 xmlTextWriterSetIndent(xmlTextWriterPtr writer, int indent) 04573 { 04574 if ((writer == NULL) || (indent < 0)) 04575 return -1; 04576 04577 writer->indent = indent; 04578 writer->doindent = 1; 04579 04580 return 0; 04581 } 04582 04592 int 04593 xmlTextWriterSetIndentString(xmlTextWriterPtr writer, const xmlChar * str) 04594 { 04595 if ((writer == NULL) || (!str)) 04596 return -1; 04597 04598 if (writer->ichar != NULL) 04599 xmlFree(writer->ichar); 04600 writer->ichar = xmlStrdup(str); 04601 04602 if (!writer->ichar) 04603 return -1; 04604 else 04605 return 0; 04606 } 04607 04616 static int 04617 xmlTextWriterWriteIndent(xmlTextWriterPtr writer) 04618 { 04619 int lksize; 04620 int i; 04621 int ret; 04622 04623 lksize = xmlListSize(writer->nodes); 04624 if (lksize < 1) 04625 return (-1); /* list is empty */ 04626 for (i = 0; i < (lksize - 1); i++) { 04627 ret = xmlOutputBufferWriteString(writer->out, 04628 (const char *) writer->ichar); 04629 if (ret == -1) 04630 return (-1); 04631 } 04632 04633 return (lksize - 1); 04634 } 04635 04645 static int 04646 xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer, 04647 xmlTextWriterStackEntry * p) 04648 { 04649 int count; 04650 int sum; 04651 char extra[3]; 04652 04653 if (writer == NULL) 04654 return -1; 04655 04656 if (p == NULL) 04657 return 0; 04658 04659 sum = 0; 04660 extra[0] = extra[1] = extra[2] = '\0'; 04661 if (p != 0) { 04662 sum = 0; 04663 switch (p->state) { 04664 case XML_TEXTWRITER_NAME: 04665 /* Output namespace declarations */ 04666 count = xmlTextWriterOutputNSDecl(writer); 04667 if (count < 0) 04668 return -1; 04669 sum += count; 04670 extra[0] = '>'; 04671 p->state = XML_TEXTWRITER_TEXT; 04672 break; 04673 case XML_TEXTWRITER_PI: 04674 extra[0] = ' '; 04675 p->state = XML_TEXTWRITER_PI_TEXT; 04676 break; 04677 case XML_TEXTWRITER_DTD: 04678 extra[0] = ' '; 04679 extra[1] = '['; 04680 p->state = XML_TEXTWRITER_DTD_TEXT; 04681 break; 04682 case XML_TEXTWRITER_DTD_ELEM: 04683 extra[0] = ' '; 04684 p->state = XML_TEXTWRITER_DTD_ELEM_TEXT; 04685 break; 04686 case XML_TEXTWRITER_DTD_ATTL: 04687 extra[0] = ' '; 04688 p->state = XML_TEXTWRITER_DTD_ATTL_TEXT; 04689 break; 04690 case XML_TEXTWRITER_DTD_ENTY: 04691 case XML_TEXTWRITER_DTD_PENT: 04692 extra[0] = ' '; 04693 extra[1] = writer->qchar; 04694 p->state = XML_TEXTWRITER_DTD_ENTY_TEXT; 04695 break; 04696 default: 04697 break; 04698 } 04699 } 04700 04701 if (*extra != '\0') { 04702 count = xmlOutputBufferWriteString(writer->out, extra); 04703 if (count < 0) 04704 return -1; 04705 sum += count; 04706 } 04707 04708 return sum; 04709 } 04710 04711 #define bottom_xmlwriter 04712 #include "elfgcchack.h" 04713 #endif Generated on Sun May 27 2012 04:35:04 for ReactOS by
1.7.6.1
|