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