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