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