1 2 /* 3 * xmlwriter.c: XML text writer implementation 4 * 5 * For license and disclaimer see the license and disclaimer of 6 * libxml2. 7 * 8 * alfred (at) mickautsch.de 9 */ 10 11 #define IN_LIBXML 12 #include "libxml.h" 13 #include <string.h> 14 15 #include <libxml/xmlmemory.h> 16 #include <libxml/parser.h> 17 #include <libxml/uri.h> 18 #include <libxml/HTMLtree.h> 19 20 #ifdef LIBXML_WRITER_ENABLED 21 22 #include <libxml/xmlwriter.h> 23 24 #include "buf.h" 25 #include "enc.h" 26 #include "save.h" 27 28 #define B64LINELEN 72 29 #define B64CRLF "\r\n" 30 31 /* 32 * The following VA_COPY was coded following an example in 33 * the Samba project. It may not be sufficient for some 34 * esoteric implementations of va_list but (hopefully) will 35 * be sufficient for libxml2. 36 */ 37 #ifndef VA_COPY 38 #ifdef HAVE_VA_COPY 39 #define VA_COPY(dest, src) va_copy(dest, src) 40 #else 41 #ifdef HAVE___VA_COPY 42 #define VA_COPY(dest,src) __va_copy(dest, src) 43 #else 44 #ifndef VA_LIST_IS_ARRAY 45 #define VA_COPY(dest,src) (dest) = (src) 46 #else 47 #include <string.h> 48 #define VA_COPY(dest,src) memcpy((char *)(dest),(char *)(src),sizeof(va_list)) 49 #endif 50 #endif 51 #endif 52 #endif 53 54 /* 55 * Types are kept private 56 */ 57 typedef enum { 58 XML_TEXTWRITER_NONE = 0, 59 XML_TEXTWRITER_NAME, 60 XML_TEXTWRITER_ATTRIBUTE, 61 XML_TEXTWRITER_TEXT, 62 XML_TEXTWRITER_PI, 63 XML_TEXTWRITER_PI_TEXT, 64 XML_TEXTWRITER_CDATA, 65 XML_TEXTWRITER_DTD, 66 XML_TEXTWRITER_DTD_TEXT, 67 XML_TEXTWRITER_DTD_ELEM, 68 XML_TEXTWRITER_DTD_ELEM_TEXT, 69 XML_TEXTWRITER_DTD_ATTL, 70 XML_TEXTWRITER_DTD_ATTL_TEXT, 71 XML_TEXTWRITER_DTD_ENTY, /* entity */ 72 XML_TEXTWRITER_DTD_ENTY_TEXT, 73 XML_TEXTWRITER_DTD_PENT, /* parameter entity */ 74 XML_TEXTWRITER_COMMENT 75 } xmlTextWriterState; 76 77 typedef struct _xmlTextWriterStackEntry xmlTextWriterStackEntry; 78 79 struct _xmlTextWriterStackEntry { 80 xmlChar *name; 81 xmlTextWriterState state; 82 }; 83 84 typedef struct _xmlTextWriterNsStackEntry xmlTextWriterNsStackEntry; 85 struct _xmlTextWriterNsStackEntry { 86 xmlChar *prefix; 87 xmlChar *uri; 88 xmlLinkPtr elem; 89 }; 90 91 struct _xmlTextWriter { 92 xmlOutputBufferPtr out; /* output buffer */ 93 xmlListPtr nodes; /* element name stack */ 94 xmlListPtr nsstack; /* name spaces stack */ 95 int level; 96 int indent; /* enable indent */ 97 int doindent; /* internal indent flag */ 98 xmlChar *ichar; /* indent character */ 99 char qchar; /* character used for quoting attribute values */ 100 xmlParserCtxtPtr ctxt; 101 int no_doc_free; 102 xmlDocPtr doc; 103 }; 104 105 static void xmlFreeTextWriterStackEntry(xmlLinkPtr lk); 106 static int xmlCmpTextWriterStackEntry(const void *data0, 107 const void *data1); 108 static int xmlTextWriterOutputNSDecl(xmlTextWriterPtr writer); 109 static void xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk); 110 static int xmlCmpTextWriterNsStackEntry(const void *data0, 111 const void *data1); 112 static int xmlTextWriterWriteDocCallback(void *context, 113 const xmlChar * str, int len); 114 static int xmlTextWriterCloseDocCallback(void *context); 115 116 static xmlChar *xmlTextWriterVSprintf(const char *format, va_list argptr) LIBXML_ATTR_FORMAT(1,0); 117 static int xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len, 118 const unsigned char *data); 119 static void xmlTextWriterStartDocumentCallback(void *ctx); 120 static int xmlTextWriterWriteIndent(xmlTextWriterPtr writer); 121 static int 122 xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer, 123 xmlTextWriterStackEntry * p); 124 125 /** 126 * xmlWriterErrMsg: 127 * @ctxt: a writer context 128 * @error: the error number 129 * @msg: the error message 130 * 131 * Handle a writer error 132 */ 133 static void 134 xmlWriterErrMsg(xmlTextWriterPtr ctxt, xmlParserErrors error, 135 const char *msg) 136 { 137 if (ctxt != NULL) { 138 __xmlRaiseError(NULL, NULL, NULL, ctxt->ctxt, 139 NULL, XML_FROM_WRITER, error, XML_ERR_FATAL, 140 NULL, 0, NULL, NULL, NULL, 0, 0, "%s", msg); 141 } else { 142 __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_WRITER, error, 143 XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0, "%s", msg); 144 } 145 } 146 147 /** 148 * xmlWriterErrMsgInt: 149 * @ctxt: a writer context 150 * @error: the error number 151 * @msg: the error message 152 * @val: an int 153 * 154 * Handle a writer error 155 */ 156 static void LIBXML_ATTR_FORMAT(3,0) 157 xmlWriterErrMsgInt(xmlTextWriterPtr ctxt, xmlParserErrors error, 158 const char *msg, int val) 159 { 160 if (ctxt != NULL) { 161 __xmlRaiseError(NULL, NULL, NULL, ctxt->ctxt, 162 NULL, XML_FROM_WRITER, error, XML_ERR_FATAL, 163 NULL, 0, NULL, NULL, NULL, val, 0, msg, val); 164 } else { 165 __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_WRITER, error, 166 XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, val, 0, msg, val); 167 } 168 } 169 170 /** 171 * xmlNewTextWriter: 172 * @out: an xmlOutputBufferPtr 173 * 174 * Create a new xmlNewTextWriter structure using an xmlOutputBufferPtr 175 * NOTE: the @out parameter will be deallocated when the writer is closed 176 * (if the call succeed.) 177 * 178 * Returns the new xmlTextWriterPtr or NULL in case of error 179 */ 180 xmlTextWriterPtr 181 xmlNewTextWriter(xmlOutputBufferPtr out) 182 { 183 xmlTextWriterPtr ret; 184 185 ret = (xmlTextWriterPtr) xmlMalloc(sizeof(xmlTextWriter)); 186 if (ret == NULL) { 187 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY, 188 "xmlNewTextWriter : out of memory!\n"); 189 return NULL; 190 } 191 memset(ret, 0, (size_t) sizeof(xmlTextWriter)); 192 193 ret->nodes = xmlListCreate((xmlListDeallocator) 194 xmlFreeTextWriterStackEntry, 195 (xmlListDataCompare) 196 xmlCmpTextWriterStackEntry); 197 if (ret->nodes == NULL) { 198 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY, 199 "xmlNewTextWriter : out of memory!\n"); 200 xmlFree(ret); 201 return NULL; 202 } 203 204 ret->nsstack = xmlListCreate((xmlListDeallocator) 205 xmlFreeTextWriterNsStackEntry, 206 (xmlListDataCompare) 207 xmlCmpTextWriterNsStackEntry); 208 if (ret->nsstack == NULL) { 209 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY, 210 "xmlNewTextWriter : out of memory!\n"); 211 xmlListDelete(ret->nodes); 212 xmlFree(ret); 213 return NULL; 214 } 215 216 ret->out = out; 217 ret->ichar = xmlStrdup(BAD_CAST " "); 218 ret->qchar = '"'; 219 220 if (!ret->ichar) { 221 xmlListDelete(ret->nodes); 222 xmlListDelete(ret->nsstack); 223 xmlFree(ret); 224 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY, 225 "xmlNewTextWriter : out of memory!\n"); 226 return NULL; 227 } 228 229 ret->doc = xmlNewDoc(NULL); 230 231 ret->no_doc_free = 0; 232 233 return ret; 234 } 235 236 /** 237 * xmlNewTextWriterFilename: 238 * @uri: the URI of the resource for the output 239 * @compression: compress the output? 240 * 241 * Create a new xmlNewTextWriter structure with @uri as output 242 * 243 * Returns the new xmlTextWriterPtr or NULL in case of error 244 */ 245 xmlTextWriterPtr 246 xmlNewTextWriterFilename(const char *uri, int compression) 247 { 248 xmlTextWriterPtr ret; 249 xmlOutputBufferPtr out; 250 251 out = xmlOutputBufferCreateFilename(uri, NULL, compression); 252 if (out == NULL) { 253 xmlWriterErrMsg(NULL, XML_IO_EIO, 254 "xmlNewTextWriterFilename : cannot open uri\n"); 255 return NULL; 256 } 257 258 ret = xmlNewTextWriter(out); 259 if (ret == NULL) { 260 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY, 261 "xmlNewTextWriterFilename : out of memory!\n"); 262 xmlOutputBufferClose(out); 263 return NULL; 264 } 265 266 ret->indent = 0; 267 ret->doindent = 0; 268 return ret; 269 } 270 271 /** 272 * xmlNewTextWriterMemory: 273 * @buf: xmlBufferPtr 274 * @compression: compress the output? 275 * 276 * Create a new xmlNewTextWriter structure with @buf as output 277 * TODO: handle compression 278 * 279 * Returns the new xmlTextWriterPtr or NULL in case of error 280 */ 281 xmlTextWriterPtr 282 xmlNewTextWriterMemory(xmlBufferPtr buf, int compression ATTRIBUTE_UNUSED) 283 { 284 xmlTextWriterPtr ret; 285 xmlOutputBufferPtr out; 286 287 /*::todo handle compression */ 288 out = xmlOutputBufferCreateBuffer(buf, NULL); 289 290 if (out == NULL) { 291 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY, 292 "xmlNewTextWriterMemory : out of memory!\n"); 293 return NULL; 294 } 295 296 ret = xmlNewTextWriter(out); 297 if (ret == NULL) { 298 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY, 299 "xmlNewTextWriterMemory : out of memory!\n"); 300 xmlOutputBufferClose(out); 301 return NULL; 302 } 303 304 return ret; 305 } 306 307 /** 308 * xmlNewTextWriterPushParser: 309 * @ctxt: xmlParserCtxtPtr to hold the new XML document tree 310 * @compression: compress the output? 311 * 312 * Create a new xmlNewTextWriter structure with @ctxt as output 313 * NOTE: the @ctxt context will be freed with the resulting writer 314 * (if the call succeeds). 315 * TODO: handle compression 316 * 317 * Returns the new xmlTextWriterPtr or NULL in case of error 318 */ 319 xmlTextWriterPtr 320 xmlNewTextWriterPushParser(xmlParserCtxtPtr ctxt, 321 int compression ATTRIBUTE_UNUSED) 322 { 323 xmlTextWriterPtr ret; 324 xmlOutputBufferPtr out; 325 326 if (ctxt == NULL) { 327 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR, 328 "xmlNewTextWriterPushParser : invalid context!\n"); 329 return NULL; 330 } 331 332 out = xmlOutputBufferCreateIO((xmlOutputWriteCallback) 333 xmlTextWriterWriteDocCallback, 334 (xmlOutputCloseCallback) 335 xmlTextWriterCloseDocCallback, 336 (void *) ctxt, NULL); 337 if (out == NULL) { 338 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR, 339 "xmlNewTextWriterPushParser : error at xmlOutputBufferCreateIO!\n"); 340 return NULL; 341 } 342 343 ret = xmlNewTextWriter(out); 344 if (ret == NULL) { 345 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR, 346 "xmlNewTextWriterPushParser : error at xmlNewTextWriter!\n"); 347 xmlOutputBufferClose(out); 348 return NULL; 349 } 350 351 ret->ctxt = ctxt; 352 353 return ret; 354 } 355 356 /** 357 * xmlNewTextWriterDoc: 358 * @doc: address of a xmlDocPtr to hold the new XML document tree 359 * @compression: compress the output? 360 * 361 * Create a new xmlNewTextWriter structure with @*doc as output 362 * 363 * Returns the new xmlTextWriterPtr or NULL in case of error 364 */ 365 xmlTextWriterPtr 366 xmlNewTextWriterDoc(xmlDocPtr * doc, int compression) 367 { 368 xmlTextWriterPtr ret; 369 xmlSAXHandler saxHandler; 370 xmlParserCtxtPtr ctxt; 371 372 memset(&saxHandler, '\0', sizeof(saxHandler)); 373 xmlSAX2InitDefaultSAXHandler(&saxHandler, 1); 374 saxHandler.startDocument = xmlTextWriterStartDocumentCallback; 375 saxHandler.startElement = xmlSAX2StartElement; 376 saxHandler.endElement = xmlSAX2EndElement; 377 378 ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL); 379 if (ctxt == NULL) { 380 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR, 381 "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n"); 382 return NULL; 383 } 384 /* 385 * For some reason this seems to completely break if node names 386 * are interned. 387 */ 388 ctxt->dictNames = 0; 389 390 ctxt->myDoc = xmlNewDoc(BAD_CAST XML_DEFAULT_VERSION); 391 if (ctxt->myDoc == NULL) { 392 xmlFreeParserCtxt(ctxt); 393 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR, 394 "xmlNewTextWriterDoc : error at xmlNewDoc!\n"); 395 return NULL; 396 } 397 398 ret = xmlNewTextWriterPushParser(ctxt, compression); 399 if (ret == NULL) { 400 xmlFreeDoc(ctxt->myDoc); 401 xmlFreeParserCtxt(ctxt); 402 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR, 403 "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n"); 404 return NULL; 405 } 406 407 xmlSetDocCompressMode(ctxt->myDoc, compression); 408 409 if (doc != NULL) { 410 *doc = ctxt->myDoc; 411 ret->no_doc_free = 1; 412 } 413 414 return ret; 415 } 416 417 /** 418 * xmlNewTextWriterTree: 419 * @doc: xmlDocPtr 420 * @node: xmlNodePtr or NULL for doc->children 421 * @compression: compress the output? 422 * 423 * Create a new xmlNewTextWriter structure with @doc as output 424 * starting at @node 425 * 426 * Returns the new xmlTextWriterPtr or NULL in case of error 427 */ 428 xmlTextWriterPtr 429 xmlNewTextWriterTree(xmlDocPtr doc, xmlNodePtr node, int compression) 430 { 431 xmlTextWriterPtr ret; 432 xmlSAXHandler saxHandler; 433 xmlParserCtxtPtr ctxt; 434 435 if (doc == NULL) { 436 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR, 437 "xmlNewTextWriterTree : invalid document tree!\n"); 438 return NULL; 439 } 440 441 memset(&saxHandler, '\0', sizeof(saxHandler)); 442 xmlSAX2InitDefaultSAXHandler(&saxHandler, 1); 443 saxHandler.startDocument = xmlTextWriterStartDocumentCallback; 444 saxHandler.startElement = xmlSAX2StartElement; 445 saxHandler.endElement = xmlSAX2EndElement; 446 447 ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL); 448 if (ctxt == NULL) { 449 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR, 450 "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n"); 451 return NULL; 452 } 453 /* 454 * For some reason this seems to completely break if node names 455 * are interned. 456 */ 457 ctxt->dictNames = 0; 458 459 ret = xmlNewTextWriterPushParser(ctxt, compression); 460 if (ret == NULL) { 461 xmlFreeParserCtxt(ctxt); 462 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR, 463 "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n"); 464 return NULL; 465 } 466 467 ctxt->myDoc = doc; 468 ctxt->node = node; 469 ret->no_doc_free = 1; 470 471 xmlSetDocCompressMode(doc, compression); 472 473 return ret; 474 } 475 476 /** 477 * xmlFreeTextWriter: 478 * @writer: the xmlTextWriterPtr 479 * 480 * Deallocate all the resources associated to the writer 481 */ 482 void 483 xmlFreeTextWriter(xmlTextWriterPtr writer) 484 { 485 if (writer == NULL) 486 return; 487 488 if (writer->out != NULL) 489 xmlOutputBufferClose(writer->out); 490 491 if (writer->nodes != NULL) 492 xmlListDelete(writer->nodes); 493 494 if (writer->nsstack != NULL) 495 xmlListDelete(writer->nsstack); 496 497 if (writer->ctxt != NULL) { 498 if ((writer->ctxt->myDoc != NULL) && (writer->no_doc_free == 0)) { 499 xmlFreeDoc(writer->ctxt->myDoc); 500 writer->ctxt->myDoc = NULL; 501 } 502 xmlFreeParserCtxt(writer->ctxt); 503 } 504 505 if (writer->doc != NULL) 506 xmlFreeDoc(writer->doc); 507 508 if (writer->ichar != NULL) 509 xmlFree(writer->ichar); 510 xmlFree(writer); 511 } 512 513 /** 514 * xmlTextWriterStartDocument: 515 * @writer: the xmlTextWriterPtr 516 * @version: the xml version ("1.0") or NULL for default ("1.0") 517 * @encoding: the encoding or NULL for default 518 * @standalone: "yes" or "no" or NULL for default 519 * 520 * Start a new xml document 521 * 522 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 523 */ 524 int 525 xmlTextWriterStartDocument(xmlTextWriterPtr writer, const char *version, 526 const char *encoding, const char *standalone) 527 { 528 int count; 529 int sum; 530 xmlLinkPtr lk; 531 xmlCharEncodingHandlerPtr encoder; 532 533 if ((writer == NULL) || (writer->out == NULL)) { 534 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 535 "xmlTextWriterStartDocument : invalid writer!\n"); 536 return -1; 537 } 538 539 lk = xmlListFront(writer->nodes); 540 if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) { 541 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 542 "xmlTextWriterStartDocument : not allowed in this context!\n"); 543 return -1; 544 } 545 546 encoder = NULL; 547 if (encoding != NULL) { 548 encoder = xmlFindCharEncodingHandler(encoding); 549 if (encoder == NULL) { 550 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 551 "xmlTextWriterStartDocument : out of memory!\n"); 552 return -1; 553 } 554 } 555 556 writer->out->encoder = encoder; 557 if (encoder != NULL) { 558 if (writer->out->conv == NULL) { 559 writer->out->conv = xmlBufCreateSize(4000); 560 } 561 xmlCharEncOutput(writer->out, 1); 562 if ((writer->doc != NULL) && (writer->doc->encoding == NULL)) 563 writer->doc->encoding = xmlStrdup((xmlChar *)writer->out->encoder->name); 564 } else 565 writer->out->conv = NULL; 566 567 sum = 0; 568 count = xmlOutputBufferWriteString(writer->out, "<?xml version="); 569 if (count < 0) 570 return -1; 571 sum += count; 572 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 573 if (count < 0) 574 return -1; 575 sum += count; 576 if (version != 0) 577 count = xmlOutputBufferWriteString(writer->out, version); 578 else 579 count = xmlOutputBufferWriteString(writer->out, "1.0"); 580 if (count < 0) 581 return -1; 582 sum += count; 583 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 584 if (count < 0) 585 return -1; 586 sum += count; 587 if (writer->out->encoder != 0) { 588 count = xmlOutputBufferWriteString(writer->out, " encoding="); 589 if (count < 0) 590 return -1; 591 sum += count; 592 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 593 if (count < 0) 594 return -1; 595 sum += count; 596 count = 597 xmlOutputBufferWriteString(writer->out, 598 writer->out->encoder->name); 599 if (count < 0) 600 return -1; 601 sum += count; 602 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 603 if (count < 0) 604 return -1; 605 sum += count; 606 } 607 608 if (standalone != 0) { 609 count = xmlOutputBufferWriteString(writer->out, " standalone="); 610 if (count < 0) 611 return -1; 612 sum += count; 613 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 614 if (count < 0) 615 return -1; 616 sum += count; 617 count = xmlOutputBufferWriteString(writer->out, standalone); 618 if (count < 0) 619 return -1; 620 sum += count; 621 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 622 if (count < 0) 623 return -1; 624 sum += count; 625 } 626 627 count = xmlOutputBufferWriteString(writer->out, "?>\n"); 628 if (count < 0) 629 return -1; 630 sum += count; 631 632 return sum; 633 } 634 635 /** 636 * xmlTextWriterEndDocument: 637 * @writer: the xmlTextWriterPtr 638 * 639 * End an xml document. All open elements are closed, and 640 * the content is flushed to the output. 641 * 642 * Returns the bytes written or -1 in case of error 643 */ 644 int 645 xmlTextWriterEndDocument(xmlTextWriterPtr writer) 646 { 647 int count; 648 int sum; 649 xmlLinkPtr lk; 650 xmlTextWriterStackEntry *p; 651 652 if (writer == NULL) { 653 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 654 "xmlTextWriterEndDocument : invalid writer!\n"); 655 return -1; 656 } 657 658 sum = 0; 659 while ((lk = xmlListFront(writer->nodes)) != NULL) { 660 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 661 if (p == 0) 662 break; 663 switch (p->state) { 664 case XML_TEXTWRITER_NAME: 665 case XML_TEXTWRITER_ATTRIBUTE: 666 case XML_TEXTWRITER_TEXT: 667 count = xmlTextWriterEndElement(writer); 668 if (count < 0) 669 return -1; 670 sum += count; 671 break; 672 case XML_TEXTWRITER_PI: 673 case XML_TEXTWRITER_PI_TEXT: 674 count = xmlTextWriterEndPI(writer); 675 if (count < 0) 676 return -1; 677 sum += count; 678 break; 679 case XML_TEXTWRITER_CDATA: 680 count = xmlTextWriterEndCDATA(writer); 681 if (count < 0) 682 return -1; 683 sum += count; 684 break; 685 case XML_TEXTWRITER_DTD: 686 case XML_TEXTWRITER_DTD_TEXT: 687 case XML_TEXTWRITER_DTD_ELEM: 688 case XML_TEXTWRITER_DTD_ELEM_TEXT: 689 case XML_TEXTWRITER_DTD_ATTL: 690 case XML_TEXTWRITER_DTD_ATTL_TEXT: 691 case XML_TEXTWRITER_DTD_ENTY: 692 case XML_TEXTWRITER_DTD_ENTY_TEXT: 693 case XML_TEXTWRITER_DTD_PENT: 694 count = xmlTextWriterEndDTD(writer); 695 if (count < 0) 696 return -1; 697 sum += count; 698 break; 699 case XML_TEXTWRITER_COMMENT: 700 count = xmlTextWriterEndComment(writer); 701 if (count < 0) 702 return -1; 703 sum += count; 704 break; 705 default: 706 break; 707 } 708 } 709 710 if (!writer->indent) { 711 count = xmlOutputBufferWriteString(writer->out, "\n"); 712 if (count < 0) 713 return -1; 714 sum += count; 715 } 716 717 sum += xmlTextWriterFlush(writer); 718 719 return sum; 720 } 721 722 /** 723 * xmlTextWriterStartComment: 724 * @writer: the xmlTextWriterPtr 725 * 726 * Start an xml comment. 727 * 728 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 729 */ 730 int 731 xmlTextWriterStartComment(xmlTextWriterPtr writer) 732 { 733 int count; 734 int sum; 735 xmlLinkPtr lk; 736 xmlTextWriterStackEntry *p; 737 738 if (writer == NULL) { 739 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 740 "xmlTextWriterStartComment : invalid writer!\n"); 741 return -1; 742 } 743 744 sum = 0; 745 lk = xmlListFront(writer->nodes); 746 if (lk != 0) { 747 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 748 if (p != 0) { 749 switch (p->state) { 750 case XML_TEXTWRITER_TEXT: 751 case XML_TEXTWRITER_NONE: 752 break; 753 case XML_TEXTWRITER_NAME: 754 /* Output namespace declarations */ 755 count = xmlTextWriterOutputNSDecl(writer); 756 if (count < 0) 757 return -1; 758 sum += count; 759 count = xmlOutputBufferWriteString(writer->out, ">"); 760 if (count < 0) 761 return -1; 762 sum += count; 763 if (writer->indent) { 764 count = 765 xmlOutputBufferWriteString(writer->out, "\n"); 766 if (count < 0) 767 return -1; 768 sum += count; 769 } 770 p->state = XML_TEXTWRITER_TEXT; 771 break; 772 default: 773 return -1; 774 } 775 } 776 } 777 778 p = (xmlTextWriterStackEntry *) 779 xmlMalloc(sizeof(xmlTextWriterStackEntry)); 780 if (p == 0) { 781 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 782 "xmlTextWriterStartElement : out of memory!\n"); 783 return -1; 784 } 785 786 p->name = NULL; 787 p->state = XML_TEXTWRITER_COMMENT; 788 789 xmlListPushFront(writer->nodes, p); 790 791 if (writer->indent) { 792 count = xmlTextWriterWriteIndent(writer); 793 if (count < 0) 794 return -1; 795 sum += count; 796 } 797 798 count = xmlOutputBufferWriteString(writer->out, "<!--"); 799 if (count < 0) 800 return -1; 801 sum += count; 802 803 return sum; 804 } 805 806 /** 807 * xmlTextWriterEndComment: 808 * @writer: the xmlTextWriterPtr 809 * 810 * End the current xml coment. 811 * 812 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 813 */ 814 int 815 xmlTextWriterEndComment(xmlTextWriterPtr writer) 816 { 817 int count; 818 int sum; 819 xmlLinkPtr lk; 820 xmlTextWriterStackEntry *p; 821 822 if (writer == NULL) { 823 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 824 "xmlTextWriterEndComment : invalid writer!\n"); 825 return -1; 826 } 827 828 lk = xmlListFront(writer->nodes); 829 if (lk == 0) { 830 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 831 "xmlTextWriterEndComment : not allowed in this context!\n"); 832 return -1; 833 } 834 835 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 836 if (p == 0) 837 return -1; 838 839 sum = 0; 840 switch (p->state) { 841 case XML_TEXTWRITER_COMMENT: 842 count = xmlOutputBufferWriteString(writer->out, "-->"); 843 if (count < 0) 844 return -1; 845 sum += count; 846 break; 847 default: 848 return -1; 849 } 850 851 if (writer->indent) { 852 count = xmlOutputBufferWriteString(writer->out, "\n"); 853 if (count < 0) 854 return -1; 855 sum += count; 856 } 857 858 xmlListPopFront(writer->nodes); 859 return sum; 860 } 861 862 /** 863 * xmlTextWriterWriteFormatComment: 864 * @writer: the xmlTextWriterPtr 865 * @format: format string (see printf) 866 * @...: extra parameters for the format 867 * 868 * Write an xml comment. 869 * 870 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 871 */ 872 int XMLCDECL 873 xmlTextWriterWriteFormatComment(xmlTextWriterPtr writer, 874 const char *format, ...) 875 { 876 int rc; 877 va_list ap; 878 879 va_start(ap, format); 880 881 rc = xmlTextWriterWriteVFormatComment(writer, format, ap); 882 883 va_end(ap); 884 return rc; 885 } 886 887 /** 888 * xmlTextWriterWriteVFormatComment: 889 * @writer: the xmlTextWriterPtr 890 * @format: format string (see printf) 891 * @argptr: pointer to the first member of the variable argument list. 892 * 893 * Write an xml comment. 894 * 895 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 896 */ 897 int 898 xmlTextWriterWriteVFormatComment(xmlTextWriterPtr writer, 899 const char *format, va_list argptr) 900 { 901 int rc; 902 xmlChar *buf; 903 904 if (writer == NULL) { 905 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 906 "xmlTextWriterWriteVFormatComment : invalid writer!\n"); 907 return -1; 908 } 909 910 buf = xmlTextWriterVSprintf(format, argptr); 911 if (buf == NULL) 912 return -1; 913 914 rc = xmlTextWriterWriteComment(writer, buf); 915 916 xmlFree(buf); 917 return rc; 918 } 919 920 /** 921 * xmlTextWriterWriteComment: 922 * @writer: the xmlTextWriterPtr 923 * @content: comment string 924 * 925 * Write an xml comment. 926 * 927 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 928 */ 929 int 930 xmlTextWriterWriteComment(xmlTextWriterPtr writer, const xmlChar * content) 931 { 932 int count; 933 int sum; 934 935 sum = 0; 936 count = xmlTextWriterStartComment(writer); 937 if (count < 0) 938 return -1; 939 sum += count; 940 count = xmlTextWriterWriteString(writer, content); 941 if (count < 0) 942 return -1; 943 sum += count; 944 count = xmlTextWriterEndComment(writer); 945 if (count < 0) 946 return -1; 947 sum += count; 948 949 return sum; 950 } 951 952 /** 953 * xmlTextWriterStartElement: 954 * @writer: the xmlTextWriterPtr 955 * @name: element name 956 * 957 * Start an xml element. 958 * 959 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 960 */ 961 int 962 xmlTextWriterStartElement(xmlTextWriterPtr writer, const xmlChar * name) 963 { 964 int count; 965 int sum; 966 xmlLinkPtr lk; 967 xmlTextWriterStackEntry *p; 968 969 if ((writer == NULL) || (name == NULL) || (*name == '\0')) 970 return -1; 971 972 sum = 0; 973 lk = xmlListFront(writer->nodes); 974 if (lk != 0) { 975 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 976 if (p != 0) { 977 switch (p->state) { 978 case XML_TEXTWRITER_PI: 979 case XML_TEXTWRITER_PI_TEXT: 980 return -1; 981 case XML_TEXTWRITER_NONE: 982 break; 983 case XML_TEXTWRITER_ATTRIBUTE: 984 count = xmlTextWriterEndAttribute(writer); 985 if (count < 0) 986 return -1; 987 sum += count; 988 /* fallthrough */ 989 case XML_TEXTWRITER_NAME: 990 /* Output namespace declarations */ 991 count = xmlTextWriterOutputNSDecl(writer); 992 if (count < 0) 993 return -1; 994 sum += count; 995 count = xmlOutputBufferWriteString(writer->out, ">"); 996 if (count < 0) 997 return -1; 998 sum += count; 999 if (writer->indent) 1000 count = 1001 xmlOutputBufferWriteString(writer->out, "\n"); 1002 p->state = XML_TEXTWRITER_TEXT; 1003 break; 1004 default: 1005 break; 1006 } 1007 } 1008 } 1009 1010 p = (xmlTextWriterStackEntry *) 1011 xmlMalloc(sizeof(xmlTextWriterStackEntry)); 1012 if (p == 0) { 1013 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 1014 "xmlTextWriterStartElement : out of memory!\n"); 1015 return -1; 1016 } 1017 1018 p->name = xmlStrdup(name); 1019 if (p->name == 0) { 1020 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 1021 "xmlTextWriterStartElement : out of memory!\n"); 1022 xmlFree(p); 1023 return -1; 1024 } 1025 p->state = XML_TEXTWRITER_NAME; 1026 1027 xmlListPushFront(writer->nodes, p); 1028 1029 if (writer->indent) { 1030 count = xmlTextWriterWriteIndent(writer); 1031 sum += count; 1032 } 1033 1034 count = xmlOutputBufferWriteString(writer->out, "<"); 1035 if (count < 0) 1036 return -1; 1037 sum += count; 1038 count = 1039 xmlOutputBufferWriteString(writer->out, (const char *) p->name); 1040 if (count < 0) 1041 return -1; 1042 sum += count; 1043 1044 return sum; 1045 } 1046 1047 /** 1048 * xmlTextWriterStartElementNS: 1049 * @writer: the xmlTextWriterPtr 1050 * @prefix: namespace prefix or NULL 1051 * @name: element local name 1052 * @namespaceURI: namespace URI or NULL 1053 * 1054 * Start an xml element with namespace support. 1055 * 1056 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 1057 */ 1058 int 1059 xmlTextWriterStartElementNS(xmlTextWriterPtr writer, 1060 const xmlChar * prefix, const xmlChar * name, 1061 const xmlChar * namespaceURI) 1062 { 1063 int count; 1064 int sum; 1065 xmlChar *buf; 1066 1067 if ((writer == NULL) || (name == NULL) || (*name == '\0')) 1068 return -1; 1069 1070 buf = NULL; 1071 if (prefix != 0) { 1072 buf = xmlStrdup(prefix); 1073 buf = xmlStrcat(buf, BAD_CAST ":"); 1074 } 1075 buf = xmlStrcat(buf, name); 1076 1077 sum = 0; 1078 count = xmlTextWriterStartElement(writer, buf); 1079 xmlFree(buf); 1080 if (count < 0) 1081 return -1; 1082 sum += count; 1083 1084 if (namespaceURI != 0) { 1085 xmlTextWriterNsStackEntry *p = (xmlTextWriterNsStackEntry *) 1086 xmlMalloc(sizeof(xmlTextWriterNsStackEntry)); 1087 if (p == 0) { 1088 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 1089 "xmlTextWriterStartElementNS : out of memory!\n"); 1090 return -1; 1091 } 1092 1093 buf = xmlStrdup(BAD_CAST "xmlns"); 1094 if (prefix != 0) { 1095 buf = xmlStrcat(buf, BAD_CAST ":"); 1096 buf = xmlStrcat(buf, prefix); 1097 } 1098 1099 p->prefix = buf; 1100 p->uri = xmlStrdup(namespaceURI); 1101 if (p->uri == 0) { 1102 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 1103 "xmlTextWriterStartElementNS : out of memory!\n"); 1104 xmlFree(p); 1105 return -1; 1106 } 1107 p->elem = xmlListFront(writer->nodes); 1108 1109 xmlListPushFront(writer->nsstack, p); 1110 } 1111 1112 return sum; 1113 } 1114 1115 /** 1116 * xmlTextWriterEndElement: 1117 * @writer: the xmlTextWriterPtr 1118 * 1119 * End the current xml element. 1120 * 1121 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 1122 */ 1123 int 1124 xmlTextWriterEndElement(xmlTextWriterPtr writer) 1125 { 1126 int count; 1127 int sum; 1128 xmlLinkPtr lk; 1129 xmlTextWriterStackEntry *p; 1130 1131 if (writer == NULL) 1132 return -1; 1133 1134 lk = xmlListFront(writer->nodes); 1135 if (lk == 0) { 1136 xmlListDelete(writer->nsstack); 1137 writer->nsstack = NULL; 1138 return -1; 1139 } 1140 1141 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 1142 if (p == 0) { 1143 xmlListDelete(writer->nsstack); 1144 writer->nsstack = NULL; 1145 return -1; 1146 } 1147 1148 sum = 0; 1149 switch (p->state) { 1150 case XML_TEXTWRITER_ATTRIBUTE: 1151 count = xmlTextWriterEndAttribute(writer); 1152 if (count < 0) { 1153 xmlListDelete(writer->nsstack); 1154 writer->nsstack = NULL; 1155 return -1; 1156 } 1157 sum += count; 1158 /* fallthrough */ 1159 case XML_TEXTWRITER_NAME: 1160 /* Output namespace declarations */ 1161 count = xmlTextWriterOutputNSDecl(writer); 1162 if (count < 0) 1163 return -1; 1164 sum += count; 1165 1166 if (writer->indent) /* next element needs indent */ 1167 writer->doindent = 1; 1168 count = xmlOutputBufferWriteString(writer->out, "/>"); 1169 if (count < 0) 1170 return -1; 1171 sum += count; 1172 break; 1173 case XML_TEXTWRITER_TEXT: 1174 if ((writer->indent) && (writer->doindent)) { 1175 count = xmlTextWriterWriteIndent(writer); 1176 sum += count; 1177 writer->doindent = 1; 1178 } else 1179 writer->doindent = 1; 1180 count = xmlOutputBufferWriteString(writer->out, "</"); 1181 if (count < 0) 1182 return -1; 1183 sum += count; 1184 count = xmlOutputBufferWriteString(writer->out, 1185 (const char *) p->name); 1186 if (count < 0) 1187 return -1; 1188 sum += count; 1189 count = xmlOutputBufferWriteString(writer->out, ">"); 1190 if (count < 0) 1191 return -1; 1192 sum += count; 1193 break; 1194 default: 1195 return -1; 1196 } 1197 1198 if (writer->indent) { 1199 count = xmlOutputBufferWriteString(writer->out, "\n"); 1200 sum += count; 1201 } 1202 1203 xmlListPopFront(writer->nodes); 1204 return sum; 1205 } 1206 1207 /** 1208 * xmlTextWriterFullEndElement: 1209 * @writer: the xmlTextWriterPtr 1210 * 1211 * End the current xml element. Writes an end tag even if the element is empty 1212 * 1213 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 1214 */ 1215 int 1216 xmlTextWriterFullEndElement(xmlTextWriterPtr writer) 1217 { 1218 int count; 1219 int sum; 1220 xmlLinkPtr lk; 1221 xmlTextWriterStackEntry *p; 1222 1223 if (writer == NULL) 1224 return -1; 1225 1226 lk = xmlListFront(writer->nodes); 1227 if (lk == 0) 1228 return -1; 1229 1230 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 1231 if (p == 0) 1232 return -1; 1233 1234 sum = 0; 1235 switch (p->state) { 1236 case XML_TEXTWRITER_ATTRIBUTE: 1237 count = xmlTextWriterEndAttribute(writer); 1238 if (count < 0) 1239 return -1; 1240 sum += count; 1241 /* fallthrough */ 1242 case XML_TEXTWRITER_NAME: 1243 /* Output namespace declarations */ 1244 count = xmlTextWriterOutputNSDecl(writer); 1245 if (count < 0) 1246 return -1; 1247 sum += count; 1248 1249 count = xmlOutputBufferWriteString(writer->out, ">"); 1250 if (count < 0) 1251 return -1; 1252 sum += count; 1253 if (writer->indent) 1254 writer->doindent = 0; 1255 /* fallthrough */ 1256 case XML_TEXTWRITER_TEXT: 1257 if ((writer->indent) && (writer->doindent)) { 1258 count = xmlTextWriterWriteIndent(writer); 1259 sum += count; 1260 writer->doindent = 1; 1261 } else 1262 writer->doindent = 1; 1263 count = xmlOutputBufferWriteString(writer->out, "</"); 1264 if (count < 0) 1265 return -1; 1266 sum += count; 1267 count = xmlOutputBufferWriteString(writer->out, 1268 (const char *) p->name); 1269 if (count < 0) 1270 return -1; 1271 sum += count; 1272 count = xmlOutputBufferWriteString(writer->out, ">"); 1273 if (count < 0) 1274 return -1; 1275 sum += count; 1276 break; 1277 default: 1278 return -1; 1279 } 1280 1281 if (writer->indent) { 1282 count = xmlOutputBufferWriteString(writer->out, "\n"); 1283 sum += count; 1284 } 1285 1286 xmlListPopFront(writer->nodes); 1287 return sum; 1288 } 1289 1290 /** 1291 * xmlTextWriterWriteFormatRaw: 1292 * @writer: the xmlTextWriterPtr 1293 * @format: format string (see printf) 1294 * @...: extra parameters for the format 1295 * 1296 * Write a formatted raw xml text. 1297 * 1298 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 1299 */ 1300 int XMLCDECL 1301 xmlTextWriterWriteFormatRaw(xmlTextWriterPtr writer, const char *format, 1302 ...) 1303 { 1304 int rc; 1305 va_list ap; 1306 1307 va_start(ap, format); 1308 1309 rc = xmlTextWriterWriteVFormatRaw(writer, format, ap); 1310 1311 va_end(ap); 1312 return rc; 1313 } 1314 1315 /** 1316 * xmlTextWriterWriteVFormatRaw: 1317 * @writer: the xmlTextWriterPtr 1318 * @format: format string (see printf) 1319 * @argptr: pointer to the first member of the variable argument list. 1320 * 1321 * Write a formatted raw xml text. 1322 * 1323 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 1324 */ 1325 int 1326 xmlTextWriterWriteVFormatRaw(xmlTextWriterPtr writer, const char *format, 1327 va_list argptr) 1328 { 1329 int rc; 1330 xmlChar *buf; 1331 1332 if (writer == NULL) 1333 return -1; 1334 1335 buf = xmlTextWriterVSprintf(format, argptr); 1336 if (buf == NULL) 1337 return -1; 1338 1339 rc = xmlTextWriterWriteRaw(writer, buf); 1340 1341 xmlFree(buf); 1342 return rc; 1343 } 1344 1345 /** 1346 * xmlTextWriterWriteRawLen: 1347 * @writer: the xmlTextWriterPtr 1348 * @content: text string 1349 * @len: length of the text string 1350 * 1351 * Write an xml text. 1352 * TODO: what about entities and special chars?? 1353 * 1354 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 1355 */ 1356 int 1357 xmlTextWriterWriteRawLen(xmlTextWriterPtr writer, const xmlChar * content, 1358 int len) 1359 { 1360 int count; 1361 int sum; 1362 xmlLinkPtr lk; 1363 xmlTextWriterStackEntry *p; 1364 1365 if (writer == NULL) { 1366 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 1367 "xmlTextWriterWriteRawLen : invalid writer!\n"); 1368 return -1; 1369 } 1370 1371 if ((content == NULL) || (len < 0)) { 1372 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 1373 "xmlTextWriterWriteRawLen : invalid content!\n"); 1374 return -1; 1375 } 1376 1377 sum = 0; 1378 lk = xmlListFront(writer->nodes); 1379 if (lk != 0) { 1380 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 1381 count = xmlTextWriterHandleStateDependencies(writer, p); 1382 if (count < 0) 1383 return -1; 1384 sum += count; 1385 } 1386 1387 if (writer->indent) 1388 writer->doindent = 0; 1389 1390 if (content != NULL) { 1391 count = 1392 xmlOutputBufferWrite(writer->out, len, (const char *) content); 1393 if (count < 0) 1394 return -1; 1395 sum += count; 1396 } 1397 1398 return sum; 1399 } 1400 1401 /** 1402 * xmlTextWriterWriteRaw: 1403 * @writer: the xmlTextWriterPtr 1404 * @content: text string 1405 * 1406 * Write a raw xml text. 1407 * 1408 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 1409 */ 1410 int 1411 xmlTextWriterWriteRaw(xmlTextWriterPtr writer, const xmlChar * content) 1412 { 1413 return xmlTextWriterWriteRawLen(writer, content, xmlStrlen(content)); 1414 } 1415 1416 /** 1417 * xmlTextWriterWriteFormatString: 1418 * @writer: the xmlTextWriterPtr 1419 * @format: format string (see printf) 1420 * @...: extra parameters for the format 1421 * 1422 * Write a formatted xml text. 1423 * 1424 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 1425 */ 1426 int XMLCDECL 1427 xmlTextWriterWriteFormatString(xmlTextWriterPtr writer, const char *format, 1428 ...) 1429 { 1430 int rc; 1431 va_list ap; 1432 1433 if ((writer == NULL) || (format == NULL)) 1434 return -1; 1435 1436 va_start(ap, format); 1437 1438 rc = xmlTextWriterWriteVFormatString(writer, format, ap); 1439 1440 va_end(ap); 1441 return rc; 1442 } 1443 1444 /** 1445 * xmlTextWriterWriteVFormatString: 1446 * @writer: the xmlTextWriterPtr 1447 * @format: format string (see printf) 1448 * @argptr: pointer to the first member of the variable argument list. 1449 * 1450 * Write a formatted xml text. 1451 * 1452 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 1453 */ 1454 int 1455 xmlTextWriterWriteVFormatString(xmlTextWriterPtr writer, 1456 const char *format, va_list argptr) 1457 { 1458 int rc; 1459 xmlChar *buf; 1460 1461 if ((writer == NULL) || (format == NULL)) 1462 return -1; 1463 1464 buf = xmlTextWriterVSprintf(format, argptr); 1465 if (buf == NULL) 1466 return -1; 1467 1468 rc = xmlTextWriterWriteString(writer, buf); 1469 1470 xmlFree(buf); 1471 return rc; 1472 } 1473 1474 /** 1475 * xmlTextWriterWriteString: 1476 * @writer: the xmlTextWriterPtr 1477 * @content: text string 1478 * 1479 * Write an xml text. 1480 * 1481 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 1482 */ 1483 int 1484 xmlTextWriterWriteString(xmlTextWriterPtr writer, const xmlChar * content) 1485 { 1486 int count; 1487 int sum; 1488 xmlLinkPtr lk; 1489 xmlTextWriterStackEntry *p; 1490 xmlChar *buf; 1491 1492 if ((writer == NULL) || (content == NULL)) 1493 return -1; 1494 1495 sum = 0; 1496 buf = (xmlChar *) content; 1497 lk = xmlListFront(writer->nodes); 1498 if (lk != 0) { 1499 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 1500 if (p != 0) { 1501 switch (p->state) { 1502 case XML_TEXTWRITER_NAME: 1503 case XML_TEXTWRITER_TEXT: 1504 #if 0 1505 buf = NULL; 1506 xmlOutputBufferWriteEscape(writer->out, content, NULL); 1507 #endif 1508 buf = xmlEncodeSpecialChars(NULL, content); 1509 break; 1510 case XML_TEXTWRITER_ATTRIBUTE: 1511 buf = NULL; 1512 xmlBufAttrSerializeTxtContent(writer->out->buffer, 1513 writer->doc, NULL, content); 1514 break; 1515 default: 1516 break; 1517 } 1518 } 1519 } 1520 1521 if (buf != NULL) { 1522 count = xmlTextWriterWriteRaw(writer, buf); 1523 1524 if (buf != content) /* buf was allocated by us, so free it */ 1525 xmlFree(buf); 1526 1527 if (count < 0) 1528 return -1; 1529 sum += count; 1530 } 1531 1532 return sum; 1533 } 1534 1535 /** 1536 * xmlOutputBufferWriteBase64: 1537 * @out: the xmlOutputBufferPtr 1538 * @data: binary data 1539 * @len: the number of bytes to encode 1540 * 1541 * Write base64 encoded data to an xmlOutputBuffer. 1542 * Adapted from John Walker's base64.c (http://www.fourmilab.ch/). 1543 * 1544 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 1545 */ 1546 static int 1547 xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len, 1548 const unsigned char *data) 1549 { 1550 static unsigned char dtable[64] = 1551 {'A','B','C','D','E','F','G','H','I','J','K','L','M', 1552 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z', 1553 'a','b','c','d','e','f','g','h','i','j','k','l','m', 1554 'n','o','p','q','r','s','t','u','v','w','x','y','z', 1555 '0','1','2','3','4','5','6','7','8','9','+','/'}; 1556 1557 int i; 1558 int linelen; 1559 int count; 1560 int sum; 1561 1562 if ((out == NULL) || (len < 0) || (data == NULL)) 1563 return(-1); 1564 1565 linelen = 0; 1566 sum = 0; 1567 1568 i = 0; 1569 while (1) { 1570 unsigned char igroup[3]; 1571 unsigned char ogroup[4]; 1572 int c; 1573 int n; 1574 1575 igroup[0] = igroup[1] = igroup[2] = 0; 1576 for (n = 0; n < 3 && i < len; n++, i++) { 1577 c = data[i]; 1578 igroup[n] = (unsigned char) c; 1579 } 1580 1581 if (n > 0) { 1582 ogroup[0] = dtable[igroup[0] >> 2]; 1583 ogroup[1] = dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)]; 1584 ogroup[2] = 1585 dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)]; 1586 ogroup[3] = dtable[igroup[2] & 0x3F]; 1587 1588 if (n < 3) { 1589 ogroup[3] = '='; 1590 if (n < 2) { 1591 ogroup[2] = '='; 1592 } 1593 } 1594 1595 if (linelen >= B64LINELEN) { 1596 count = xmlOutputBufferWrite(out, 2, B64CRLF); 1597 if (count == -1) 1598 return -1; 1599 sum += count; 1600 linelen = 0; 1601 } 1602 count = xmlOutputBufferWrite(out, 4, (const char *) ogroup); 1603 if (count == -1) 1604 return -1; 1605 sum += count; 1606 1607 linelen += 4; 1608 } 1609 1610 if (i >= len) 1611 break; 1612 } 1613 1614 return sum; 1615 } 1616 1617 /** 1618 * xmlTextWriterWriteBase64: 1619 * @writer: the xmlTextWriterPtr 1620 * @data: binary data 1621 * @start: the position within the data of the first byte to encode 1622 * @len: the number of bytes to encode 1623 * 1624 * Write an base64 encoded xml text. 1625 * 1626 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 1627 */ 1628 int 1629 xmlTextWriterWriteBase64(xmlTextWriterPtr writer, const char *data, 1630 int start, int len) 1631 { 1632 int count; 1633 int sum; 1634 xmlLinkPtr lk; 1635 xmlTextWriterStackEntry *p; 1636 1637 if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0)) 1638 return -1; 1639 1640 sum = 0; 1641 lk = xmlListFront(writer->nodes); 1642 if (lk != 0) { 1643 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 1644 if (p != 0) { 1645 count = xmlTextWriterHandleStateDependencies(writer, p); 1646 if (count < 0) 1647 return -1; 1648 sum += count; 1649 } 1650 } 1651 1652 if (writer->indent) 1653 writer->doindent = 0; 1654 1655 count = 1656 xmlOutputBufferWriteBase64(writer->out, len, 1657 (unsigned char *) data + start); 1658 if (count < 0) 1659 return -1; 1660 sum += count; 1661 1662 return sum; 1663 } 1664 1665 /** 1666 * xmlOutputBufferWriteBinHex: 1667 * @out: the xmlOutputBufferPtr 1668 * @data: binary data 1669 * @len: the number of bytes to encode 1670 * 1671 * Write hqx encoded data to an xmlOutputBuffer. 1672 * ::todo 1673 * 1674 * Returns the bytes written (may be 0 because of buffering) 1675 * or -1 in case of error 1676 */ 1677 static int 1678 xmlOutputBufferWriteBinHex(xmlOutputBufferPtr out, 1679 int len, const unsigned char *data) 1680 { 1681 int count; 1682 int sum; 1683 static char hex[16] = 1684 {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; 1685 int i; 1686 1687 if ((out == NULL) || (data == NULL) || (len < 0)) { 1688 return -1; 1689 } 1690 1691 sum = 0; 1692 for (i = 0; i < len; i++) { 1693 count = 1694 xmlOutputBufferWrite(out, 1, 1695 (const char *) &hex[data[i] >> 4]); 1696 if (count == -1) 1697 return -1; 1698 sum += count; 1699 count = 1700 xmlOutputBufferWrite(out, 1, 1701 (const char *) &hex[data[i] & 0xF]); 1702 if (count == -1) 1703 return -1; 1704 sum += count; 1705 } 1706 1707 return sum; 1708 } 1709 1710 /** 1711 * xmlTextWriterWriteBinHex: 1712 * @writer: the xmlTextWriterPtr 1713 * @data: binary data 1714 * @start: the position within the data of the first byte to encode 1715 * @len: the number of bytes to encode 1716 * 1717 * Write a BinHex encoded xml text. 1718 * 1719 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 1720 */ 1721 int 1722 xmlTextWriterWriteBinHex(xmlTextWriterPtr writer, const char *data, 1723 int start, int len) 1724 { 1725 int count; 1726 int sum; 1727 xmlLinkPtr lk; 1728 xmlTextWriterStackEntry *p; 1729 1730 if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0)) 1731 return -1; 1732 1733 sum = 0; 1734 lk = xmlListFront(writer->nodes); 1735 if (lk != 0) { 1736 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 1737 if (p != 0) { 1738 count = xmlTextWriterHandleStateDependencies(writer, p); 1739 if (count < 0) 1740 return -1; 1741 sum += count; 1742 } 1743 } 1744 1745 if (writer->indent) 1746 writer->doindent = 0; 1747 1748 count = 1749 xmlOutputBufferWriteBinHex(writer->out, len, 1750 (unsigned char *) data + start); 1751 if (count < 0) 1752 return -1; 1753 sum += count; 1754 1755 return sum; 1756 } 1757 1758 /** 1759 * xmlTextWriterStartAttribute: 1760 * @writer: the xmlTextWriterPtr 1761 * @name: element name 1762 * 1763 * Start an xml attribute. 1764 * 1765 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 1766 */ 1767 int 1768 xmlTextWriterStartAttribute(xmlTextWriterPtr writer, const xmlChar * name) 1769 { 1770 int count; 1771 int sum; 1772 xmlLinkPtr lk; 1773 xmlTextWriterStackEntry *p; 1774 1775 if ((writer == NULL) || (name == NULL) || (*name == '\0')) 1776 return -1; 1777 1778 sum = 0; 1779 lk = xmlListFront(writer->nodes); 1780 if (lk == 0) 1781 return -1; 1782 1783 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 1784 if (p == 0) 1785 return -1; 1786 1787 switch (p->state) { 1788 case XML_TEXTWRITER_ATTRIBUTE: 1789 count = xmlTextWriterEndAttribute(writer); 1790 if (count < 0) 1791 return -1; 1792 sum += count; 1793 /* fallthrough */ 1794 case XML_TEXTWRITER_NAME: 1795 count = xmlOutputBufferWriteString(writer->out, " "); 1796 if (count < 0) 1797 return -1; 1798 sum += count; 1799 count = 1800 xmlOutputBufferWriteString(writer->out, 1801 (const char *) name); 1802 if (count < 0) 1803 return -1; 1804 sum += count; 1805 count = xmlOutputBufferWriteString(writer->out, "="); 1806 if (count < 0) 1807 return -1; 1808 sum += count; 1809 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 1810 if (count < 0) 1811 return -1; 1812 sum += count; 1813 p->state = XML_TEXTWRITER_ATTRIBUTE; 1814 break; 1815 default: 1816 return -1; 1817 } 1818 1819 return sum; 1820 } 1821 1822 /** 1823 * xmlTextWriterStartAttributeNS: 1824 * @writer: the xmlTextWriterPtr 1825 * @prefix: namespace prefix or NULL 1826 * @name: element local name 1827 * @namespaceURI: namespace URI or NULL 1828 * 1829 * Start an xml attribute with namespace support. 1830 * 1831 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 1832 */ 1833 int 1834 xmlTextWriterStartAttributeNS(xmlTextWriterPtr writer, 1835 const xmlChar * prefix, const xmlChar * name, 1836 const xmlChar * namespaceURI) 1837 { 1838 int count; 1839 int sum; 1840 xmlChar *buf; 1841 xmlTextWriterNsStackEntry *p; 1842 1843 if ((writer == NULL) || (name == NULL) || (*name == '\0')) 1844 return -1; 1845 1846 /* Handle namespace first in case of error */ 1847 if (namespaceURI != 0) { 1848 xmlTextWriterNsStackEntry nsentry, *curns; 1849 1850 buf = xmlStrdup(BAD_CAST "xmlns"); 1851 if (prefix != 0) { 1852 buf = xmlStrcat(buf, BAD_CAST ":"); 1853 buf = xmlStrcat(buf, prefix); 1854 } 1855 1856 nsentry.prefix = buf; 1857 nsentry.uri = (xmlChar *)namespaceURI; 1858 nsentry.elem = xmlListFront(writer->nodes); 1859 1860 curns = (xmlTextWriterNsStackEntry *)xmlListSearch(writer->nsstack, 1861 (void *)&nsentry); 1862 if ((curns != NULL)) { 1863 xmlFree(buf); 1864 if (xmlStrcmp(curns->uri, namespaceURI) == 0) { 1865 /* Namespace already defined on element skip */ 1866 buf = NULL; 1867 } else { 1868 /* Prefix mismatch so error out */ 1869 return -1; 1870 } 1871 } 1872 1873 /* Do not add namespace decl to list - it is already there */ 1874 if (buf != NULL) { 1875 p = (xmlTextWriterNsStackEntry *) 1876 xmlMalloc(sizeof(xmlTextWriterNsStackEntry)); 1877 if (p == 0) { 1878 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 1879 "xmlTextWriterStartAttributeNS : out of memory!\n"); 1880 return -1; 1881 } 1882 1883 p->prefix = buf; 1884 p->uri = xmlStrdup(namespaceURI); 1885 if (p->uri == 0) { 1886 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 1887 "xmlTextWriterStartAttributeNS : out of memory!\n"); 1888 xmlFree(p); 1889 return -1; 1890 } 1891 p->elem = xmlListFront(writer->nodes); 1892 1893 xmlListPushFront(writer->nsstack, p); 1894 } 1895 } 1896 1897 buf = NULL; 1898 if (prefix != 0) { 1899 buf = xmlStrdup(prefix); 1900 buf = xmlStrcat(buf, BAD_CAST ":"); 1901 } 1902 buf = xmlStrcat(buf, name); 1903 1904 sum = 0; 1905 count = xmlTextWriterStartAttribute(writer, buf); 1906 xmlFree(buf); 1907 if (count < 0) 1908 return -1; 1909 sum += count; 1910 1911 return sum; 1912 } 1913 1914 /** 1915 * xmlTextWriterEndAttribute: 1916 * @writer: the xmlTextWriterPtr 1917 * 1918 * End the current xml element. 1919 * 1920 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 1921 */ 1922 int 1923 xmlTextWriterEndAttribute(xmlTextWriterPtr writer) 1924 { 1925 int count; 1926 int sum; 1927 xmlLinkPtr lk; 1928 xmlTextWriterStackEntry *p; 1929 1930 if (writer == NULL) 1931 return -1; 1932 1933 lk = xmlListFront(writer->nodes); 1934 if (lk == 0) { 1935 return -1; 1936 } 1937 1938 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 1939 if (p == 0) { 1940 return -1; 1941 } 1942 1943 sum = 0; 1944 switch (p->state) { 1945 case XML_TEXTWRITER_ATTRIBUTE: 1946 p->state = XML_TEXTWRITER_NAME; 1947 1948 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 1949 if (count < 0) { 1950 return -1; 1951 } 1952 sum += count; 1953 break; 1954 default: 1955 return -1; 1956 } 1957 1958 return sum; 1959 } 1960 1961 /** 1962 * xmlTextWriterWriteFormatAttribute: 1963 * @writer: the xmlTextWriterPtr 1964 * @name: attribute name 1965 * @format: format string (see printf) 1966 * @...: extra parameters for the format 1967 * 1968 * Write a formatted xml attribute. 1969 * 1970 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 1971 */ 1972 int XMLCDECL 1973 xmlTextWriterWriteFormatAttribute(xmlTextWriterPtr writer, 1974 const xmlChar * name, const char *format, 1975 ...) 1976 { 1977 int rc; 1978 va_list ap; 1979 1980 va_start(ap, format); 1981 1982 rc = xmlTextWriterWriteVFormatAttribute(writer, name, format, ap); 1983 1984 va_end(ap); 1985 return rc; 1986 } 1987 1988 /** 1989 * xmlTextWriterWriteVFormatAttribute: 1990 * @writer: the xmlTextWriterPtr 1991 * @name: attribute name 1992 * @format: format string (see printf) 1993 * @argptr: pointer to the first member of the variable argument list. 1994 * 1995 * Write a formatted xml attribute. 1996 * 1997 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 1998 */ 1999 int 2000 xmlTextWriterWriteVFormatAttribute(xmlTextWriterPtr writer, 2001 const xmlChar * name, 2002 const char *format, va_list argptr) 2003 { 2004 int rc; 2005 xmlChar *buf; 2006 2007 if (writer == NULL) 2008 return -1; 2009 2010 buf = xmlTextWriterVSprintf(format, argptr); 2011 if (buf == NULL) 2012 return -1; 2013 2014 rc = xmlTextWriterWriteAttribute(writer, name, buf); 2015 2016 xmlFree(buf); 2017 return rc; 2018 } 2019 2020 /** 2021 * xmlTextWriterWriteAttribute: 2022 * @writer: the xmlTextWriterPtr 2023 * @name: attribute name 2024 * @content: attribute content 2025 * 2026 * Write an xml attribute. 2027 * 2028 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2029 */ 2030 int 2031 xmlTextWriterWriteAttribute(xmlTextWriterPtr writer, const xmlChar * name, 2032 const xmlChar * content) 2033 { 2034 int count; 2035 int sum; 2036 2037 sum = 0; 2038 count = xmlTextWriterStartAttribute(writer, name); 2039 if (count < 0) 2040 return -1; 2041 sum += count; 2042 count = xmlTextWriterWriteString(writer, content); 2043 if (count < 0) 2044 return -1; 2045 sum += count; 2046 count = xmlTextWriterEndAttribute(writer); 2047 if (count < 0) 2048 return -1; 2049 sum += count; 2050 2051 return sum; 2052 } 2053 2054 /** 2055 * xmlTextWriterWriteFormatAttributeNS: 2056 * @writer: the xmlTextWriterPtr 2057 * @prefix: namespace prefix 2058 * @name: attribute local name 2059 * @namespaceURI: namespace URI 2060 * @format: format string (see printf) 2061 * @...: extra parameters for the format 2062 * 2063 * Write a formatted xml attribute.with namespace support 2064 * 2065 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2066 */ 2067 int XMLCDECL 2068 xmlTextWriterWriteFormatAttributeNS(xmlTextWriterPtr writer, 2069 const xmlChar * prefix, 2070 const xmlChar * name, 2071 const xmlChar * namespaceURI, 2072 const char *format, ...) 2073 { 2074 int rc; 2075 va_list ap; 2076 2077 va_start(ap, format); 2078 2079 rc = xmlTextWriterWriteVFormatAttributeNS(writer, prefix, name, 2080 namespaceURI, format, ap); 2081 2082 va_end(ap); 2083 return rc; 2084 } 2085 2086 /** 2087 * xmlTextWriterWriteVFormatAttributeNS: 2088 * @writer: the xmlTextWriterPtr 2089 * @prefix: namespace prefix 2090 * @name: attribute local name 2091 * @namespaceURI: namespace URI 2092 * @format: format string (see printf) 2093 * @argptr: pointer to the first member of the variable argument list. 2094 * 2095 * Write a formatted xml attribute.with namespace support 2096 * 2097 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2098 */ 2099 int 2100 xmlTextWriterWriteVFormatAttributeNS(xmlTextWriterPtr writer, 2101 const xmlChar * prefix, 2102 const xmlChar * name, 2103 const xmlChar * namespaceURI, 2104 const char *format, va_list argptr) 2105 { 2106 int rc; 2107 xmlChar *buf; 2108 2109 if (writer == NULL) 2110 return -1; 2111 2112 buf = xmlTextWriterVSprintf(format, argptr); 2113 if (buf == NULL) 2114 return -1; 2115 2116 rc = xmlTextWriterWriteAttributeNS(writer, prefix, name, namespaceURI, 2117 buf); 2118 2119 xmlFree(buf); 2120 return rc; 2121 } 2122 2123 /** 2124 * xmlTextWriterWriteAttributeNS: 2125 * @writer: the xmlTextWriterPtr 2126 * @prefix: namespace prefix 2127 * @name: attribute local name 2128 * @namespaceURI: namespace URI 2129 * @content: attribute content 2130 * 2131 * Write an xml attribute. 2132 * 2133 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2134 */ 2135 int 2136 xmlTextWriterWriteAttributeNS(xmlTextWriterPtr writer, 2137 const xmlChar * prefix, const xmlChar * name, 2138 const xmlChar * namespaceURI, 2139 const xmlChar * content) 2140 { 2141 int count; 2142 int sum; 2143 2144 if ((writer == NULL) || (name == NULL) || (*name == '\0')) 2145 return -1; 2146 2147 sum = 0; 2148 count = xmlTextWriterStartAttributeNS(writer, prefix, name, namespaceURI); 2149 if (count < 0) 2150 return -1; 2151 sum += count; 2152 count = xmlTextWriterWriteString(writer, content); 2153 if (count < 0) 2154 return -1; 2155 sum += count; 2156 count = xmlTextWriterEndAttribute(writer); 2157 if (count < 0) 2158 return -1; 2159 sum += count; 2160 2161 return sum; 2162 } 2163 2164 /** 2165 * xmlTextWriterWriteFormatElement: 2166 * @writer: the xmlTextWriterPtr 2167 * @name: element name 2168 * @format: format string (see printf) 2169 * @...: extra parameters for the format 2170 * 2171 * Write a formatted xml element. 2172 * 2173 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2174 */ 2175 int XMLCDECL 2176 xmlTextWriterWriteFormatElement(xmlTextWriterPtr writer, 2177 const xmlChar * name, const char *format, 2178 ...) 2179 { 2180 int rc; 2181 va_list ap; 2182 2183 va_start(ap, format); 2184 2185 rc = xmlTextWriterWriteVFormatElement(writer, name, format, ap); 2186 2187 va_end(ap); 2188 return rc; 2189 } 2190 2191 /** 2192 * xmlTextWriterWriteVFormatElement: 2193 * @writer: the xmlTextWriterPtr 2194 * @name: element name 2195 * @format: format string (see printf) 2196 * @argptr: pointer to the first member of the variable argument list. 2197 * 2198 * Write a formatted xml element. 2199 * 2200 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2201 */ 2202 int 2203 xmlTextWriterWriteVFormatElement(xmlTextWriterPtr writer, 2204 const xmlChar * name, const char *format, 2205 va_list argptr) 2206 { 2207 int rc; 2208 xmlChar *buf; 2209 2210 if (writer == NULL) 2211 return -1; 2212 2213 buf = xmlTextWriterVSprintf(format, argptr); 2214 if (buf == NULL) 2215 return -1; 2216 2217 rc = xmlTextWriterWriteElement(writer, name, buf); 2218 2219 xmlFree(buf); 2220 return rc; 2221 } 2222 2223 /** 2224 * xmlTextWriterWriteElement: 2225 * @writer: the xmlTextWriterPtr 2226 * @name: element name 2227 * @content: element content 2228 * 2229 * Write an xml element. 2230 * 2231 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2232 */ 2233 int 2234 xmlTextWriterWriteElement(xmlTextWriterPtr writer, const xmlChar * name, 2235 const xmlChar * content) 2236 { 2237 int count; 2238 int sum; 2239 2240 sum = 0; 2241 count = xmlTextWriterStartElement(writer, name); 2242 if (count == -1) 2243 return -1; 2244 sum += count; 2245 if (content != NULL) { 2246 count = xmlTextWriterWriteString(writer, content); 2247 if (count == -1) 2248 return -1; 2249 sum += count; 2250 } 2251 count = xmlTextWriterEndElement(writer); 2252 if (count == -1) 2253 return -1; 2254 sum += count; 2255 2256 return sum; 2257 } 2258 2259 /** 2260 * xmlTextWriterWriteFormatElementNS: 2261 * @writer: the xmlTextWriterPtr 2262 * @prefix: namespace prefix 2263 * @name: element local name 2264 * @namespaceURI: namespace URI 2265 * @format: format string (see printf) 2266 * @...: extra parameters for the format 2267 * 2268 * Write a formatted xml element with namespace support. 2269 * 2270 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2271 */ 2272 int XMLCDECL 2273 xmlTextWriterWriteFormatElementNS(xmlTextWriterPtr writer, 2274 const xmlChar * prefix, 2275 const xmlChar * name, 2276 const xmlChar * namespaceURI, 2277 const char *format, ...) 2278 { 2279 int rc; 2280 va_list ap; 2281 2282 va_start(ap, format); 2283 2284 rc = xmlTextWriterWriteVFormatElementNS(writer, prefix, name, 2285 namespaceURI, format, ap); 2286 2287 va_end(ap); 2288 return rc; 2289 } 2290 2291 /** 2292 * xmlTextWriterWriteVFormatElementNS: 2293 * @writer: the xmlTextWriterPtr 2294 * @prefix: namespace prefix 2295 * @name: element local name 2296 * @namespaceURI: namespace URI 2297 * @format: format string (see printf) 2298 * @argptr: pointer to the first member of the variable argument list. 2299 * 2300 * Write a formatted xml element with namespace support. 2301 * 2302 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2303 */ 2304 int 2305 xmlTextWriterWriteVFormatElementNS(xmlTextWriterPtr writer, 2306 const xmlChar * prefix, 2307 const xmlChar * name, 2308 const xmlChar * namespaceURI, 2309 const char *format, va_list argptr) 2310 { 2311 int rc; 2312 xmlChar *buf; 2313 2314 if (writer == NULL) 2315 return -1; 2316 2317 buf = xmlTextWriterVSprintf(format, argptr); 2318 if (buf == NULL) 2319 return -1; 2320 2321 rc = xmlTextWriterWriteElementNS(writer, prefix, name, namespaceURI, 2322 buf); 2323 2324 xmlFree(buf); 2325 return rc; 2326 } 2327 2328 /** 2329 * xmlTextWriterWriteElementNS: 2330 * @writer: the xmlTextWriterPtr 2331 * @prefix: namespace prefix 2332 * @name: element local name 2333 * @namespaceURI: namespace URI 2334 * @content: element content 2335 * 2336 * Write an xml element with namespace support. 2337 * 2338 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2339 */ 2340 int 2341 xmlTextWriterWriteElementNS(xmlTextWriterPtr writer, 2342 const xmlChar * prefix, const xmlChar * name, 2343 const xmlChar * namespaceURI, 2344 const xmlChar * content) 2345 { 2346 int count; 2347 int sum; 2348 2349 if ((writer == NULL) || (name == NULL) || (*name == '\0')) 2350 return -1; 2351 2352 sum = 0; 2353 count = 2354 xmlTextWriterStartElementNS(writer, prefix, name, namespaceURI); 2355 if (count < 0) 2356 return -1; 2357 sum += count; 2358 count = xmlTextWriterWriteString(writer, content); 2359 if (count == -1) 2360 return -1; 2361 sum += count; 2362 count = xmlTextWriterEndElement(writer); 2363 if (count == -1) 2364 return -1; 2365 sum += count; 2366 2367 return sum; 2368 } 2369 2370 /** 2371 * xmlTextWriterStartPI: 2372 * @writer: the xmlTextWriterPtr 2373 * @target: PI target 2374 * 2375 * Start an xml PI. 2376 * 2377 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2378 */ 2379 int 2380 xmlTextWriterStartPI(xmlTextWriterPtr writer, const xmlChar * target) 2381 { 2382 int count; 2383 int sum; 2384 xmlLinkPtr lk; 2385 xmlTextWriterStackEntry *p; 2386 2387 if ((writer == NULL) || (target == NULL) || (*target == '\0')) 2388 return -1; 2389 2390 if (xmlStrcasecmp(target, (const xmlChar *) "xml") == 0) { 2391 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 2392 "xmlTextWriterStartPI : target name [Xx][Mm][Ll] is reserved for xml standardization!\n"); 2393 return -1; 2394 } 2395 2396 sum = 0; 2397 lk = xmlListFront(writer->nodes); 2398 if (lk != 0) { 2399 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 2400 if (p != 0) { 2401 switch (p->state) { 2402 case XML_TEXTWRITER_ATTRIBUTE: 2403 count = xmlTextWriterEndAttribute(writer); 2404 if (count < 0) 2405 return -1; 2406 sum += count; 2407 /* fallthrough */ 2408 case XML_TEXTWRITER_NAME: 2409 /* Output namespace declarations */ 2410 count = xmlTextWriterOutputNSDecl(writer); 2411 if (count < 0) 2412 return -1; 2413 sum += count; 2414 count = xmlOutputBufferWriteString(writer->out, ">"); 2415 if (count < 0) 2416 return -1; 2417 sum += count; 2418 p->state = XML_TEXTWRITER_TEXT; 2419 break; 2420 case XML_TEXTWRITER_NONE: 2421 case XML_TEXTWRITER_TEXT: 2422 case XML_TEXTWRITER_DTD: 2423 break; 2424 case XML_TEXTWRITER_PI: 2425 case XML_TEXTWRITER_PI_TEXT: 2426 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 2427 "xmlTextWriterStartPI : nested PI!\n"); 2428 return -1; 2429 default: 2430 return -1; 2431 } 2432 } 2433 } 2434 2435 p = (xmlTextWriterStackEntry *) 2436 xmlMalloc(sizeof(xmlTextWriterStackEntry)); 2437 if (p == 0) { 2438 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 2439 "xmlTextWriterStartPI : out of memory!\n"); 2440 return -1; 2441 } 2442 2443 p->name = xmlStrdup(target); 2444 if (p->name == 0) { 2445 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 2446 "xmlTextWriterStartPI : out of memory!\n"); 2447 xmlFree(p); 2448 return -1; 2449 } 2450 p->state = XML_TEXTWRITER_PI; 2451 2452 xmlListPushFront(writer->nodes, p); 2453 2454 count = xmlOutputBufferWriteString(writer->out, "<?"); 2455 if (count < 0) 2456 return -1; 2457 sum += count; 2458 count = 2459 xmlOutputBufferWriteString(writer->out, (const char *) p->name); 2460 if (count < 0) 2461 return -1; 2462 sum += count; 2463 2464 return sum; 2465 } 2466 2467 /** 2468 * xmlTextWriterEndPI: 2469 * @writer: the xmlTextWriterPtr 2470 * 2471 * End the current xml PI. 2472 * 2473 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2474 */ 2475 int 2476 xmlTextWriterEndPI(xmlTextWriterPtr writer) 2477 { 2478 int count; 2479 int sum; 2480 xmlLinkPtr lk; 2481 xmlTextWriterStackEntry *p; 2482 2483 if (writer == NULL) 2484 return -1; 2485 2486 lk = xmlListFront(writer->nodes); 2487 if (lk == 0) 2488 return 0; 2489 2490 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 2491 if (p == 0) 2492 return 0; 2493 2494 sum = 0; 2495 switch (p->state) { 2496 case XML_TEXTWRITER_PI: 2497 case XML_TEXTWRITER_PI_TEXT: 2498 count = xmlOutputBufferWriteString(writer->out, "?>"); 2499 if (count < 0) 2500 return -1; 2501 sum += count; 2502 break; 2503 default: 2504 return -1; 2505 } 2506 2507 if (writer->indent) { 2508 count = xmlOutputBufferWriteString(writer->out, "\n"); 2509 if (count < 0) 2510 return -1; 2511 sum += count; 2512 } 2513 2514 xmlListPopFront(writer->nodes); 2515 return sum; 2516 } 2517 2518 /** 2519 * xmlTextWriterWriteFormatPI: 2520 * @writer: the xmlTextWriterPtr 2521 * @target: PI target 2522 * @format: format string (see printf) 2523 * @...: extra parameters for the format 2524 * 2525 * Write a formatted PI. 2526 * 2527 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2528 */ 2529 int XMLCDECL 2530 xmlTextWriterWriteFormatPI(xmlTextWriterPtr writer, const xmlChar * target, 2531 const char *format, ...) 2532 { 2533 int rc; 2534 va_list ap; 2535 2536 va_start(ap, format); 2537 2538 rc = xmlTextWriterWriteVFormatPI(writer, target, format, ap); 2539 2540 va_end(ap); 2541 return rc; 2542 } 2543 2544 /** 2545 * xmlTextWriterWriteVFormatPI: 2546 * @writer: the xmlTextWriterPtr 2547 * @target: PI target 2548 * @format: format string (see printf) 2549 * @argptr: pointer to the first member of the variable argument list. 2550 * 2551 * Write a formatted xml PI. 2552 * 2553 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2554 */ 2555 int 2556 xmlTextWriterWriteVFormatPI(xmlTextWriterPtr writer, 2557 const xmlChar * target, const char *format, 2558 va_list argptr) 2559 { 2560 int rc; 2561 xmlChar *buf; 2562 2563 if (writer == NULL) 2564 return -1; 2565 2566 buf = xmlTextWriterVSprintf(format, argptr); 2567 if (buf == NULL) 2568 return -1; 2569 2570 rc = xmlTextWriterWritePI(writer, target, buf); 2571 2572 xmlFree(buf); 2573 return rc; 2574 } 2575 2576 /** 2577 * xmlTextWriterWritePI: 2578 * @writer: the xmlTextWriterPtr 2579 * @target: PI target 2580 * @content: PI content 2581 * 2582 * Write an xml PI. 2583 * 2584 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2585 */ 2586 int 2587 xmlTextWriterWritePI(xmlTextWriterPtr writer, const xmlChar * target, 2588 const xmlChar * content) 2589 { 2590 int count; 2591 int sum; 2592 2593 sum = 0; 2594 count = xmlTextWriterStartPI(writer, target); 2595 if (count == -1) 2596 return -1; 2597 sum += count; 2598 if (content != 0) { 2599 count = xmlTextWriterWriteString(writer, content); 2600 if (count == -1) 2601 return -1; 2602 sum += count; 2603 } 2604 count = xmlTextWriterEndPI(writer); 2605 if (count == -1) 2606 return -1; 2607 sum += count; 2608 2609 return sum; 2610 } 2611 2612 /** 2613 * xmlTextWriterStartCDATA: 2614 * @writer: the xmlTextWriterPtr 2615 * 2616 * Start an xml CDATA section. 2617 * 2618 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2619 */ 2620 int 2621 xmlTextWriterStartCDATA(xmlTextWriterPtr writer) 2622 { 2623 int count; 2624 int sum; 2625 xmlLinkPtr lk; 2626 xmlTextWriterStackEntry *p; 2627 2628 if (writer == NULL) 2629 return -1; 2630 2631 sum = 0; 2632 lk = xmlListFront(writer->nodes); 2633 if (lk != 0) { 2634 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 2635 if (p != 0) { 2636 switch (p->state) { 2637 case XML_TEXTWRITER_NONE: 2638 case XML_TEXTWRITER_TEXT: 2639 case XML_TEXTWRITER_PI: 2640 case XML_TEXTWRITER_PI_TEXT: 2641 break; 2642 case XML_TEXTWRITER_ATTRIBUTE: 2643 count = xmlTextWriterEndAttribute(writer); 2644 if (count < 0) 2645 return -1; 2646 sum += count; 2647 /* fallthrough */ 2648 case XML_TEXTWRITER_NAME: 2649 /* Output namespace declarations */ 2650 count = xmlTextWriterOutputNSDecl(writer); 2651 if (count < 0) 2652 return -1; 2653 sum += count; 2654 count = xmlOutputBufferWriteString(writer->out, ">"); 2655 if (count < 0) 2656 return -1; 2657 sum += count; 2658 p->state = XML_TEXTWRITER_TEXT; 2659 break; 2660 case XML_TEXTWRITER_CDATA: 2661 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 2662 "xmlTextWriterStartCDATA : CDATA not allowed in this context!\n"); 2663 return -1; 2664 default: 2665 return -1; 2666 } 2667 } 2668 } 2669 2670 p = (xmlTextWriterStackEntry *) 2671 xmlMalloc(sizeof(xmlTextWriterStackEntry)); 2672 if (p == 0) { 2673 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 2674 "xmlTextWriterStartCDATA : out of memory!\n"); 2675 return -1; 2676 } 2677 2678 p->name = NULL; 2679 p->state = XML_TEXTWRITER_CDATA; 2680 2681 xmlListPushFront(writer->nodes, p); 2682 2683 count = xmlOutputBufferWriteString(writer->out, "<![CDATA["); 2684 if (count < 0) 2685 return -1; 2686 sum += count; 2687 2688 return sum; 2689 } 2690 2691 /** 2692 * xmlTextWriterEndCDATA: 2693 * @writer: the xmlTextWriterPtr 2694 * 2695 * End an xml CDATA section. 2696 * 2697 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2698 */ 2699 int 2700 xmlTextWriterEndCDATA(xmlTextWriterPtr writer) 2701 { 2702 int count; 2703 int sum; 2704 xmlLinkPtr lk; 2705 xmlTextWriterStackEntry *p; 2706 2707 if (writer == NULL) 2708 return -1; 2709 2710 lk = xmlListFront(writer->nodes); 2711 if (lk == 0) 2712 return -1; 2713 2714 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 2715 if (p == 0) 2716 return -1; 2717 2718 sum = 0; 2719 switch (p->state) { 2720 case XML_TEXTWRITER_CDATA: 2721 count = xmlOutputBufferWriteString(writer->out, "]]>"); 2722 if (count < 0) 2723 return -1; 2724 sum += count; 2725 break; 2726 default: 2727 return -1; 2728 } 2729 2730 xmlListPopFront(writer->nodes); 2731 return sum; 2732 } 2733 2734 /** 2735 * xmlTextWriterWriteFormatCDATA: 2736 * @writer: the xmlTextWriterPtr 2737 * @format: format string (see printf) 2738 * @...: extra parameters for the format 2739 * 2740 * Write a formatted xml CDATA. 2741 * 2742 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2743 */ 2744 int XMLCDECL 2745 xmlTextWriterWriteFormatCDATA(xmlTextWriterPtr writer, const char *format, 2746 ...) 2747 { 2748 int rc; 2749 va_list ap; 2750 2751 va_start(ap, format); 2752 2753 rc = xmlTextWriterWriteVFormatCDATA(writer, format, ap); 2754 2755 va_end(ap); 2756 return rc; 2757 } 2758 2759 /** 2760 * xmlTextWriterWriteVFormatCDATA: 2761 * @writer: the xmlTextWriterPtr 2762 * @format: format string (see printf) 2763 * @argptr: pointer to the first member of the variable argument list. 2764 * 2765 * Write a formatted xml CDATA. 2766 * 2767 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2768 */ 2769 int 2770 xmlTextWriterWriteVFormatCDATA(xmlTextWriterPtr writer, const char *format, 2771 va_list argptr) 2772 { 2773 int rc; 2774 xmlChar *buf; 2775 2776 if (writer == NULL) 2777 return -1; 2778 2779 buf = xmlTextWriterVSprintf(format, argptr); 2780 if (buf == NULL) 2781 return -1; 2782 2783 rc = xmlTextWriterWriteCDATA(writer, buf); 2784 2785 xmlFree(buf); 2786 return rc; 2787 } 2788 2789 /** 2790 * xmlTextWriterWriteCDATA: 2791 * @writer: the xmlTextWriterPtr 2792 * @content: CDATA content 2793 * 2794 * Write an xml CDATA. 2795 * 2796 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2797 */ 2798 int 2799 xmlTextWriterWriteCDATA(xmlTextWriterPtr writer, const xmlChar * content) 2800 { 2801 int count; 2802 int sum; 2803 2804 sum = 0; 2805 count = xmlTextWriterStartCDATA(writer); 2806 if (count == -1) 2807 return -1; 2808 sum += count; 2809 if (content != 0) { 2810 count = xmlTextWriterWriteString(writer, content); 2811 if (count == -1) 2812 return -1; 2813 sum += count; 2814 } 2815 count = xmlTextWriterEndCDATA(writer); 2816 if (count == -1) 2817 return -1; 2818 sum += count; 2819 2820 return sum; 2821 } 2822 2823 /** 2824 * xmlTextWriterStartDTD: 2825 * @writer: the xmlTextWriterPtr 2826 * @name: the name of the DTD 2827 * @pubid: the public identifier, which is an alternative to the system identifier 2828 * @sysid: the system identifier, which is the URI of the DTD 2829 * 2830 * Start an xml DTD. 2831 * 2832 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2833 */ 2834 int 2835 xmlTextWriterStartDTD(xmlTextWriterPtr writer, 2836 const xmlChar * name, 2837 const xmlChar * pubid, const xmlChar * sysid) 2838 { 2839 int count; 2840 int sum; 2841 xmlLinkPtr lk; 2842 xmlTextWriterStackEntry *p; 2843 2844 if (writer == NULL || name == NULL || *name == '\0') 2845 return -1; 2846 2847 sum = 0; 2848 lk = xmlListFront(writer->nodes); 2849 if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) { 2850 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 2851 "xmlTextWriterStartDTD : DTD allowed only in prolog!\n"); 2852 return -1; 2853 } 2854 2855 p = (xmlTextWriterStackEntry *) 2856 xmlMalloc(sizeof(xmlTextWriterStackEntry)); 2857 if (p == 0) { 2858 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 2859 "xmlTextWriterStartDTD : out of memory!\n"); 2860 return -1; 2861 } 2862 2863 p->name = xmlStrdup(name); 2864 if (p->name == 0) { 2865 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 2866 "xmlTextWriterStartDTD : out of memory!\n"); 2867 xmlFree(p); 2868 return -1; 2869 } 2870 p->state = XML_TEXTWRITER_DTD; 2871 2872 xmlListPushFront(writer->nodes, p); 2873 2874 count = xmlOutputBufferWriteString(writer->out, "<!DOCTYPE "); 2875 if (count < 0) 2876 return -1; 2877 sum += count; 2878 count = xmlOutputBufferWriteString(writer->out, (const char *) name); 2879 if (count < 0) 2880 return -1; 2881 sum += count; 2882 2883 if (pubid != 0) { 2884 if (sysid == 0) { 2885 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 2886 "xmlTextWriterStartDTD : system identifier needed!\n"); 2887 return -1; 2888 } 2889 2890 if (writer->indent) 2891 count = xmlOutputBufferWrite(writer->out, 1, "\n"); 2892 else 2893 count = xmlOutputBufferWrite(writer->out, 1, " "); 2894 if (count < 0) 2895 return -1; 2896 sum += count; 2897 2898 count = xmlOutputBufferWriteString(writer->out, "PUBLIC "); 2899 if (count < 0) 2900 return -1; 2901 sum += count; 2902 2903 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 2904 if (count < 0) 2905 return -1; 2906 sum += count; 2907 2908 count = 2909 xmlOutputBufferWriteString(writer->out, (const char *) pubid); 2910 if (count < 0) 2911 return -1; 2912 sum += count; 2913 2914 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 2915 if (count < 0) 2916 return -1; 2917 sum += count; 2918 } 2919 2920 if (sysid != 0) { 2921 if (pubid == 0) { 2922 if (writer->indent) 2923 count = xmlOutputBufferWrite(writer->out, 1, "\n"); 2924 else 2925 count = xmlOutputBufferWrite(writer->out, 1, " "); 2926 if (count < 0) 2927 return -1; 2928 sum += count; 2929 count = xmlOutputBufferWriteString(writer->out, "SYSTEM "); 2930 if (count < 0) 2931 return -1; 2932 sum += count; 2933 } else { 2934 if (writer->indent) 2935 count = xmlOutputBufferWriteString(writer->out, "\n "); 2936 else 2937 count = xmlOutputBufferWrite(writer->out, 1, " "); 2938 if (count < 0) 2939 return -1; 2940 sum += count; 2941 } 2942 2943 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 2944 if (count < 0) 2945 return -1; 2946 sum += count; 2947 2948 count = 2949 xmlOutputBufferWriteString(writer->out, (const char *) sysid); 2950 if (count < 0) 2951 return -1; 2952 sum += count; 2953 2954 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 2955 if (count < 0) 2956 return -1; 2957 sum += count; 2958 } 2959 2960 return sum; 2961 } 2962 2963 /** 2964 * xmlTextWriterEndDTD: 2965 * @writer: the xmlTextWriterPtr 2966 * 2967 * End an xml DTD. 2968 * 2969 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2970 */ 2971 int 2972 xmlTextWriterEndDTD(xmlTextWriterPtr writer) 2973 { 2974 int loop; 2975 int count; 2976 int sum; 2977 xmlLinkPtr lk; 2978 xmlTextWriterStackEntry *p; 2979 2980 if (writer == NULL) 2981 return -1; 2982 2983 sum = 0; 2984 loop = 1; 2985 while (loop) { 2986 lk = xmlListFront(writer->nodes); 2987 if (lk == NULL) 2988 break; 2989 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 2990 if (p == 0) 2991 break; 2992 switch (p->state) { 2993 case XML_TEXTWRITER_DTD_TEXT: 2994 count = xmlOutputBufferWriteString(writer->out, "]"); 2995 if (count < 0) 2996 return -1; 2997 sum += count; 2998 /* fallthrough */ 2999 case XML_TEXTWRITER_DTD: 3000 count = xmlOutputBufferWriteString(writer->out, ">"); 3001 3002 if (writer->indent) { 3003 if (count < 0) 3004 return -1; 3005 sum += count; 3006 count = xmlOutputBufferWriteString(writer->out, "\n"); 3007 } 3008 3009 xmlListPopFront(writer->nodes); 3010 break; 3011 case XML_TEXTWRITER_DTD_ELEM: 3012 case XML_TEXTWRITER_DTD_ELEM_TEXT: 3013 count = xmlTextWriterEndDTDElement(writer); 3014 break; 3015 case XML_TEXTWRITER_DTD_ATTL: 3016 case XML_TEXTWRITER_DTD_ATTL_TEXT: 3017 count = xmlTextWriterEndDTDAttlist(writer); 3018 break; 3019 case XML_TEXTWRITER_DTD_ENTY: 3020 case XML_TEXTWRITER_DTD_PENT: 3021 case XML_TEXTWRITER_DTD_ENTY_TEXT: 3022 count = xmlTextWriterEndDTDEntity(writer); 3023 break; 3024 case XML_TEXTWRITER_COMMENT: 3025 count = xmlTextWriterEndComment(writer); 3026 break; 3027 default: 3028 loop = 0; 3029 continue; 3030 } 3031 3032 if (count < 0) 3033 return -1; 3034 sum += count; 3035 } 3036 3037 return sum; 3038 } 3039 3040 /** 3041 * xmlTextWriterWriteFormatDTD: 3042 * @writer: the xmlTextWriterPtr 3043 * @name: the name of the DTD 3044 * @pubid: the public identifier, which is an alternative to the system identifier 3045 * @sysid: the system identifier, which is the URI of the DTD 3046 * @format: format string (see printf) 3047 * @...: extra parameters for the format 3048 * 3049 * Write a DTD with a formatted markup declarations part. 3050 * 3051 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3052 */ 3053 int XMLCDECL 3054 xmlTextWriterWriteFormatDTD(xmlTextWriterPtr writer, 3055 const xmlChar * name, 3056 const xmlChar * pubid, 3057 const xmlChar * sysid, const char *format, ...) 3058 { 3059 int rc; 3060 va_list ap; 3061 3062 va_start(ap, format); 3063 3064 rc = xmlTextWriterWriteVFormatDTD(writer, name, pubid, sysid, format, 3065 ap); 3066 3067 va_end(ap); 3068 return rc; 3069 } 3070 3071 /** 3072 * xmlTextWriterWriteVFormatDTD: 3073 * @writer: the xmlTextWriterPtr 3074 * @name: the name of the DTD 3075 * @pubid: the public identifier, which is an alternative to the system identifier 3076 * @sysid: the system identifier, which is the URI of the DTD 3077 * @format: format string (see printf) 3078 * @argptr: pointer to the first member of the variable argument list. 3079 * 3080 * Write a DTD with a formatted markup declarations part. 3081 * 3082 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3083 */ 3084 int 3085 xmlTextWriterWriteVFormatDTD(xmlTextWriterPtr writer, 3086 const xmlChar * name, 3087 const xmlChar * pubid, 3088 const xmlChar * sysid, 3089 const char *format, va_list argptr) 3090 { 3091 int rc; 3092 xmlChar *buf; 3093 3094 if (writer == NULL) 3095 return -1; 3096 3097 buf = xmlTextWriterVSprintf(format, argptr); 3098 if (buf == NULL) 3099 return -1; 3100 3101 rc = xmlTextWriterWriteDTD(writer, name, pubid, sysid, buf); 3102 3103 xmlFree(buf); 3104 return rc; 3105 } 3106 3107 /** 3108 * xmlTextWriterWriteDTD: 3109 * @writer: the xmlTextWriterPtr 3110 * @name: the name of the DTD 3111 * @pubid: the public identifier, which is an alternative to the system identifier 3112 * @sysid: the system identifier, which is the URI of the DTD 3113 * @subset: string content of the DTD 3114 * 3115 * Write a DTD. 3116 * 3117 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3118 */ 3119 int 3120 xmlTextWriterWriteDTD(xmlTextWriterPtr writer, 3121 const xmlChar * name, 3122 const xmlChar * pubid, 3123 const xmlChar * sysid, const xmlChar * subset) 3124 { 3125 int count; 3126 int sum; 3127 3128 sum = 0; 3129 count = xmlTextWriterStartDTD(writer, name, pubid, sysid); 3130 if (count == -1) 3131 return -1; 3132 sum += count; 3133 if (subset != 0) { 3134 count = xmlTextWriterWriteString(writer, subset); 3135 if (count == -1) 3136 return -1; 3137 sum += count; 3138 } 3139 count = xmlTextWriterEndDTD(writer); 3140 if (count == -1) 3141 return -1; 3142 sum += count; 3143 3144 return sum; 3145 } 3146 3147 /** 3148 * xmlTextWriterStartDTDElement: 3149 * @writer: the xmlTextWriterPtr 3150 * @name: the name of the DTD element 3151 * 3152 * Start an xml DTD element. 3153 * 3154 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3155 */ 3156 int 3157 xmlTextWriterStartDTDElement(xmlTextWriterPtr writer, const xmlChar * name) 3158 { 3159 int count; 3160 int sum; 3161 xmlLinkPtr lk; 3162 xmlTextWriterStackEntry *p; 3163 3164 if (writer == NULL || name == NULL || *name == '\0') 3165 return -1; 3166 3167 sum = 0; 3168 lk = xmlListFront(writer->nodes); 3169 if (lk == 0) { 3170 return -1; 3171 } 3172 3173 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 3174 if (p != 0) { 3175 switch (p->state) { 3176 case XML_TEXTWRITER_DTD: 3177 count = xmlOutputBufferWriteString(writer->out, " ["); 3178 if (count < 0) 3179 return -1; 3180 sum += count; 3181 if (writer->indent) { 3182 count = xmlOutputBufferWriteString(writer->out, "\n"); 3183 if (count < 0) 3184 return -1; 3185 sum += count; 3186 } 3187 p->state = XML_TEXTWRITER_DTD_TEXT; 3188 /* fallthrough */ 3189 case XML_TEXTWRITER_DTD_TEXT: 3190 case XML_TEXTWRITER_NONE: 3191 break; 3192 default: 3193 return -1; 3194 } 3195 } 3196 3197 p = (xmlTextWriterStackEntry *) 3198 xmlMalloc(sizeof(xmlTextWriterStackEntry)); 3199 if (p == 0) { 3200 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 3201 "xmlTextWriterStartDTDElement : out of memory!\n"); 3202 return -1; 3203 } 3204 3205 p->name = xmlStrdup(name); 3206 if (p->name == 0) { 3207 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 3208 "xmlTextWriterStartDTDElement : out of memory!\n"); 3209 xmlFree(p); 3210 return -1; 3211 } 3212 p->state = XML_TEXTWRITER_DTD_ELEM; 3213 3214 xmlListPushFront(writer->nodes, p); 3215 3216 if (writer->indent) { 3217 count = xmlTextWriterWriteIndent(writer); 3218 if (count < 0) 3219 return -1; 3220 sum += count; 3221 } 3222 3223 count = xmlOutputBufferWriteString(writer->out, "<!ELEMENT "); 3224 if (count < 0) 3225 return -1; 3226 sum += count; 3227 count = xmlOutputBufferWriteString(writer->out, (const char *) name); 3228 if (count < 0) 3229 return -1; 3230 sum += count; 3231 3232 return sum; 3233 } 3234 3235 /** 3236 * xmlTextWriterEndDTDElement: 3237 * @writer: the xmlTextWriterPtr 3238 * 3239 * End an xml DTD element. 3240 * 3241 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3242 */ 3243 int 3244 xmlTextWriterEndDTDElement(xmlTextWriterPtr writer) 3245 { 3246 int count; 3247 int sum; 3248 xmlLinkPtr lk; 3249 xmlTextWriterStackEntry *p; 3250 3251 if (writer == NULL) 3252 return -1; 3253 3254 sum = 0; 3255 lk = xmlListFront(writer->nodes); 3256 if (lk == 0) 3257 return -1; 3258 3259 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 3260 if (p == 0) 3261 return -1; 3262 3263 switch (p->state) { 3264 case XML_TEXTWRITER_DTD_ELEM: 3265 case XML_TEXTWRITER_DTD_ELEM_TEXT: 3266 count = xmlOutputBufferWriteString(writer->out, ">"); 3267 if (count < 0) 3268 return -1; 3269 sum += count; 3270 break; 3271 default: 3272 return -1; 3273 } 3274 3275 if (writer->indent) { 3276 count = xmlOutputBufferWriteString(writer->out, "\n"); 3277 if (count < 0) 3278 return -1; 3279 sum += count; 3280 } 3281 3282 xmlListPopFront(writer->nodes); 3283 return sum; 3284 } 3285 3286 /** 3287 * xmlTextWriterWriteFormatDTDElement: 3288 * @writer: the xmlTextWriterPtr 3289 * @name: the name of the DTD element 3290 * @format: format string (see printf) 3291 * @...: extra parameters for the format 3292 * 3293 * Write a formatted DTD element. 3294 * 3295 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3296 */ 3297 int XMLCDECL 3298 xmlTextWriterWriteFormatDTDElement(xmlTextWriterPtr writer, 3299 const xmlChar * name, 3300 const char *format, ...) 3301 { 3302 int rc; 3303 va_list ap; 3304 3305 va_start(ap, format); 3306 3307 rc = xmlTextWriterWriteVFormatDTDElement(writer, name, format, ap); 3308 3309 va_end(ap); 3310 return rc; 3311 } 3312 3313 /** 3314 * xmlTextWriterWriteVFormatDTDElement: 3315 * @writer: the xmlTextWriterPtr 3316 * @name: the name of the DTD element 3317 * @format: format string (see printf) 3318 * @argptr: pointer to the first member of the variable argument list. 3319 * 3320 * Write a formatted DTD element. 3321 * 3322 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3323 */ 3324 int 3325 xmlTextWriterWriteVFormatDTDElement(xmlTextWriterPtr writer, 3326 const xmlChar * name, 3327 const char *format, va_list argptr) 3328 { 3329 int rc; 3330 xmlChar *buf; 3331 3332 if (writer == NULL) 3333 return -1; 3334 3335 buf = xmlTextWriterVSprintf(format, argptr); 3336 if (buf == NULL) 3337 return -1; 3338 3339 rc = xmlTextWriterWriteDTDElement(writer, name, buf); 3340 3341 xmlFree(buf); 3342 return rc; 3343 } 3344 3345 /** 3346 * xmlTextWriterWriteDTDElement: 3347 * @writer: the xmlTextWriterPtr 3348 * @name: the name of the DTD element 3349 * @content: content of the element 3350 * 3351 * Write a DTD element. 3352 * 3353 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3354 */ 3355 int 3356 xmlTextWriterWriteDTDElement(xmlTextWriterPtr writer, 3357 const xmlChar * name, const xmlChar * content) 3358 { 3359 int count; 3360 int sum; 3361 3362 if (content == NULL) 3363 return -1; 3364 3365 sum = 0; 3366 count = xmlTextWriterStartDTDElement(writer, name); 3367 if (count == -1) 3368 return -1; 3369 sum += count; 3370 3371 count = xmlTextWriterWriteString(writer, content); 3372 if (count == -1) 3373 return -1; 3374 sum += count; 3375 3376 count = xmlTextWriterEndDTDElement(writer); 3377 if (count == -1) 3378 return -1; 3379 sum += count; 3380 3381 return sum; 3382 } 3383 3384 /** 3385 * xmlTextWriterStartDTDAttlist: 3386 * @writer: the xmlTextWriterPtr 3387 * @name: the name of the DTD ATTLIST 3388 * 3389 * Start an xml DTD ATTLIST. 3390 * 3391 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3392 */ 3393 int 3394 xmlTextWriterStartDTDAttlist(xmlTextWriterPtr writer, const xmlChar * name) 3395 { 3396 int count; 3397 int sum; 3398 xmlLinkPtr lk; 3399 xmlTextWriterStackEntry *p; 3400 3401 if (writer == NULL || name == NULL || *name == '\0') 3402 return -1; 3403 3404 sum = 0; 3405 lk = xmlListFront(writer->nodes); 3406 if (lk == 0) { 3407 return -1; 3408 } 3409 3410 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 3411 if (p != 0) { 3412 switch (p->state) { 3413 case XML_TEXTWRITER_DTD: 3414 count = xmlOutputBufferWriteString(writer->out, " ["); 3415 if (count < 0) 3416 return -1; 3417 sum += count; 3418 if (writer->indent) { 3419 count = xmlOutputBufferWriteString(writer->out, "\n"); 3420 if (count < 0) 3421 return -1; 3422 sum += count; 3423 } 3424 p->state = XML_TEXTWRITER_DTD_TEXT; 3425 /* fallthrough */ 3426 case XML_TEXTWRITER_DTD_TEXT: 3427 case XML_TEXTWRITER_NONE: 3428 break; 3429 default: 3430 return -1; 3431 } 3432 } 3433 3434 p = (xmlTextWriterStackEntry *) 3435 xmlMalloc(sizeof(xmlTextWriterStackEntry)); 3436 if (p == 0) { 3437 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 3438 "xmlTextWriterStartDTDAttlist : out of memory!\n"); 3439 return -1; 3440 } 3441 3442 p->name = xmlStrdup(name); 3443 if (p->name == 0) { 3444 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 3445 "xmlTextWriterStartDTDAttlist : out of memory!\n"); 3446 xmlFree(p); 3447 return -1; 3448 } 3449 p->state = XML_TEXTWRITER_DTD_ATTL; 3450 3451 xmlListPushFront(writer->nodes, p); 3452 3453 if (writer->indent) { 3454 count = xmlTextWriterWriteIndent(writer); 3455 if (count < 0) 3456 return -1; 3457 sum += count; 3458 } 3459 3460 count = xmlOutputBufferWriteString(writer->out, "<!ATTLIST "); 3461 if (count < 0) 3462 return -1; 3463 sum += count; 3464 count = xmlOutputBufferWriteString(writer->out, (const char *) name); 3465 if (count < 0) 3466 return -1; 3467 sum += count; 3468 3469 return sum; 3470 } 3471 3472 /** 3473 * xmlTextWriterEndDTDAttlist: 3474 * @writer: the xmlTextWriterPtr 3475 * 3476 * End an xml DTD attribute list. 3477 * 3478 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3479 */ 3480 int 3481 xmlTextWriterEndDTDAttlist(xmlTextWriterPtr writer) 3482 { 3483 int count; 3484 int sum; 3485 xmlLinkPtr lk; 3486 xmlTextWriterStackEntry *p; 3487 3488 if (writer == NULL) 3489 return -1; 3490 3491 sum = 0; 3492 lk = xmlListFront(writer->nodes); 3493 if (lk == 0) 3494 return -1; 3495 3496 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 3497 if (p == 0) 3498 return -1; 3499 3500 switch (p->state) { 3501 case XML_TEXTWRITER_DTD_ATTL: 3502 case XML_TEXTWRITER_DTD_ATTL_TEXT: 3503 count = xmlOutputBufferWriteString(writer->out, ">"); 3504 if (count < 0) 3505 return -1; 3506 sum += count; 3507 break; 3508 default: 3509 return -1; 3510 } 3511 3512 if (writer->indent) { 3513 count = xmlOutputBufferWriteString(writer->out, "\n"); 3514 if (count < 0) 3515 return -1; 3516 sum += count; 3517 } 3518 3519 xmlListPopFront(writer->nodes); 3520 return sum; 3521 } 3522 3523 /** 3524 * xmlTextWriterWriteFormatDTDAttlist: 3525 * @writer: the xmlTextWriterPtr 3526 * @name: the name of the DTD ATTLIST 3527 * @format: format string (see printf) 3528 * @...: extra parameters for the format 3529 * 3530 * Write a formatted DTD ATTLIST. 3531 * 3532 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3533 */ 3534 int XMLCDECL 3535 xmlTextWriterWriteFormatDTDAttlist(xmlTextWriterPtr writer, 3536 const xmlChar * name, 3537 const char *format, ...) 3538 { 3539 int rc; 3540 va_list ap; 3541 3542 va_start(ap, format); 3543 3544 rc = xmlTextWriterWriteVFormatDTDAttlist(writer, name, format, ap); 3545 3546 va_end(ap); 3547 return rc; 3548 } 3549 3550 /** 3551 * xmlTextWriterWriteVFormatDTDAttlist: 3552 * @writer: the xmlTextWriterPtr 3553 * @name: the name of the DTD ATTLIST 3554 * @format: format string (see printf) 3555 * @argptr: pointer to the first member of the variable argument list. 3556 * 3557 * Write a formatted DTD ATTLIST. 3558 * 3559 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3560 */ 3561 int 3562 xmlTextWriterWriteVFormatDTDAttlist(xmlTextWriterPtr writer, 3563 const xmlChar * name, 3564 const char *format, va_list argptr) 3565 { 3566 int rc; 3567 xmlChar *buf; 3568 3569 if (writer == NULL) 3570 return -1; 3571 3572 buf = xmlTextWriterVSprintf(format, argptr); 3573 if (buf == NULL) 3574 return -1; 3575 3576 rc = xmlTextWriterWriteDTDAttlist(writer, name, buf); 3577 3578 xmlFree(buf); 3579 return rc; 3580 } 3581 3582 /** 3583 * xmlTextWriterWriteDTDAttlist: 3584 * @writer: the xmlTextWriterPtr 3585 * @name: the name of the DTD ATTLIST 3586 * @content: content of the ATTLIST 3587 * 3588 * Write a DTD ATTLIST. 3589 * 3590 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3591 */ 3592 int 3593 xmlTextWriterWriteDTDAttlist(xmlTextWriterPtr writer, 3594 const xmlChar * name, const xmlChar * content) 3595 { 3596 int count; 3597 int sum; 3598 3599 if (content == NULL) 3600 return -1; 3601 3602 sum = 0; 3603 count = xmlTextWriterStartDTDAttlist(writer, name); 3604 if (count == -1) 3605 return -1; 3606 sum += count; 3607 3608 count = xmlTextWriterWriteString(writer, content); 3609 if (count == -1) 3610 return -1; 3611 sum += count; 3612 3613 count = xmlTextWriterEndDTDAttlist(writer); 3614 if (count == -1) 3615 return -1; 3616 sum += count; 3617 3618 return sum; 3619 } 3620 3621 /** 3622 * xmlTextWriterStartDTDEntity: 3623 * @writer: the xmlTextWriterPtr 3624 * @pe: TRUE if this is a parameter entity, FALSE if not 3625 * @name: the name of the DTD ATTLIST 3626 * 3627 * Start an xml DTD ATTLIST. 3628 * 3629 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3630 */ 3631 int 3632 xmlTextWriterStartDTDEntity(xmlTextWriterPtr writer, 3633 int pe, const xmlChar * name) 3634 { 3635 int count; 3636 int sum; 3637 xmlLinkPtr lk; 3638 xmlTextWriterStackEntry *p; 3639 3640 if (writer == NULL || name == NULL || *name == '\0') 3641 return -1; 3642 3643 sum = 0; 3644 lk = xmlListFront(writer->nodes); 3645 if (lk != 0) { 3646 3647 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 3648 if (p != 0) { 3649 switch (p->state) { 3650 case XML_TEXTWRITER_DTD: 3651 count = xmlOutputBufferWriteString(writer->out, " ["); 3652 if (count < 0) 3653 return -1; 3654 sum += count; 3655 if (writer->indent) { 3656 count = 3657 xmlOutputBufferWriteString(writer->out, "\n"); 3658 if (count < 0) 3659 return -1; 3660 sum += count; 3661 } 3662 p->state = XML_TEXTWRITER_DTD_TEXT; 3663 /* fallthrough */ 3664 case XML_TEXTWRITER_DTD_TEXT: 3665 case XML_TEXTWRITER_NONE: 3666 break; 3667 default: 3668 return -1; 3669 } 3670 } 3671 } 3672 3673 p = (xmlTextWriterStackEntry *) 3674 xmlMalloc(sizeof(xmlTextWriterStackEntry)); 3675 if (p == 0) { 3676 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 3677 "xmlTextWriterStartDTDElement : out of memory!\n"); 3678 return -1; 3679 } 3680 3681 p->name = xmlStrdup(name); 3682 if (p->name == 0) { 3683 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 3684 "xmlTextWriterStartDTDElement : out of memory!\n"); 3685 xmlFree(p); 3686 return -1; 3687 } 3688 3689 if (pe != 0) 3690 p->state = XML_TEXTWRITER_DTD_PENT; 3691 else 3692 p->state = XML_TEXTWRITER_DTD_ENTY; 3693 3694 xmlListPushFront(writer->nodes, p); 3695 3696 if (writer->indent) { 3697 count = xmlTextWriterWriteIndent(writer); 3698 if (count < 0) 3699 return -1; 3700 sum += count; 3701 } 3702 3703 count = xmlOutputBufferWriteString(writer->out, "<!ENTITY "); 3704 if (count < 0) 3705 return -1; 3706 sum += count; 3707 3708 if (pe != 0) { 3709 count = xmlOutputBufferWriteString(writer->out, "% "); 3710 if (count < 0) 3711 return -1; 3712 sum += count; 3713 } 3714 3715 count = xmlOutputBufferWriteString(writer->out, (const char *) name); 3716 if (count < 0) 3717 return -1; 3718 sum += count; 3719 3720 return sum; 3721 } 3722 3723 /** 3724 * xmlTextWriterEndDTDEntity: 3725 * @writer: the xmlTextWriterPtr 3726 * 3727 * End an xml DTD entity. 3728 * 3729 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3730 */ 3731 int 3732 xmlTextWriterEndDTDEntity(xmlTextWriterPtr writer) 3733 { 3734 int count; 3735 int sum; 3736 xmlLinkPtr lk; 3737 xmlTextWriterStackEntry *p; 3738 3739 if (writer == NULL) 3740 return -1; 3741 3742 sum = 0; 3743 lk = xmlListFront(writer->nodes); 3744 if (lk == 0) 3745 return -1; 3746 3747 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 3748 if (p == 0) 3749 return -1; 3750 3751 switch (p->state) { 3752 case XML_TEXTWRITER_DTD_ENTY_TEXT: 3753 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 3754 if (count < 0) 3755 return -1; 3756 sum += count; 3757 case XML_TEXTWRITER_DTD_ENTY: 3758 case XML_TEXTWRITER_DTD_PENT: 3759 count = xmlOutputBufferWriteString(writer->out, ">"); 3760 if (count < 0) 3761 return -1; 3762 sum += count; 3763 break; 3764 default: 3765 return -1; 3766 } 3767 3768 if (writer->indent) { 3769 count = xmlOutputBufferWriteString(writer->out, "\n"); 3770 if (count < 0) 3771 return -1; 3772 sum += count; 3773 } 3774 3775 xmlListPopFront(writer->nodes); 3776 return sum; 3777 } 3778 3779 /** 3780 * xmlTextWriterWriteFormatDTDInternalEntity: 3781 * @writer: the xmlTextWriterPtr 3782 * @pe: TRUE if this is a parameter entity, FALSE if not 3783 * @name: the name of the DTD entity 3784 * @format: format string (see printf) 3785 * @...: extra parameters for the format 3786 * 3787 * Write a formatted DTD internal entity. 3788 * 3789 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3790 */ 3791 int XMLCDECL 3792 xmlTextWriterWriteFormatDTDInternalEntity(xmlTextWriterPtr writer, 3793 int pe, 3794 const xmlChar * name, 3795 const char *format, ...) 3796 { 3797 int rc; 3798 va_list ap; 3799 3800 va_start(ap, format); 3801 3802 rc = xmlTextWriterWriteVFormatDTDInternalEntity(writer, pe, name, 3803 format, ap); 3804 3805 va_end(ap); 3806 return rc; 3807 } 3808 3809 /** 3810 * xmlTextWriterWriteVFormatDTDInternalEntity: 3811 * @writer: the xmlTextWriterPtr 3812 * @pe: TRUE if this is a parameter entity, FALSE if not 3813 * @name: the name of the DTD entity 3814 * @format: format string (see printf) 3815 * @argptr: pointer to the first member of the variable argument list. 3816 * 3817 * Write a formatted DTD internal entity. 3818 * 3819 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3820 */ 3821 int 3822 xmlTextWriterWriteVFormatDTDInternalEntity(xmlTextWriterPtr writer, 3823 int pe, 3824 const xmlChar * name, 3825 const char *format, 3826 va_list argptr) 3827 { 3828 int rc; 3829 xmlChar *buf; 3830 3831 if (writer == NULL) 3832 return -1; 3833 3834 buf = xmlTextWriterVSprintf(format, argptr); 3835 if (buf == NULL) 3836 return -1; 3837 3838 rc = xmlTextWriterWriteDTDInternalEntity(writer, pe, name, buf); 3839 3840 xmlFree(buf); 3841 return rc; 3842 } 3843 3844 /** 3845 * xmlTextWriterWriteDTDEntity: 3846 * @writer: the xmlTextWriterPtr 3847 * @pe: TRUE if this is a parameter entity, FALSE if not 3848 * @name: the name of the DTD entity 3849 * @pubid: the public identifier, which is an alternative to the system identifier 3850 * @sysid: the system identifier, which is the URI of the DTD 3851 * @ndataid: the xml notation name. 3852 * @content: content of the entity 3853 * 3854 * Write a DTD entity. 3855 * 3856 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3857 */ 3858 int 3859 xmlTextWriterWriteDTDEntity(xmlTextWriterPtr writer, 3860 int pe, 3861 const xmlChar * name, 3862 const xmlChar * pubid, 3863 const xmlChar * sysid, 3864 const xmlChar * ndataid, 3865 const xmlChar * content) 3866 { 3867 if ((content == NULL) && (pubid == NULL) && (sysid == NULL)) 3868 return -1; 3869 if ((pe != 0) && (ndataid != NULL)) 3870 return -1; 3871 3872 if ((pubid == NULL) && (sysid == NULL)) 3873 return xmlTextWriterWriteDTDInternalEntity(writer, pe, name, 3874 content); 3875 3876 return xmlTextWriterWriteDTDExternalEntity(writer, pe, name, pubid, 3877 sysid, ndataid); 3878 } 3879 3880 /** 3881 * xmlTextWriterWriteDTDInternalEntity: 3882 * @writer: the xmlTextWriterPtr 3883 * @pe: TRUE if this is a parameter entity, FALSE if not 3884 * @name: the name of the DTD entity 3885 * @content: content of the entity 3886 * 3887 * Write a DTD internal entity. 3888 * 3889 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3890 */ 3891 int 3892 xmlTextWriterWriteDTDInternalEntity(xmlTextWriterPtr writer, 3893 int pe, 3894 const xmlChar * name, 3895 const xmlChar * content) 3896 { 3897 int count; 3898 int sum; 3899 3900 if ((name == NULL) || (*name == '\0') || (content == NULL)) 3901 return -1; 3902 3903 sum = 0; 3904 count = xmlTextWriterStartDTDEntity(writer, pe, name); 3905 if (count == -1) 3906 return -1; 3907 sum += count; 3908 3909 count = xmlTextWriterWriteString(writer, content); 3910 if (count == -1) 3911 return -1; 3912 sum += count; 3913 3914 count = xmlTextWriterEndDTDEntity(writer); 3915 if (count == -1) 3916 return -1; 3917 sum += count; 3918 3919 return sum; 3920 } 3921 3922 /** 3923 * xmlTextWriterWriteDTDExternalEntity: 3924 * @writer: the xmlTextWriterPtr 3925 * @pe: TRUE if this is a parameter entity, FALSE if not 3926 * @name: the name of the DTD entity 3927 * @pubid: the public identifier, which is an alternative to the system identifier 3928 * @sysid: the system identifier, which is the URI of the DTD 3929 * @ndataid: the xml notation name. 3930 * 3931 * Write a DTD external entity. The entity must have been started with xmlTextWriterStartDTDEntity 3932 * 3933 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3934 */ 3935 int 3936 xmlTextWriterWriteDTDExternalEntity(xmlTextWriterPtr writer, 3937 int pe, 3938 const xmlChar * name, 3939 const xmlChar * pubid, 3940 const xmlChar * sysid, 3941 const xmlChar * ndataid) 3942 { 3943 int count; 3944 int sum; 3945 3946 if (((pubid == NULL) && (sysid == NULL))) 3947 return -1; 3948 if ((pe != 0) && (ndataid != NULL)) 3949 return -1; 3950 3951 sum = 0; 3952 count = xmlTextWriterStartDTDEntity(writer, pe, name); 3953 if (count == -1) 3954 return -1; 3955 sum += count; 3956 3957 count = 3958 xmlTextWriterWriteDTDExternalEntityContents(writer, pubid, sysid, 3959 ndataid); 3960 if (count < 0) 3961 return -1; 3962 sum += count; 3963 3964 count = xmlTextWriterEndDTDEntity(writer); 3965 if (count == -1) 3966 return -1; 3967 sum += count; 3968 3969 return sum; 3970 } 3971 3972 /** 3973 * xmlTextWriterWriteDTDExternalEntityContents: 3974 * @writer: the xmlTextWriterPtr 3975 * @pubid: the public identifier, which is an alternative to the system identifier 3976 * @sysid: the system identifier, which is the URI of the DTD 3977 * @ndataid: the xml notation name. 3978 * 3979 * Write the contents of a DTD external entity. 3980 * 3981 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3982 */ 3983 int 3984 xmlTextWriterWriteDTDExternalEntityContents(xmlTextWriterPtr writer, 3985 const xmlChar * pubid, 3986 const xmlChar * sysid, 3987 const xmlChar * ndataid) 3988 { 3989 int count; 3990 int sum; 3991 xmlLinkPtr lk; 3992 xmlTextWriterStackEntry *p; 3993 3994 if (writer == NULL) { 3995 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 3996 "xmlTextWriterWriteDTDExternalEntityContents: xmlTextWriterPtr invalid!\n"); 3997 return -1; 3998 } 3999 4000 sum = 0; 4001 lk = xmlListFront(writer->nodes); 4002 if (lk == 0) { 4003 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 4004 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n"); 4005 return -1; 4006 } 4007 4008 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 4009 if (p == 0) 4010 return -1; 4011 4012 switch (p->state) { 4013 case XML_TEXTWRITER_DTD_ENTY: 4014 break; 4015 case XML_TEXTWRITER_DTD_PENT: 4016 if (ndataid != NULL) { 4017 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 4018 "xmlTextWriterWriteDTDExternalEntityContents: notation not allowed with parameter entities!\n"); 4019 return -1; 4020 } 4021 break; 4022 default: 4023 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 4024 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n"); 4025 return -1; 4026 } 4027 4028 if (pubid != 0) { 4029 if (sysid == 0) { 4030 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 4031 "xmlTextWriterWriteDTDExternalEntityContents: system identifier needed!\n"); 4032 return -1; 4033 } 4034 4035 count = xmlOutputBufferWriteString(writer->out, " PUBLIC "); 4036 if (count < 0) 4037 return -1; 4038 sum += count; 4039 4040 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 4041 if (count < 0) 4042 return -1; 4043 sum += count; 4044 4045 count = 4046 xmlOutputBufferWriteString(writer->out, (const char *) pubid); 4047 if (count < 0) 4048 return -1; 4049 sum += count; 4050 4051 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 4052 if (count < 0) 4053 return -1; 4054 sum += count; 4055 } 4056 4057 if (sysid != 0) { 4058 if (pubid == 0) { 4059 count = xmlOutputBufferWriteString(writer->out, " SYSTEM"); 4060 if (count < 0) 4061 return -1; 4062 sum += count; 4063 } 4064 4065 count = xmlOutputBufferWriteString(writer->out, " "); 4066 if (count < 0) 4067 return -1; 4068 sum += count; 4069 4070 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 4071 if (count < 0) 4072 return -1; 4073 sum += count; 4074 4075 count = 4076 xmlOutputBufferWriteString(writer->out, (const char *) sysid); 4077 if (count < 0) 4078 return -1; 4079 sum += count; 4080 4081 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 4082 if (count < 0) 4083 return -1; 4084 sum += count; 4085 } 4086 4087 if (ndataid != NULL) { 4088 count = xmlOutputBufferWriteString(writer->out, " NDATA "); 4089 if (count < 0) 4090 return -1; 4091 sum += count; 4092 4093 count = 4094 xmlOutputBufferWriteString(writer->out, 4095 (const char *) ndataid); 4096 if (count < 0) 4097 return -1; 4098 sum += count; 4099 } 4100 4101 return sum; 4102 } 4103 4104 /** 4105 * xmlTextWriterWriteDTDNotation: 4106 * @writer: the xmlTextWriterPtr 4107 * @name: the name of the xml notation 4108 * @pubid: the public identifier, which is an alternative to the system identifier 4109 * @sysid: the system identifier, which is the URI of the DTD 4110 * 4111 * Write a DTD entity. 4112 * 4113 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 4114 */ 4115 int 4116 xmlTextWriterWriteDTDNotation(xmlTextWriterPtr writer, 4117 const xmlChar * name, 4118 const xmlChar * pubid, const xmlChar * sysid) 4119 { 4120 int count; 4121 int sum; 4122 xmlLinkPtr lk; 4123 xmlTextWriterStackEntry *p; 4124 4125 if (writer == NULL || name == NULL || *name == '\0') 4126 return -1; 4127 4128 sum = 0; 4129 lk = xmlListFront(writer->nodes); 4130 if (lk == 0) { 4131 return -1; 4132 } 4133 4134 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 4135 if (p != 0) { 4136 switch (p->state) { 4137 case XML_TEXTWRITER_DTD: 4138 count = xmlOutputBufferWriteString(writer->out, " ["); 4139 if (count < 0) 4140 return -1; 4141 sum += count; 4142 if (writer->indent) { 4143 count = xmlOutputBufferWriteString(writer->out, "\n"); 4144 if (count < 0) 4145 return -1; 4146 sum += count; 4147 } 4148 p->state = XML_TEXTWRITER_DTD_TEXT; 4149 /* fallthrough */ 4150 case XML_TEXTWRITER_DTD_TEXT: 4151 break; 4152 default: 4153 return -1; 4154 } 4155 } 4156 4157 if (writer->indent) { 4158 count = xmlTextWriterWriteIndent(writer); 4159 if (count < 0) 4160 return -1; 4161 sum += count; 4162 } 4163 4164 count = xmlOutputBufferWriteString(writer->out, "<!NOTATION "); 4165 if (count < 0) 4166 return -1; 4167 sum += count; 4168 count = xmlOutputBufferWriteString(writer->out, (const char *) name); 4169 if (count < 0) 4170 return -1; 4171 sum += count; 4172 4173 if (pubid != 0) { 4174 count = xmlOutputBufferWriteString(writer->out, " PUBLIC "); 4175 if (count < 0) 4176 return -1; 4177 sum += count; 4178 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 4179 if (count < 0) 4180 return -1; 4181 sum += count; 4182 count = 4183 xmlOutputBufferWriteString(writer->out, (const char *) pubid); 4184 if (count < 0) 4185 return -1; 4186 sum += count; 4187 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 4188 if (count < 0) 4189 return -1; 4190 sum += count; 4191 } 4192 4193 if (sysid != 0) { 4194 if (pubid == 0) { 4195 count = xmlOutputBufferWriteString(writer->out, " SYSTEM"); 4196 if (count < 0) 4197 return -1; 4198 sum += count; 4199 } 4200 count = xmlOutputBufferWriteString(writer->out, " "); 4201 if (count < 0) 4202 return -1; 4203 sum += count; 4204 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 4205 if (count < 0) 4206 return -1; 4207 sum += count; 4208 count = 4209 xmlOutputBufferWriteString(writer->out, (const char *) sysid); 4210 if (count < 0) 4211 return -1; 4212 sum += count; 4213 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 4214 if (count < 0) 4215 return -1; 4216 sum += count; 4217 } 4218 4219 count = xmlOutputBufferWriteString(writer->out, ">"); 4220 if (count < 0) 4221 return -1; 4222 sum += count; 4223 4224 return sum; 4225 } 4226 4227 /** 4228 * xmlTextWriterFlush: 4229 * @writer: the xmlTextWriterPtr 4230 * 4231 * Flush the output buffer. 4232 * 4233 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 4234 */ 4235 int 4236 xmlTextWriterFlush(xmlTextWriterPtr writer) 4237 { 4238 int count; 4239 4240 if (writer == NULL) 4241 return -1; 4242 4243 if (writer->out == NULL) 4244 count = 0; 4245 else 4246 count = xmlOutputBufferFlush(writer->out); 4247 4248 return count; 4249 } 4250 4251 /** 4252 * misc 4253 */ 4254 4255 /** 4256 * xmlFreeTextWriterStackEntry: 4257 * @lk: the xmlLinkPtr 4258 * 4259 * Free callback for the xmlList. 4260 */ 4261 static void 4262 xmlFreeTextWriterStackEntry(xmlLinkPtr lk) 4263 { 4264 xmlTextWriterStackEntry *p; 4265 4266 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 4267 if (p == 0) 4268 return; 4269 4270 if (p->name != 0) 4271 xmlFree(p->name); 4272 xmlFree(p); 4273 } 4274 4275 /** 4276 * xmlCmpTextWriterStackEntry: 4277 * @data0: the first data 4278 * @data1: the second data 4279 * 4280 * Compare callback for the xmlList. 4281 * 4282 * Returns -1, 0, 1 4283 */ 4284 static int 4285 xmlCmpTextWriterStackEntry(const void *data0, const void *data1) 4286 { 4287 xmlTextWriterStackEntry *p0; 4288 xmlTextWriterStackEntry *p1; 4289 4290 if (data0 == data1) 4291 return 0; 4292 4293 if (data0 == 0) 4294 return -1; 4295 4296 if (data1 == 0) 4297 return 1; 4298 4299 p0 = (xmlTextWriterStackEntry *) data0; 4300 p1 = (xmlTextWriterStackEntry *) data1; 4301 4302 return xmlStrcmp(p0->name, p1->name); 4303 } 4304 4305 /** 4306 * misc 4307 */ 4308 4309 /** 4310 * xmlTextWriterOutputNSDecl: 4311 * @writer: the xmlTextWriterPtr 4312 * 4313 * Output the current namespace declarations. 4314 */ 4315 static int 4316 xmlTextWriterOutputNSDecl(xmlTextWriterPtr writer) 4317 { 4318 xmlLinkPtr lk; 4319 xmlTextWriterNsStackEntry *np; 4320 int count; 4321 int sum; 4322 4323 sum = 0; 4324 while (!xmlListEmpty(writer->nsstack)) { 4325 xmlChar *namespaceURI = NULL; 4326 xmlChar *prefix = NULL; 4327 4328 lk = xmlListFront(writer->nsstack); 4329 np = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk); 4330 4331 if (np != 0) { 4332 namespaceURI = xmlStrdup(np->uri); 4333 prefix = xmlStrdup(np->prefix); 4334 } 4335 4336 xmlListPopFront(writer->nsstack); 4337 4338 if (np != 0) { 4339 count = xmlTextWriterWriteAttribute(writer, prefix, namespaceURI); 4340 xmlFree(namespaceURI); 4341 xmlFree(prefix); 4342 4343 if (count < 0) { 4344 xmlListDelete(writer->nsstack); 4345 writer->nsstack = NULL; 4346 return -1; 4347 } 4348 sum += count; 4349 } 4350 } 4351 return sum; 4352 } 4353 4354 /** 4355 * xmlFreeTextWriterNsStackEntry: 4356 * @lk: the xmlLinkPtr 4357 * 4358 * Free callback for the xmlList. 4359 */ 4360 static void 4361 xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk) 4362 { 4363 xmlTextWriterNsStackEntry *p; 4364 4365 p = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk); 4366 if (p == 0) 4367 return; 4368 4369 if (p->prefix != 0) 4370 xmlFree(p->prefix); 4371 if (p->uri != 0) 4372 xmlFree(p->uri); 4373 4374 xmlFree(p); 4375 } 4376 4377 /** 4378 * xmlCmpTextWriterNsStackEntry: 4379 * @data0: the first data 4380 * @data1: the second data 4381 * 4382 * Compare callback for the xmlList. 4383 * 4384 * Returns -1, 0, 1 4385 */ 4386 static int 4387 xmlCmpTextWriterNsStackEntry(const void *data0, const void *data1) 4388 { 4389 xmlTextWriterNsStackEntry *p0; 4390 xmlTextWriterNsStackEntry *p1; 4391 int rc; 4392 4393 if (data0 == data1) 4394 return 0; 4395 4396 if (data0 == 0) 4397 return -1; 4398 4399 if (data1 == 0) 4400 return 1; 4401 4402 p0 = (xmlTextWriterNsStackEntry *) data0; 4403 p1 = (xmlTextWriterNsStackEntry *) data1; 4404 4405 rc = xmlStrcmp(p0->prefix, p1->prefix); 4406 4407 if ((rc != 0) || (p0->elem != p1->elem)) 4408 rc = -1; 4409 4410 return rc; 4411 } 4412 4413 /** 4414 * xmlTextWriterWriteDocCallback: 4415 * @context: the xmlBufferPtr 4416 * @str: the data to write 4417 * @len: the length of the data 4418 * 4419 * Write callback for the xmlOutputBuffer with target xmlBuffer 4420 * 4421 * Returns -1, 0, 1 4422 */ 4423 static int 4424 xmlTextWriterWriteDocCallback(void *context, const xmlChar * str, int len) 4425 { 4426 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context; 4427 int rc; 4428 4429 if ((rc = xmlParseChunk(ctxt, (const char *) str, len, 0)) != 0) { 4430 xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR, 4431 "xmlTextWriterWriteDocCallback : XML error %d !\n", 4432 rc); 4433 return -1; 4434 } 4435 4436 return len; 4437 } 4438 4439 /** 4440 * xmlTextWriterCloseDocCallback: 4441 * @context: the xmlBufferPtr 4442 * 4443 * Close callback for the xmlOutputBuffer with target xmlBuffer 4444 * 4445 * Returns -1, 0, 1 4446 */ 4447 static int 4448 xmlTextWriterCloseDocCallback(void *context) 4449 { 4450 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context; 4451 int rc; 4452 4453 if ((rc = xmlParseChunk(ctxt, NULL, 0, 1)) != 0) { 4454 xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR, 4455 "xmlTextWriterWriteDocCallback : XML error %d !\n", 4456 rc); 4457 return -1; 4458 } 4459 4460 return 0; 4461 } 4462 4463 /** 4464 * xmlTextWriterVSprintf: 4465 * @format: see printf 4466 * @argptr: pointer to the first member of the variable argument list. 4467 * 4468 * Utility function for formatted output 4469 * 4470 * Returns a new xmlChar buffer with the data or NULL on error. This buffer must be freed. 4471 */ 4472 static xmlChar * 4473 xmlTextWriterVSprintf(const char *format, va_list argptr) 4474 { 4475 int size; 4476 int count; 4477 xmlChar *buf; 4478 va_list locarg; 4479 4480 size = BUFSIZ; 4481 buf = (xmlChar *) xmlMalloc(size); 4482 if (buf == NULL) { 4483 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY, 4484 "xmlTextWriterVSprintf : out of memory!\n"); 4485 return NULL; 4486 } 4487 4488 VA_COPY(locarg, argptr); 4489 while (((count = vsnprintf((char *) buf, size, format, locarg)) < 0) 4490 || (count == size - 1) || (count == size) || (count > size)) { 4491 va_end(locarg); 4492 xmlFree(buf); 4493 size += BUFSIZ; 4494 buf = (xmlChar *) xmlMalloc(size); 4495 if (buf == NULL) { 4496 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY, 4497 "xmlTextWriterVSprintf : out of memory!\n"); 4498 return NULL; 4499 } 4500 VA_COPY(locarg, argptr); 4501 } 4502 va_end(locarg); 4503 4504 return buf; 4505 } 4506 4507 /** 4508 * xmlTextWriterStartDocumentCallback: 4509 * @ctx: the user data (XML parser context) 4510 * 4511 * called at the start of document processing. 4512 */ 4513 static void 4514 xmlTextWriterStartDocumentCallback(void *ctx) 4515 { 4516 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 4517 xmlDocPtr doc; 4518 4519 if (ctxt->html) { 4520 #ifdef LIBXML_HTML_ENABLED 4521 if (ctxt->myDoc == NULL) 4522 ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL); 4523 if (ctxt->myDoc == NULL) { 4524 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 4525 ctxt->sax->error(ctxt->userData, 4526 "SAX.startDocument(): out of memory\n"); 4527 ctxt->errNo = XML_ERR_NO_MEMORY; 4528 ctxt->instate = XML_PARSER_EOF; 4529 ctxt->disableSAX = 1; 4530 return; 4531 } 4532 #else 4533 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR, 4534 "libxml2 built without HTML support\n"); 4535 ctxt->errNo = XML_ERR_INTERNAL_ERROR; 4536 ctxt->instate = XML_PARSER_EOF; 4537 ctxt->disableSAX = 1; 4538 return; 4539 #endif 4540 } else { 4541 doc = ctxt->myDoc; 4542 if (doc == NULL) 4543 doc = ctxt->myDoc = xmlNewDoc(ctxt->version); 4544 if (doc != NULL) { 4545 if (doc->children == NULL) { 4546 if (ctxt->encoding != NULL) 4547 doc->encoding = xmlStrdup(ctxt->encoding); 4548 else 4549 doc->encoding = NULL; 4550 doc->standalone = ctxt->standalone; 4551 } 4552 } else { 4553 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 4554 ctxt->sax->error(ctxt->userData, 4555 "SAX.startDocument(): out of memory\n"); 4556 ctxt->errNo = XML_ERR_NO_MEMORY; 4557 ctxt->instate = XML_PARSER_EOF; 4558 ctxt->disableSAX = 1; 4559 return; 4560 } 4561 } 4562 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) && 4563 (ctxt->input != NULL) && (ctxt->input->filename != NULL)) { 4564 ctxt->myDoc->URL = 4565 xmlCanonicPath((const xmlChar *) ctxt->input->filename); 4566 if (ctxt->myDoc->URL == NULL) 4567 ctxt->myDoc->URL = 4568 xmlStrdup((const xmlChar *) ctxt->input->filename); 4569 } 4570 } 4571 4572 /** 4573 * xmlTextWriterSetIndent: 4574 * @writer: the xmlTextWriterPtr 4575 * @indent: do indentation? 4576 * 4577 * Set indentation output. indent = 0 do not indentation. indent > 0 do indentation. 4578 * 4579 * Returns -1 on error or 0 otherwise. 4580 */ 4581 int 4582 xmlTextWriterSetIndent(xmlTextWriterPtr writer, int indent) 4583 { 4584 if ((writer == NULL) || (indent < 0)) 4585 return -1; 4586 4587 writer->indent = indent; 4588 writer->doindent = 1; 4589 4590 return 0; 4591 } 4592 4593 /** 4594 * xmlTextWriterSetIndentString: 4595 * @writer: the xmlTextWriterPtr 4596 * @str: the xmlChar string 4597 * 4598 * Set string indentation. 4599 * 4600 * Returns -1 on error or 0 otherwise. 4601 */ 4602 int 4603 xmlTextWriterSetIndentString(xmlTextWriterPtr writer, const xmlChar * str) 4604 { 4605 if ((writer == NULL) || (!str)) 4606 return -1; 4607 4608 if (writer->ichar != NULL) 4609 xmlFree(writer->ichar); 4610 writer->ichar = xmlStrdup(str); 4611 4612 if (!writer->ichar) 4613 return -1; 4614 else 4615 return 0; 4616 } 4617 4618 /** 4619 * xmlTextWriterSetQuoteChar: 4620 * @writer: the xmlTextWriterPtr 4621 * @quotechar: the quote character 4622 * 4623 * Set the character used for quoting attributes. 4624 * 4625 * Returns -1 on error or 0 otherwise. 4626 */ 4627 int 4628 xmlTextWriterSetQuoteChar(xmlTextWriterPtr writer, xmlChar quotechar) 4629 { 4630 if ((writer == NULL) || ((quotechar != '\'') && (quotechar != '"'))) 4631 return -1; 4632 4633 writer->qchar = quotechar; 4634 4635 return 0; 4636 } 4637 4638 /** 4639 * xmlTextWriterWriteIndent: 4640 * @writer: the xmlTextWriterPtr 4641 * 4642 * Write indent string. 4643 * 4644 * Returns -1 on error or the number of strings written. 4645 */ 4646 static int 4647 xmlTextWriterWriteIndent(xmlTextWriterPtr writer) 4648 { 4649 int lksize; 4650 int i; 4651 int ret; 4652 4653 lksize = xmlListSize(writer->nodes); 4654 if (lksize < 1) 4655 return (-1); /* list is empty */ 4656 for (i = 0; i < (lksize - 1); i++) { 4657 ret = xmlOutputBufferWriteString(writer->out, 4658 (const char *) writer->ichar); 4659 if (ret == -1) 4660 return (-1); 4661 } 4662 4663 return (lksize - 1); 4664 } 4665 4666 /** 4667 * xmlTextWriterHandleStateDependencies: 4668 * @writer: the xmlTextWriterPtr 4669 * @p: the xmlTextWriterStackEntry 4670 * 4671 * Write state dependent strings. 4672 * 4673 * Returns -1 on error or the number of characters written. 4674 */ 4675 static int 4676 xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer, 4677 xmlTextWriterStackEntry * p) 4678 { 4679 int count; 4680 int sum; 4681 char extra[3]; 4682 4683 if (writer == NULL) 4684 return -1; 4685 4686 if (p == NULL) 4687 return 0; 4688 4689 sum = 0; 4690 extra[0] = extra[1] = extra[2] = '\0'; 4691 if (p != 0) { 4692 sum = 0; 4693 switch (p->state) { 4694 case XML_TEXTWRITER_NAME: 4695 /* Output namespace declarations */ 4696 count = xmlTextWriterOutputNSDecl(writer); 4697 if (count < 0) 4698 return -1; 4699 sum += count; 4700 extra[0] = '>'; 4701 p->state = XML_TEXTWRITER_TEXT; 4702 break; 4703 case XML_TEXTWRITER_PI: 4704 extra[0] = ' '; 4705 p->state = XML_TEXTWRITER_PI_TEXT; 4706 break; 4707 case XML_TEXTWRITER_DTD: 4708 extra[0] = ' '; 4709 extra[1] = '['; 4710 p->state = XML_TEXTWRITER_DTD_TEXT; 4711 break; 4712 case XML_TEXTWRITER_DTD_ELEM: 4713 extra[0] = ' '; 4714 p->state = XML_TEXTWRITER_DTD_ELEM_TEXT; 4715 break; 4716 case XML_TEXTWRITER_DTD_ATTL: 4717 extra[0] = ' '; 4718 p->state = XML_TEXTWRITER_DTD_ATTL_TEXT; 4719 break; 4720 case XML_TEXTWRITER_DTD_ENTY: 4721 case XML_TEXTWRITER_DTD_PENT: 4722 extra[0] = ' '; 4723 extra[1] = writer->qchar; 4724 p->state = XML_TEXTWRITER_DTD_ENTY_TEXT; 4725 break; 4726 default: 4727 break; 4728 } 4729 } 4730 4731 if (*extra != '\0') { 4732 count = xmlOutputBufferWriteString(writer->out, extra); 4733 if (count < 0) 4734 return -1; 4735 sum += count; 4736 } 4737 4738 return sum; 4739 } 4740 4741 #define bottom_xmlwriter 4742 #include "elfgcchack.h" 4743 #endif 4744