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