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