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 /* fallthrough */ 1244 case XML_TEXTWRITER_TEXT: 1245 count = xmlOutputBufferWriteString(writer->out, "</"); 1246 if (count < 0) 1247 return -1; 1248 sum += count; 1249 count = xmlOutputBufferWriteString(writer->out, 1250 (const char *) p->name); 1251 if (count < 0) 1252 return -1; 1253 sum += count; 1254 count = xmlOutputBufferWriteString(writer->out, ">"); 1255 if (count < 0) 1256 return -1; 1257 sum += count; 1258 break; 1259 default: 1260 return -1; 1261 } 1262 1263 if (writer->indent) { 1264 count = xmlOutputBufferWriteString(writer->out, "\n"); 1265 sum += count; 1266 } 1267 1268 xmlListPopFront(writer->nodes); 1269 return sum; 1270} 1271 1272/** 1273 * xmlTextWriterWriteFormatRaw: 1274 * @writer: the xmlTextWriterPtr 1275 * @format: format string (see printf) 1276 * @...: extra parameters for the format 1277 * 1278 * Write a formatted raw xml text. 1279 * 1280 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 1281 */ 1282int XMLCDECL 1283xmlTextWriterWriteFormatRaw(xmlTextWriterPtr writer, const char *format, 1284 ...) 1285{ 1286 int rc; 1287 va_list ap; 1288 1289 va_start(ap, format); 1290 1291 rc = xmlTextWriterWriteVFormatRaw(writer, format, ap); 1292 1293 va_end(ap); 1294 return rc; 1295} 1296 1297/** 1298 * xmlTextWriterWriteVFormatRaw: 1299 * @writer: the xmlTextWriterPtr 1300 * @format: format string (see printf) 1301 * @argptr: pointer to the first member of the variable argument list. 1302 * 1303 * Write a formatted raw xml text. 1304 * 1305 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 1306 */ 1307int 1308xmlTextWriterWriteVFormatRaw(xmlTextWriterPtr writer, const char *format, 1309 va_list argptr) 1310{ 1311 int rc; 1312 xmlChar *buf; 1313 1314 if (writer == NULL) 1315 return -1; 1316 1317 buf = xmlTextWriterVSprintf(format, argptr); 1318 if (buf == 0) 1319 return 0; 1320 1321 rc = xmlTextWriterWriteRaw(writer, buf); 1322 1323 xmlFree(buf); 1324 return rc; 1325} 1326 1327/** 1328 * xmlTextWriterWriteRawLen: 1329 * @writer: the xmlTextWriterPtr 1330 * @content: text string 1331 * @len: length of the text string 1332 * 1333 * Write an xml text. 1334 * TODO: what about entities and special chars?? 1335 * 1336 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 1337 */ 1338int 1339xmlTextWriterWriteRawLen(xmlTextWriterPtr writer, const xmlChar * content, 1340 int len) 1341{ 1342 int count; 1343 int sum; 1344 xmlLinkPtr lk; 1345 xmlTextWriterStackEntry *p; 1346 1347 if (writer == NULL) { 1348 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 1349 "xmlTextWriterWriteRawLen : invalid writer!\n"); 1350 return -1; 1351 } 1352 1353 if ((content == NULL) || (len < 0)) { 1354 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 1355 "xmlTextWriterWriteRawLen : invalid content!\n"); 1356 return -1; 1357 } 1358 1359 sum = 0; 1360 lk = xmlListFront(writer->nodes); 1361 if (lk != 0) { 1362 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 1363 count = xmlTextWriterHandleStateDependencies(writer, p); 1364 if (count < 0) 1365 return -1; 1366 sum += count; 1367 } 1368 1369 if (writer->indent) 1370 writer->doindent = 0; 1371 1372 if (content != NULL) { 1373 count = 1374 xmlOutputBufferWrite(writer->out, len, (const char *) content); 1375 if (count < 0) 1376 return -1; 1377 sum += count; 1378 } 1379 1380 return sum; 1381} 1382 1383/** 1384 * xmlTextWriterWriteRaw: 1385 * @writer: the xmlTextWriterPtr 1386 * @content: text string 1387 * 1388 * Write a raw xml text. 1389 * 1390 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 1391 */ 1392int 1393xmlTextWriterWriteRaw(xmlTextWriterPtr writer, const xmlChar * content) 1394{ 1395 return xmlTextWriterWriteRawLen(writer, content, xmlStrlen(content)); 1396} 1397 1398/** 1399 * xmlTextWriterWriteFormatString: 1400 * @writer: the xmlTextWriterPtr 1401 * @format: format string (see printf) 1402 * @...: extra parameters for the format 1403 * 1404 * Write a formatted xml text. 1405 * 1406 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 1407 */ 1408int XMLCDECL 1409xmlTextWriterWriteFormatString(xmlTextWriterPtr writer, const char *format, 1410 ...) 1411{ 1412 int rc; 1413 va_list ap; 1414 1415 if ((writer == NULL) || (format == NULL)) 1416 return -1; 1417 1418 va_start(ap, format); 1419 1420 rc = xmlTextWriterWriteVFormatString(writer, format, ap); 1421 1422 va_end(ap); 1423 return rc; 1424} 1425 1426/** 1427 * xmlTextWriterWriteVFormatString: 1428 * @writer: the xmlTextWriterPtr 1429 * @format: format string (see printf) 1430 * @argptr: pointer to the first member of the variable argument list. 1431 * 1432 * Write a formatted xml text. 1433 * 1434 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 1435 */ 1436int 1437xmlTextWriterWriteVFormatString(xmlTextWriterPtr writer, 1438 const char *format, va_list argptr) 1439{ 1440 int rc; 1441 xmlChar *buf; 1442 1443 if ((writer == NULL) || (format == NULL)) 1444 return -1; 1445 1446 buf = xmlTextWriterVSprintf(format, argptr); 1447 if (buf == 0) 1448 return 0; 1449 1450 rc = xmlTextWriterWriteString(writer, buf); 1451 1452 xmlFree(buf); 1453 return rc; 1454} 1455 1456/** 1457 * xmlTextWriterWriteString: 1458 * @writer: the xmlTextWriterPtr 1459 * @content: text string 1460 * 1461 * Write an xml text. 1462 * 1463 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 1464 */ 1465int 1466xmlTextWriterWriteString(xmlTextWriterPtr writer, const xmlChar * content) 1467{ 1468 int count; 1469 int sum; 1470 xmlLinkPtr lk; 1471 xmlTextWriterStackEntry *p; 1472 xmlChar *buf; 1473 1474 if ((writer == NULL) || (content == NULL)) 1475 return -1; 1476 1477 sum = 0; 1478 buf = (xmlChar *) content; 1479 lk = xmlListFront(writer->nodes); 1480 if (lk != 0) { 1481 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 1482 if (p != 0) { 1483 switch (p->state) { 1484 case XML_TEXTWRITER_NAME: 1485 case XML_TEXTWRITER_TEXT: 1486#if 0 1487 buf = NULL; 1488 xmlOutputBufferWriteEscape(writer->out, content, NULL); 1489#endif 1490 buf = xmlEncodeSpecialChars(NULL, content); 1491 break; 1492 case XML_TEXTWRITER_ATTRIBUTE: 1493 buf = NULL; 1494 xmlAttrSerializeTxtContent(writer->out->buffer, writer->doc, 1495 NULL, content); 1496 break; 1497 default: 1498 break; 1499 } 1500 } 1501 } 1502 1503 if (buf != NULL) { 1504 count = xmlTextWriterWriteRaw(writer, buf); 1505 if (count < 0) 1506 return -1; 1507 sum += count; 1508 1509 if (buf != content) /* buf was allocated by us, so free it */ 1510 xmlFree(buf); 1511 } 1512 1513 return sum; 1514} 1515 1516/** 1517 * xmlOutputBufferWriteBase64: 1518 * @out: the xmlOutputBufferPtr 1519 * @data: binary data 1520 * @len: the number of bytes to encode 1521 * 1522 * Write base64 encoded data to an xmlOutputBuffer. 1523 * Adapted from John Walker's base64.c (http://www.fourmilab.ch/). 1524 * 1525 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 1526 */ 1527static int 1528xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len, 1529 const unsigned char *data) 1530{ 1531 static unsigned char dtable[64] = 1532 {'A','B','C','D','E','F','G','H','I','J','K','L','M', 1533 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z', 1534 'a','b','c','d','e','f','g','h','i','j','k','l','m', 1535 'n','o','p','q','r','s','t','u','v','w','x','y','z', 1536 '0','1','2','3','4','5','6','7','8','9','+','/'}; 1537 1538 int i; 1539 int linelen; 1540 int count; 1541 int sum; 1542 1543 if ((out == NULL) || (len < 0) || (data == NULL)) 1544 return(-1); 1545 1546 linelen = 0; 1547 sum = 0; 1548 1549 i = 0; 1550 while (1) { 1551 unsigned char igroup[3]; 1552 unsigned char ogroup[4]; 1553 int c; 1554 int n; 1555 1556 igroup[0] = igroup[1] = igroup[2] = 0; 1557 for (n = 0; n < 3 && i < len; n++, i++) { 1558 c = data[i]; 1559 igroup[n] = (unsigned char) c; 1560 } 1561 1562 if (n > 0) { 1563 ogroup[0] = dtable[igroup[0] >> 2]; 1564 ogroup[1] = dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)]; 1565 ogroup[2] = 1566 dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)]; 1567 ogroup[3] = dtable[igroup[2] & 0x3F]; 1568 1569 if (n < 3) { 1570 ogroup[3] = '='; 1571 if (n < 2) { 1572 ogroup[2] = '='; 1573 } 1574 } 1575 1576 if (linelen >= B64LINELEN) { 1577 count = xmlOutputBufferWrite(out, 2, B64CRLF); 1578 if (count == -1) 1579 return -1; 1580 sum += count; 1581 linelen = 0; 1582 } 1583 count = xmlOutputBufferWrite(out, 4, (const char *) ogroup); 1584 if (count == -1) 1585 return -1; 1586 sum += count; 1587 1588 linelen += 4; 1589 } 1590 1591 if (i >= len) 1592 break; 1593 } 1594 1595 return sum; 1596} 1597 1598/** 1599 * xmlTextWriterWriteBase64: 1600 * @writer: the xmlTextWriterPtr 1601 * @data: binary data 1602 * @start: the position within the data of the first byte to encode 1603 * @len: the number of bytes to encode 1604 * 1605 * Write an base64 encoded xml text. 1606 * 1607 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 1608 */ 1609int 1610xmlTextWriterWriteBase64(xmlTextWriterPtr writer, const char *data, 1611 int start, int len) 1612{ 1613 int count; 1614 int sum; 1615 xmlLinkPtr lk; 1616 xmlTextWriterStackEntry *p; 1617 1618 if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0)) 1619 return -1; 1620 1621 sum = 0; 1622 lk = xmlListFront(writer->nodes); 1623 if (lk != 0) { 1624 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 1625 if (p != 0) { 1626 count = xmlTextWriterHandleStateDependencies(writer, p); 1627 if (count < 0) 1628 return -1; 1629 sum += count; 1630 } 1631 } 1632 1633 if (writer->indent) 1634 writer->doindent = 0; 1635 1636 count = 1637 xmlOutputBufferWriteBase64(writer->out, len, 1638 (unsigned char *) data + start); 1639 if (count < 0) 1640 return -1; 1641 sum += count; 1642 1643 return sum; 1644} 1645 1646/** 1647 * xmlOutputBufferWriteBinHex: 1648 * @out: the xmlOutputBufferPtr 1649 * @data: binary data 1650 * @len: the number of bytes to encode 1651 * 1652 * Write hqx encoded data to an xmlOutputBuffer. 1653 * ::todo 1654 * 1655 * Returns the bytes written (may be 0 because of buffering) 1656 * or -1 in case of error 1657 */ 1658static int 1659xmlOutputBufferWriteBinHex(xmlOutputBufferPtr out, 1660 int len, const unsigned char *data) 1661{ 1662 int count; 1663 int sum; 1664 static char hex[16] = 1665 {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; 1666 int i; 1667 1668 if ((out == NULL) || (data == NULL) || (len < 0)) { 1669 return -1; 1670 } 1671 1672 sum = 0; 1673 for (i = 0; i < len; i++) { 1674 count = 1675 xmlOutputBufferWrite(out, 1, 1676 (const char *) &hex[data[i] >> 4]); 1677 if (count == -1) 1678 return -1; 1679 sum += count; 1680 count = 1681 xmlOutputBufferWrite(out, 1, 1682 (const char *) &hex[data[i] & 0xF]); 1683 if (count == -1) 1684 return -1; 1685 sum += count; 1686 } 1687 1688 return sum; 1689} 1690 1691/** 1692 * xmlTextWriterWriteBinHex: 1693 * @writer: the xmlTextWriterPtr 1694 * @data: binary data 1695 * @start: the position within the data of the first byte to encode 1696 * @len: the number of bytes to encode 1697 * 1698 * Write a BinHex encoded xml text. 1699 * 1700 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 1701 */ 1702int 1703xmlTextWriterWriteBinHex(xmlTextWriterPtr writer, const char *data, 1704 int start, int len) 1705{ 1706 int count; 1707 int sum; 1708 xmlLinkPtr lk; 1709 xmlTextWriterStackEntry *p; 1710 1711 if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0)) 1712 return -1; 1713 1714 sum = 0; 1715 lk = xmlListFront(writer->nodes); 1716 if (lk != 0) { 1717 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 1718 if (p != 0) { 1719 count = xmlTextWriterHandleStateDependencies(writer, p); 1720 if (count < 0) 1721 return -1; 1722 sum += count; 1723 } 1724 } 1725 1726 if (writer->indent) 1727 writer->doindent = 0; 1728 1729 count = 1730 xmlOutputBufferWriteBinHex(writer->out, len, 1731 (unsigned char *) data + start); 1732 if (count < 0) 1733 return -1; 1734 sum += count; 1735 1736 return sum; 1737} 1738 1739/** 1740 * xmlTextWriterStartAttribute: 1741 * @writer: the xmlTextWriterPtr 1742 * @name: element name 1743 * 1744 * Start an xml attribute. 1745 * 1746 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 1747 */ 1748int 1749xmlTextWriterStartAttribute(xmlTextWriterPtr writer, const xmlChar * name) 1750{ 1751 int count; 1752 int sum; 1753 xmlLinkPtr lk; 1754 xmlTextWriterStackEntry *p; 1755 1756 if ((writer == NULL) || (name == NULL) || (*name == '\0')) 1757 return -1; 1758 1759 sum = 0; 1760 lk = xmlListFront(writer->nodes); 1761 if (lk == 0) 1762 return -1; 1763 1764 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 1765 if (p == 0) 1766 return -1; 1767 1768 switch (p->state) { 1769 case XML_TEXTWRITER_ATTRIBUTE: 1770 count = xmlTextWriterEndAttribute(writer); 1771 if (count < 0) 1772 return -1; 1773 sum += count; 1774 /* fallthrough */ 1775 case XML_TEXTWRITER_NAME: 1776 count = xmlOutputBufferWriteString(writer->out, " "); 1777 if (count < 0) 1778 return -1; 1779 sum += count; 1780 count = 1781 xmlOutputBufferWriteString(writer->out, 1782 (const char *) name); 1783 if (count < 0) 1784 return -1; 1785 sum += count; 1786 count = xmlOutputBufferWriteString(writer->out, "="); 1787 if (count < 0) 1788 return -1; 1789 sum += count; 1790 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 1791 if (count < 0) 1792 return -1; 1793 sum += count; 1794 p->state = XML_TEXTWRITER_ATTRIBUTE; 1795 break; 1796 default: 1797 return -1; 1798 } 1799 1800 return sum; 1801} 1802 1803/** 1804 * xmlTextWriterStartAttributeNS: 1805 * @writer: the xmlTextWriterPtr 1806 * @prefix: namespace prefix or NULL 1807 * @name: element local name 1808 * @namespaceURI: namespace URI or NULL 1809 * 1810 * Start an xml attribute with namespace support. 1811 * 1812 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 1813 */ 1814int 1815xmlTextWriterStartAttributeNS(xmlTextWriterPtr writer, 1816 const xmlChar * prefix, const xmlChar * name, 1817 const xmlChar * namespaceURI) 1818{ 1819 int count; 1820 int sum; 1821 xmlChar *buf; 1822 xmlTextWriterNsStackEntry *p; 1823 1824 if ((writer == NULL) || (name == NULL) || (*name == '\0')) 1825 return -1; 1826 1827 /* Handle namespace first in case of error */ 1828 if (namespaceURI != 0) { 1829 xmlTextWriterNsStackEntry nsentry, *curns; 1830 1831 buf = xmlStrdup(BAD_CAST "xmlns"); 1832 if (prefix != 0) { 1833 buf = xmlStrcat(buf, BAD_CAST ":"); 1834 buf = xmlStrcat(buf, prefix); 1835 } 1836 1837 nsentry.prefix = buf; 1838 nsentry.uri = (xmlChar *)namespaceURI; 1839 nsentry.elem = xmlListFront(writer->nodes); 1840 1841 curns = (xmlTextWriterNsStackEntry *)xmlListSearch(writer->nsstack, 1842 (void *)&nsentry); 1843 if ((curns != NULL)) { 1844 xmlFree(buf); 1845 if (xmlStrcmp(curns->uri, namespaceURI) == 0) { 1846 /* Namespace already defined on element skip */ 1847 buf = NULL; 1848 } else { 1849 /* Prefix mismatch so error out */ 1850 return -1; 1851 } 1852 } 1853 1854 /* Do not add namespace decl to list - it is already there */ 1855 if (buf != NULL) { 1856 p = (xmlTextWriterNsStackEntry *) 1857 xmlMalloc(sizeof(xmlTextWriterNsStackEntry)); 1858 if (p == 0) { 1859 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 1860 "xmlTextWriterStartAttributeNS : out of memory!\n"); 1861 return -1; 1862 } 1863 1864 p->prefix = buf; 1865 p->uri = xmlStrdup(namespaceURI); 1866 if (p->uri == 0) { 1867 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 1868 "xmlTextWriterStartAttributeNS : out of memory!\n"); 1869 xmlFree(p); 1870 return -1; 1871 } 1872 p->elem = xmlListFront(writer->nodes); 1873 1874 xmlListPushFront(writer->nsstack, p); 1875 } 1876 } 1877 1878 buf = NULL; 1879 if (prefix != 0) { 1880 buf = xmlStrdup(prefix); 1881 buf = xmlStrcat(buf, BAD_CAST ":"); 1882 } 1883 buf = xmlStrcat(buf, name); 1884 1885 sum = 0; 1886 count = xmlTextWriterStartAttribute(writer, buf); 1887 xmlFree(buf); 1888 if (count < 0) 1889 return -1; 1890 sum += count; 1891 1892 return sum; 1893} 1894 1895/** 1896 * xmlTextWriterEndAttribute: 1897 * @writer: the xmlTextWriterPtr 1898 * 1899 * End the current xml element. 1900 * 1901 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 1902 */ 1903int 1904xmlTextWriterEndAttribute(xmlTextWriterPtr writer) 1905{ 1906 int count; 1907 int sum; 1908 xmlLinkPtr lk; 1909 xmlTextWriterStackEntry *p; 1910 1911 if (writer == NULL) 1912 return -1; 1913 1914 lk = xmlListFront(writer->nodes); 1915 if (lk == 0) { 1916 return -1; 1917 } 1918 1919 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 1920 if (p == 0) { 1921 return -1; 1922 } 1923 1924 sum = 0; 1925 switch (p->state) { 1926 case XML_TEXTWRITER_ATTRIBUTE: 1927 p->state = XML_TEXTWRITER_NAME; 1928 1929 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 1930 if (count < 0) { 1931 return -1; 1932 } 1933 sum += count; 1934 break; 1935 default: 1936 return -1; 1937 } 1938 1939 return sum; 1940} 1941 1942/** 1943 * xmlTextWriterWriteFormatAttribute: 1944 * @writer: the xmlTextWriterPtr 1945 * @name: attribute name 1946 * @format: format string (see printf) 1947 * @...: extra parameters for the format 1948 * 1949 * Write a formatted xml attribute. 1950 * 1951 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 1952 */ 1953int XMLCDECL 1954xmlTextWriterWriteFormatAttribute(xmlTextWriterPtr writer, 1955 const xmlChar * name, const char *format, 1956 ...) 1957{ 1958 int rc; 1959 va_list ap; 1960 1961 va_start(ap, format); 1962 1963 rc = xmlTextWriterWriteVFormatAttribute(writer, name, format, ap); 1964 1965 va_end(ap); 1966 return rc; 1967} 1968 1969/** 1970 * xmlTextWriterWriteVFormatAttribute: 1971 * @writer: the xmlTextWriterPtr 1972 * @name: attribute name 1973 * @format: format string (see printf) 1974 * @argptr: pointer to the first member of the variable argument list. 1975 * 1976 * Write a formatted xml attribute. 1977 * 1978 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 1979 */ 1980int 1981xmlTextWriterWriteVFormatAttribute(xmlTextWriterPtr writer, 1982 const xmlChar * name, 1983 const char *format, va_list argptr) 1984{ 1985 int rc; 1986 xmlChar *buf; 1987 1988 if (writer == NULL) 1989 return -1; 1990 1991 buf = xmlTextWriterVSprintf(format, argptr); 1992 if (buf == 0) 1993 return 0; 1994 1995 rc = xmlTextWriterWriteAttribute(writer, name, buf); 1996 1997 xmlFree(buf); 1998 return rc; 1999} 2000 2001/** 2002 * xmlTextWriterWriteAttribute: 2003 * @writer: the xmlTextWriterPtr 2004 * @name: attribute name 2005 * @content: attribute content 2006 * 2007 * Write an xml attribute. 2008 * 2009 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2010 */ 2011int 2012xmlTextWriterWriteAttribute(xmlTextWriterPtr writer, const xmlChar * name, 2013 const xmlChar * content) 2014{ 2015 int count; 2016 int sum; 2017 2018 sum = 0; 2019 count = xmlTextWriterStartAttribute(writer, name); 2020 if (count < 0) 2021 return -1; 2022 sum += count; 2023 count = xmlTextWriterWriteString(writer, content); 2024 if (count < 0) 2025 return -1; 2026 sum += count; 2027 count = xmlTextWriterEndAttribute(writer); 2028 if (count < 0) 2029 return -1; 2030 sum += count; 2031 2032 return sum; 2033} 2034 2035/** 2036 * xmlTextWriterWriteFormatAttributeNS: 2037 * @writer: the xmlTextWriterPtr 2038 * @prefix: namespace prefix 2039 * @name: attribute local name 2040 * @namespaceURI: namespace URI 2041 * @format: format string (see printf) 2042 * @...: extra parameters for the format 2043 * 2044 * Write a formatted xml attribute.with namespace support 2045 * 2046 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2047 */ 2048int XMLCDECL 2049xmlTextWriterWriteFormatAttributeNS(xmlTextWriterPtr writer, 2050 const xmlChar * prefix, 2051 const xmlChar * name, 2052 const xmlChar * namespaceURI, 2053 const char *format, ...) 2054{ 2055 int rc; 2056 va_list ap; 2057 2058 va_start(ap, format); 2059 2060 rc = xmlTextWriterWriteVFormatAttributeNS(writer, prefix, name, 2061 namespaceURI, format, ap); 2062 2063 va_end(ap); 2064 return rc; 2065} 2066 2067/** 2068 * xmlTextWriterWriteVFormatAttributeNS: 2069 * @writer: the xmlTextWriterPtr 2070 * @prefix: namespace prefix 2071 * @name: attribute local name 2072 * @namespaceURI: namespace URI 2073 * @format: format string (see printf) 2074 * @argptr: pointer to the first member of the variable argument list. 2075 * 2076 * Write a formatted xml attribute.with namespace support 2077 * 2078 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2079 */ 2080int 2081xmlTextWriterWriteVFormatAttributeNS(xmlTextWriterPtr writer, 2082 const xmlChar * prefix, 2083 const xmlChar * name, 2084 const xmlChar * namespaceURI, 2085 const char *format, va_list argptr) 2086{ 2087 int rc; 2088 xmlChar *buf; 2089 2090 if (writer == NULL) 2091 return -1; 2092 2093 buf = xmlTextWriterVSprintf(format, argptr); 2094 if (buf == 0) 2095 return 0; 2096 2097 rc = xmlTextWriterWriteAttributeNS(writer, prefix, name, namespaceURI, 2098 buf); 2099 2100 xmlFree(buf); 2101 return rc; 2102} 2103 2104/** 2105 * xmlTextWriterWriteAttributeNS: 2106 * @writer: the xmlTextWriterPtr 2107 * @prefix: namespace prefix 2108 * @name: attribute local name 2109 * @namespaceURI: namespace URI 2110 * @content: attribute content 2111 * 2112 * Write an xml attribute. 2113 * 2114 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2115 */ 2116int 2117xmlTextWriterWriteAttributeNS(xmlTextWriterPtr writer, 2118 const xmlChar * prefix, const xmlChar * name, 2119 const xmlChar * namespaceURI, 2120 const xmlChar * content) 2121{ 2122 int count; 2123 int sum; 2124 2125 if ((writer == NULL) || (name == NULL) || (*name == '\0')) 2126 return -1; 2127 2128 sum = 0; 2129 count = xmlTextWriterStartAttributeNS(writer, prefix, name, namespaceURI); 2130 if (count < 0) 2131 return -1; 2132 sum += count; 2133 count = xmlTextWriterWriteString(writer, content); 2134 if (count < 0) 2135 return -1; 2136 sum += count; 2137 count = xmlTextWriterEndAttribute(writer); 2138 if (count < 0) 2139 return -1; 2140 sum += count; 2141 2142 return sum; 2143} 2144 2145/** 2146 * xmlTextWriterWriteFormatElement: 2147 * @writer: the xmlTextWriterPtr 2148 * @name: element name 2149 * @format: format string (see printf) 2150 * @...: extra parameters for the format 2151 * 2152 * Write a formatted xml element. 2153 * 2154 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2155 */ 2156int XMLCDECL 2157xmlTextWriterWriteFormatElement(xmlTextWriterPtr writer, 2158 const xmlChar * name, const char *format, 2159 ...) 2160{ 2161 int rc; 2162 va_list ap; 2163 2164 va_start(ap, format); 2165 2166 rc = xmlTextWriterWriteVFormatElement(writer, name, format, ap); 2167 2168 va_end(ap); 2169 return rc; 2170} 2171 2172/** 2173 * xmlTextWriterWriteVFormatElement: 2174 * @writer: the xmlTextWriterPtr 2175 * @name: element name 2176 * @format: format string (see printf) 2177 * @argptr: pointer to the first member of the variable argument list. 2178 * 2179 * Write a formatted xml element. 2180 * 2181 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2182 */ 2183int 2184xmlTextWriterWriteVFormatElement(xmlTextWriterPtr writer, 2185 const xmlChar * name, const char *format, 2186 va_list argptr) 2187{ 2188 int rc; 2189 xmlChar *buf; 2190 2191 if (writer == NULL) 2192 return -1; 2193 2194 buf = xmlTextWriterVSprintf(format, argptr); 2195 if (buf == 0) 2196 return 0; 2197 2198 rc = xmlTextWriterWriteElement(writer, name, buf); 2199 2200 xmlFree(buf); 2201 return rc; 2202} 2203 2204/** 2205 * xmlTextWriterWriteElement: 2206 * @writer: the xmlTextWriterPtr 2207 * @name: element name 2208 * @content: element content 2209 * 2210 * Write an xml element. 2211 * 2212 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2213 */ 2214int 2215xmlTextWriterWriteElement(xmlTextWriterPtr writer, const xmlChar * name, 2216 const xmlChar * content) 2217{ 2218 int count; 2219 int sum; 2220 2221 sum = 0; 2222 count = xmlTextWriterStartElement(writer, name); 2223 if (count == -1) 2224 return -1; 2225 sum += count; 2226 count = xmlTextWriterWriteString(writer, content); 2227 if (count == -1) 2228 return -1; 2229 sum += count; 2230 count = xmlTextWriterEndElement(writer); 2231 if (count == -1) 2232 return -1; 2233 sum += count; 2234 2235 return sum; 2236} 2237 2238/** 2239 * xmlTextWriterWriteFormatElementNS: 2240 * @writer: the xmlTextWriterPtr 2241 * @prefix: namespace prefix 2242 * @name: element local name 2243 * @namespaceURI: namespace URI 2244 * @format: format string (see printf) 2245 * @...: extra parameters for the format 2246 * 2247 * Write a formatted xml element with namespace support. 2248 * 2249 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2250 */ 2251int XMLCDECL 2252xmlTextWriterWriteFormatElementNS(xmlTextWriterPtr writer, 2253 const xmlChar * prefix, 2254 const xmlChar * name, 2255 const xmlChar * namespaceURI, 2256 const char *format, ...) 2257{ 2258 int rc; 2259 va_list ap; 2260 2261 va_start(ap, format); 2262 2263 rc = xmlTextWriterWriteVFormatElementNS(writer, prefix, name, 2264 namespaceURI, format, ap); 2265 2266 va_end(ap); 2267 return rc; 2268} 2269 2270/** 2271 * xmlTextWriterWriteVFormatElementNS: 2272 * @writer: the xmlTextWriterPtr 2273 * @prefix: namespace prefix 2274 * @name: element local name 2275 * @namespaceURI: namespace URI 2276 * @format: format string (see printf) 2277 * @argptr: pointer to the first member of the variable argument list. 2278 * 2279 * Write a formatted xml element with namespace support. 2280 * 2281 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2282 */ 2283int 2284xmlTextWriterWriteVFormatElementNS(xmlTextWriterPtr writer, 2285 const xmlChar * prefix, 2286 const xmlChar * name, 2287 const xmlChar * namespaceURI, 2288 const char *format, va_list argptr) 2289{ 2290 int rc; 2291 xmlChar *buf; 2292 2293 if (writer == NULL) 2294 return -1; 2295 2296 buf = xmlTextWriterVSprintf(format, argptr); 2297 if (buf == 0) 2298 return 0; 2299 2300 rc = xmlTextWriterWriteElementNS(writer, prefix, name, namespaceURI, 2301 buf); 2302 2303 xmlFree(buf); 2304 return rc; 2305} 2306 2307/** 2308 * xmlTextWriterWriteElementNS: 2309 * @writer: the xmlTextWriterPtr 2310 * @prefix: namespace prefix 2311 * @name: element local name 2312 * @namespaceURI: namespace URI 2313 * @content: element content 2314 * 2315 * Write an xml element with namespace support. 2316 * 2317 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2318 */ 2319int 2320xmlTextWriterWriteElementNS(xmlTextWriterPtr writer, 2321 const xmlChar * prefix, const xmlChar * name, 2322 const xmlChar * namespaceURI, 2323 const xmlChar * content) 2324{ 2325 int count; 2326 int sum; 2327 2328 if ((writer == NULL) || (name == NULL) || (*name == '\0')) 2329 return -1; 2330 2331 sum = 0; 2332 count = 2333 xmlTextWriterStartElementNS(writer, prefix, name, namespaceURI); 2334 if (count < 0) 2335 return -1; 2336 sum += count; 2337 count = xmlTextWriterWriteString(writer, content); 2338 if (count == -1) 2339 return -1; 2340 sum += count; 2341 count = xmlTextWriterEndElement(writer); 2342 if (count == -1) 2343 return -1; 2344 sum += count; 2345 2346 return sum; 2347} 2348 2349/** 2350 * xmlTextWriterStartPI: 2351 * @writer: the xmlTextWriterPtr 2352 * @target: PI target 2353 * 2354 * Start an xml PI. 2355 * 2356 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2357 */ 2358int 2359xmlTextWriterStartPI(xmlTextWriterPtr writer, const xmlChar * target) 2360{ 2361 int count; 2362 int sum; 2363 xmlLinkPtr lk; 2364 xmlTextWriterStackEntry *p; 2365 2366 if ((writer == NULL) || (target == NULL) || (*target == '\0')) 2367 return -1; 2368 2369 if (xmlStrcasecmp(target, (const xmlChar *) "xml") == 0) { 2370 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 2371 "xmlTextWriterStartPI : target name [Xx][Mm][Ll] is reserved for xml standardization!\n"); 2372 return -1; 2373 } 2374 2375 sum = 0; 2376 lk = xmlListFront(writer->nodes); 2377 if (lk != 0) { 2378 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 2379 if (p != 0) { 2380 switch (p->state) { 2381 case XML_TEXTWRITER_ATTRIBUTE: 2382 count = xmlTextWriterEndAttribute(writer); 2383 if (count < 0) 2384 return -1; 2385 sum += count; 2386 /* fallthrough */ 2387 case XML_TEXTWRITER_NAME: 2388 /* Output namespace declarations */ 2389 count = xmlTextWriterOutputNSDecl(writer); 2390 if (count < 0) 2391 return -1; 2392 sum += count; 2393 count = xmlOutputBufferWriteString(writer->out, ">"); 2394 if (count < 0) 2395 return -1; 2396 sum += count; 2397 p->state = XML_TEXTWRITER_TEXT; 2398 break; 2399 case XML_TEXTWRITER_NONE: 2400 case XML_TEXTWRITER_TEXT: 2401 case XML_TEXTWRITER_DTD: 2402 break; 2403 case XML_TEXTWRITER_PI: 2404 case XML_TEXTWRITER_PI_TEXT: 2405 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 2406 "xmlTextWriterStartPI : nested PI!\n"); 2407 return -1; 2408 default: 2409 return -1; 2410 } 2411 } 2412 } 2413 2414 p = (xmlTextWriterStackEntry *) 2415 xmlMalloc(sizeof(xmlTextWriterStackEntry)); 2416 if (p == 0) { 2417 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 2418 "xmlTextWriterStartPI : out of memory!\n"); 2419 return -1; 2420 } 2421 2422 p->name = xmlStrdup(target); 2423 if (p->name == 0) { 2424 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 2425 "xmlTextWriterStartPI : out of memory!\n"); 2426 xmlFree(p); 2427 return -1; 2428 } 2429 p->state = XML_TEXTWRITER_PI; 2430 2431 xmlListPushFront(writer->nodes, p); 2432 2433 count = xmlOutputBufferWriteString(writer->out, "<?"); 2434 if (count < 0) 2435 return -1; 2436 sum += count; 2437 count = 2438 xmlOutputBufferWriteString(writer->out, (const char *) p->name); 2439 if (count < 0) 2440 return -1; 2441 sum += count; 2442 2443 return sum; 2444} 2445 2446/** 2447 * xmlTextWriterEndPI: 2448 * @writer: the xmlTextWriterPtr 2449 * 2450 * End the current xml PI. 2451 * 2452 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2453 */ 2454int 2455xmlTextWriterEndPI(xmlTextWriterPtr writer) 2456{ 2457 int count; 2458 int sum; 2459 xmlLinkPtr lk; 2460 xmlTextWriterStackEntry *p; 2461 2462 if (writer == NULL) 2463 return -1; 2464 2465 lk = xmlListFront(writer->nodes); 2466 if (lk == 0) 2467 return 0; 2468 2469 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 2470 if (p == 0) 2471 return 0; 2472 2473 sum = 0; 2474 switch (p->state) { 2475 case XML_TEXTWRITER_PI: 2476 case XML_TEXTWRITER_PI_TEXT: 2477 count = xmlOutputBufferWriteString(writer->out, "?>"); 2478 if (count < 0) 2479 return -1; 2480 sum += count; 2481 break; 2482 default: 2483 return -1; 2484 } 2485 2486 if (writer->indent) { 2487 count = xmlOutputBufferWriteString(writer->out, "\n"); 2488 if (count < 0) 2489 return -1; 2490 sum += count; 2491 } 2492 2493 xmlListPopFront(writer->nodes); 2494 return sum; 2495} 2496 2497/** 2498 * xmlTextWriterWriteFormatPI: 2499 * @writer: the xmlTextWriterPtr 2500 * @target: PI target 2501 * @format: format string (see printf) 2502 * @...: extra parameters for the format 2503 * 2504 * Write a formatted PI. 2505 * 2506 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2507 */ 2508int XMLCDECL 2509xmlTextWriterWriteFormatPI(xmlTextWriterPtr writer, const xmlChar * target, 2510 const char *format, ...) 2511{ 2512 int rc; 2513 va_list ap; 2514 2515 va_start(ap, format); 2516 2517 rc = xmlTextWriterWriteVFormatPI(writer, target, format, ap); 2518 2519 va_end(ap); 2520 return rc; 2521} 2522 2523/** 2524 * xmlTextWriterWriteVFormatPI: 2525 * @writer: the xmlTextWriterPtr 2526 * @target: PI target 2527 * @format: format string (see printf) 2528 * @argptr: pointer to the first member of the variable argument list. 2529 * 2530 * Write a formatted xml PI. 2531 * 2532 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2533 */ 2534int 2535xmlTextWriterWriteVFormatPI(xmlTextWriterPtr writer, 2536 const xmlChar * target, const char *format, 2537 va_list argptr) 2538{ 2539 int rc; 2540 xmlChar *buf; 2541 2542 if (writer == NULL) 2543 return -1; 2544 2545 buf = xmlTextWriterVSprintf(format, argptr); 2546 if (buf == 0) 2547 return 0; 2548 2549 rc = xmlTextWriterWritePI(writer, target, buf); 2550 2551 xmlFree(buf); 2552 return rc; 2553} 2554 2555/** 2556 * xmlTextWriterWritePI: 2557 * @writer: the xmlTextWriterPtr 2558 * @target: PI target 2559 * @content: PI content 2560 * 2561 * Write an xml PI. 2562 * 2563 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2564 */ 2565int 2566xmlTextWriterWritePI(xmlTextWriterPtr writer, const xmlChar * target, 2567 const xmlChar * content) 2568{ 2569 int count; 2570 int sum; 2571 2572 sum = 0; 2573 count = xmlTextWriterStartPI(writer, target); 2574 if (count == -1) 2575 return -1; 2576 sum += count; 2577 if (content != 0) { 2578 count = xmlTextWriterWriteString(writer, content); 2579 if (count == -1) 2580 return -1; 2581 sum += count; 2582 } 2583 count = xmlTextWriterEndPI(writer); 2584 if (count == -1) 2585 return -1; 2586 sum += count; 2587 2588 return sum; 2589} 2590 2591/** 2592 * xmlTextWriterStartCDATA: 2593 * @writer: the xmlTextWriterPtr 2594 * 2595 * Start an xml CDATA section. 2596 * 2597 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2598 */ 2599int 2600xmlTextWriterStartCDATA(xmlTextWriterPtr writer) 2601{ 2602 int count; 2603 int sum; 2604 xmlLinkPtr lk; 2605 xmlTextWriterStackEntry *p; 2606 2607 if (writer == NULL) 2608 return -1; 2609 2610 sum = 0; 2611 lk = xmlListFront(writer->nodes); 2612 if (lk != 0) { 2613 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 2614 if (p != 0) { 2615 switch (p->state) { 2616 case XML_TEXTWRITER_NONE: 2617 case XML_TEXTWRITER_TEXT: 2618 case XML_TEXTWRITER_PI: 2619 case XML_TEXTWRITER_PI_TEXT: 2620 break; 2621 case XML_TEXTWRITER_ATTRIBUTE: 2622 count = xmlTextWriterEndAttribute(writer); 2623 if (count < 0) 2624 return -1; 2625 sum += count; 2626 /* fallthrough */ 2627 case XML_TEXTWRITER_NAME: 2628 /* Output namespace declarations */ 2629 count = xmlTextWriterOutputNSDecl(writer); 2630 if (count < 0) 2631 return -1; 2632 sum += count; 2633 count = xmlOutputBufferWriteString(writer->out, ">"); 2634 if (count < 0) 2635 return -1; 2636 sum += count; 2637 p->state = XML_TEXTWRITER_TEXT; 2638 break; 2639 case XML_TEXTWRITER_CDATA: 2640 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 2641 "xmlTextWriterStartCDATA : CDATA not allowed in this context!\n"); 2642 return -1; 2643 default: 2644 return -1; 2645 } 2646 } 2647 } 2648 2649 p = (xmlTextWriterStackEntry *) 2650 xmlMalloc(sizeof(xmlTextWriterStackEntry)); 2651 if (p == 0) { 2652 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 2653 "xmlTextWriterStartCDATA : out of memory!\n"); 2654 return -1; 2655 } 2656 2657 p->name = NULL; 2658 p->state = XML_TEXTWRITER_CDATA; 2659 2660 xmlListPushFront(writer->nodes, p); 2661 2662 count = xmlOutputBufferWriteString(writer->out, "<![CDATA["); 2663 if (count < 0) 2664 return -1; 2665 sum += count; 2666 2667 return sum; 2668} 2669 2670/** 2671 * xmlTextWriterEndCDATA: 2672 * @writer: the xmlTextWriterPtr 2673 * 2674 * End an xml CDATA section. 2675 * 2676 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2677 */ 2678int 2679xmlTextWriterEndCDATA(xmlTextWriterPtr writer) 2680{ 2681 int count; 2682 int sum; 2683 xmlLinkPtr lk; 2684 xmlTextWriterStackEntry *p; 2685 2686 if (writer == NULL) 2687 return -1; 2688 2689 lk = xmlListFront(writer->nodes); 2690 if (lk == 0) 2691 return -1; 2692 2693 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 2694 if (p == 0) 2695 return -1; 2696 2697 sum = 0; 2698 switch (p->state) { 2699 case XML_TEXTWRITER_CDATA: 2700 count = xmlOutputBufferWriteString(writer->out, "]]>"); 2701 if (count < 0) 2702 return -1; 2703 sum += count; 2704 break; 2705 default: 2706 return -1; 2707 } 2708 2709 xmlListPopFront(writer->nodes); 2710 return sum; 2711} 2712 2713/** 2714 * xmlTextWriterWriteFormatCDATA: 2715 * @writer: the xmlTextWriterPtr 2716 * @format: format string (see printf) 2717 * @...: extra parameters for the format 2718 * 2719 * Write a formatted xml CDATA. 2720 * 2721 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2722 */ 2723int XMLCDECL 2724xmlTextWriterWriteFormatCDATA(xmlTextWriterPtr writer, const char *format, 2725 ...) 2726{ 2727 int rc; 2728 va_list ap; 2729 2730 va_start(ap, format); 2731 2732 rc = xmlTextWriterWriteVFormatCDATA(writer, format, ap); 2733 2734 va_end(ap); 2735 return rc; 2736} 2737 2738/** 2739 * xmlTextWriterWriteVFormatCDATA: 2740 * @writer: the xmlTextWriterPtr 2741 * @format: format string (see printf) 2742 * @argptr: pointer to the first member of the variable argument list. 2743 * 2744 * Write a formatted xml CDATA. 2745 * 2746 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2747 */ 2748int 2749xmlTextWriterWriteVFormatCDATA(xmlTextWriterPtr writer, const char *format, 2750 va_list argptr) 2751{ 2752 int rc; 2753 xmlChar *buf; 2754 2755 if (writer == NULL) 2756 return -1; 2757 2758 buf = xmlTextWriterVSprintf(format, argptr); 2759 if (buf == 0) 2760 return 0; 2761 2762 rc = xmlTextWriterWriteCDATA(writer, buf); 2763 2764 xmlFree(buf); 2765 return rc; 2766} 2767 2768/** 2769 * xmlTextWriterWriteCDATA: 2770 * @writer: the xmlTextWriterPtr 2771 * @content: CDATA content 2772 * 2773 * Write an xml CDATA. 2774 * 2775 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2776 */ 2777int 2778xmlTextWriterWriteCDATA(xmlTextWriterPtr writer, const xmlChar * content) 2779{ 2780 int count; 2781 int sum; 2782 2783 sum = 0; 2784 count = xmlTextWriterStartCDATA(writer); 2785 if (count == -1) 2786 return -1; 2787 sum += count; 2788 if (content != 0) { 2789 count = xmlTextWriterWriteString(writer, content); 2790 if (count == -1) 2791 return -1; 2792 sum += count; 2793 } 2794 count = xmlTextWriterEndCDATA(writer); 2795 if (count == -1) 2796 return -1; 2797 sum += count; 2798 2799 return sum; 2800} 2801 2802/** 2803 * xmlTextWriterStartDTD: 2804 * @writer: the xmlTextWriterPtr 2805 * @name: the name of the DTD 2806 * @pubid: the public identifier, which is an alternative to the system identifier 2807 * @sysid: the system identifier, which is the URI of the DTD 2808 * 2809 * Start an xml DTD. 2810 * 2811 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2812 */ 2813int 2814xmlTextWriterStartDTD(xmlTextWriterPtr writer, 2815 const xmlChar * name, 2816 const xmlChar * pubid, const xmlChar * sysid) 2817{ 2818 int count; 2819 int sum; 2820 xmlLinkPtr lk; 2821 xmlTextWriterStackEntry *p; 2822 2823 if (writer == NULL || name == NULL || *name == '\0') 2824 return -1; 2825 2826 sum = 0; 2827 lk = xmlListFront(writer->nodes); 2828 if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) { 2829 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 2830 "xmlTextWriterStartDTD : DTD allowed only in prolog!\n"); 2831 return -1; 2832 } 2833 2834 p = (xmlTextWriterStackEntry *) 2835 xmlMalloc(sizeof(xmlTextWriterStackEntry)); 2836 if (p == 0) { 2837 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 2838 "xmlTextWriterStartDTD : out of memory!\n"); 2839 return -1; 2840 } 2841 2842 p->name = xmlStrdup(name); 2843 if (p->name == 0) { 2844 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 2845 "xmlTextWriterStartDTD : out of memory!\n"); 2846 xmlFree(p); 2847 return -1; 2848 } 2849 p->state = XML_TEXTWRITER_DTD; 2850 2851 xmlListPushFront(writer->nodes, p); 2852 2853 count = xmlOutputBufferWriteString(writer->out, "<!DOCTYPE "); 2854 if (count < 0) 2855 return -1; 2856 sum += count; 2857 count = xmlOutputBufferWriteString(writer->out, (const char *) name); 2858 if (count < 0) 2859 return -1; 2860 sum += count; 2861 2862 if (pubid != 0) { 2863 if (sysid == 0) { 2864 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 2865 "xmlTextWriterStartDTD : system identifier needed!\n"); 2866 return -1; 2867 } 2868 2869 if (writer->indent) 2870 count = xmlOutputBufferWrite(writer->out, 1, "\n"); 2871 else 2872 count = xmlOutputBufferWrite(writer->out, 1, " "); 2873 if (count < 0) 2874 return -1; 2875 sum += count; 2876 2877 count = xmlOutputBufferWriteString(writer->out, "PUBLIC "); 2878 if (count < 0) 2879 return -1; 2880 sum += count; 2881 2882 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 2883 if (count < 0) 2884 return -1; 2885 sum += count; 2886 2887 count = 2888 xmlOutputBufferWriteString(writer->out, (const char *) pubid); 2889 if (count < 0) 2890 return -1; 2891 sum += count; 2892 2893 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 2894 if (count < 0) 2895 return -1; 2896 sum += count; 2897 } 2898 2899 if (sysid != 0) { 2900 if (pubid == 0) { 2901 if (writer->indent) 2902 count = xmlOutputBufferWrite(writer->out, 1, "\n"); 2903 else 2904 count = xmlOutputBufferWrite(writer->out, 1, " "); 2905 if (count < 0) 2906 return -1; 2907 sum += count; 2908 count = xmlOutputBufferWriteString(writer->out, "SYSTEM "); 2909 if (count < 0) 2910 return -1; 2911 sum += count; 2912 } else { 2913 if (writer->indent) 2914 count = xmlOutputBufferWriteString(writer->out, "\n "); 2915 else 2916 count = xmlOutputBufferWrite(writer->out, 1, " "); 2917 if (count < 0) 2918 return -1; 2919 sum += count; 2920 } 2921 2922 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 2923 if (count < 0) 2924 return -1; 2925 sum += count; 2926 2927 count = 2928 xmlOutputBufferWriteString(writer->out, (const char *) sysid); 2929 if (count < 0) 2930 return -1; 2931 sum += count; 2932 2933 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 2934 if (count < 0) 2935 return -1; 2936 sum += count; 2937 } 2938 2939 return sum; 2940} 2941 2942/** 2943 * xmlTextWriterEndDTD: 2944 * @writer: the xmlTextWriterPtr 2945 * 2946 * End an xml DTD. 2947 * 2948 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 2949 */ 2950int 2951xmlTextWriterEndDTD(xmlTextWriterPtr writer) 2952{ 2953 int loop; 2954 int count; 2955 int sum; 2956 xmlLinkPtr lk; 2957 xmlTextWriterStackEntry *p; 2958 2959 if (writer == NULL) 2960 return -1; 2961 2962 sum = 0; 2963 loop = 1; 2964 while (loop) { 2965 lk = xmlListFront(writer->nodes); 2966 if (lk == NULL) 2967 break; 2968 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 2969 if (p == 0) 2970 break; 2971 switch (p->state) { 2972 case XML_TEXTWRITER_DTD_TEXT: 2973 count = xmlOutputBufferWriteString(writer->out, "]"); 2974 if (count < 0) 2975 return -1; 2976 sum += count; 2977 /* fallthrough */ 2978 case XML_TEXTWRITER_DTD: 2979 count = xmlOutputBufferWriteString(writer->out, ">"); 2980 2981 if (writer->indent) { 2982 if (count < 0) 2983 return -1; 2984 sum += count; 2985 count = xmlOutputBufferWriteString(writer->out, "\n"); 2986 } 2987 2988 xmlListPopFront(writer->nodes); 2989 break; 2990 case XML_TEXTWRITER_DTD_ELEM: 2991 case XML_TEXTWRITER_DTD_ELEM_TEXT: 2992 count = xmlTextWriterEndDTDElement(writer); 2993 break; 2994 case XML_TEXTWRITER_DTD_ATTL: 2995 case XML_TEXTWRITER_DTD_ATTL_TEXT: 2996 count = xmlTextWriterEndDTDAttlist(writer); 2997 break; 2998 case XML_TEXTWRITER_DTD_ENTY: 2999 case XML_TEXTWRITER_DTD_PENT: 3000 case XML_TEXTWRITER_DTD_ENTY_TEXT: 3001 count = xmlTextWriterEndDTDEntity(writer); 3002 break; 3003 case XML_TEXTWRITER_COMMENT: 3004 count = xmlTextWriterEndComment(writer); 3005 break; 3006 default: 3007 loop = 0; 3008 continue; 3009 } 3010 3011 if (count < 0) 3012 return -1; 3013 sum += count; 3014 } 3015 3016 return sum; 3017} 3018 3019/** 3020 * xmlTextWriterWriteFormatDTD: 3021 * @writer: the xmlTextWriterPtr 3022 * @name: the name of the DTD 3023 * @pubid: the public identifier, which is an alternative to the system identifier 3024 * @sysid: the system identifier, which is the URI of the DTD 3025 * @format: format string (see printf) 3026 * @...: extra parameters for the format 3027 * 3028 * Write a DTD with a formatted markup declarations part. 3029 * 3030 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3031 */ 3032int XMLCDECL 3033xmlTextWriterWriteFormatDTD(xmlTextWriterPtr writer, 3034 const xmlChar * name, 3035 const xmlChar * pubid, 3036 const xmlChar * sysid, const char *format, ...) 3037{ 3038 int rc; 3039 va_list ap; 3040 3041 va_start(ap, format); 3042 3043 rc = xmlTextWriterWriteVFormatDTD(writer, name, pubid, sysid, format, 3044 ap); 3045 3046 va_end(ap); 3047 return rc; 3048} 3049 3050/** 3051 * xmlTextWriterWriteVFormatDTD: 3052 * @writer: the xmlTextWriterPtr 3053 * @name: the name of the DTD 3054 * @pubid: the public identifier, which is an alternative to the system identifier 3055 * @sysid: the system identifier, which is the URI of the DTD 3056 * @format: format string (see printf) 3057 * @argptr: pointer to the first member of the variable argument list. 3058 * 3059 * Write a DTD with a formatted markup declarations part. 3060 * 3061 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3062 */ 3063int 3064xmlTextWriterWriteVFormatDTD(xmlTextWriterPtr writer, 3065 const xmlChar * name, 3066 const xmlChar * pubid, 3067 const xmlChar * sysid, 3068 const char *format, va_list argptr) 3069{ 3070 int rc; 3071 xmlChar *buf; 3072 3073 if (writer == NULL) 3074 return -1; 3075 3076 buf = xmlTextWriterVSprintf(format, argptr); 3077 if (buf == 0) 3078 return 0; 3079 3080 rc = xmlTextWriterWriteDTD(writer, name, pubid, sysid, buf); 3081 3082 xmlFree(buf); 3083 return rc; 3084} 3085 3086/** 3087 * xmlTextWriterWriteDTD: 3088 * @writer: the xmlTextWriterPtr 3089 * @name: the name of the DTD 3090 * @pubid: the public identifier, which is an alternative to the system identifier 3091 * @sysid: the system identifier, which is the URI of the DTD 3092 * @subset: string content of the DTD 3093 * 3094 * Write a DTD. 3095 * 3096 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3097 */ 3098int 3099xmlTextWriterWriteDTD(xmlTextWriterPtr writer, 3100 const xmlChar * name, 3101 const xmlChar * pubid, 3102 const xmlChar * sysid, const xmlChar * subset) 3103{ 3104 int count; 3105 int sum; 3106 3107 sum = 0; 3108 count = xmlTextWriterStartDTD(writer, name, pubid, sysid); 3109 if (count == -1) 3110 return -1; 3111 sum += count; 3112 if (subset != 0) { 3113 count = xmlTextWriterWriteString(writer, subset); 3114 if (count == -1) 3115 return -1; 3116 sum += count; 3117 } 3118 count = xmlTextWriterEndDTD(writer); 3119 if (count == -1) 3120 return -1; 3121 sum += count; 3122 3123 return sum; 3124} 3125 3126/** 3127 * xmlTextWriterStartDTDElement: 3128 * @writer: the xmlTextWriterPtr 3129 * @name: the name of the DTD element 3130 * 3131 * Start an xml DTD element. 3132 * 3133 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3134 */ 3135int 3136xmlTextWriterStartDTDElement(xmlTextWriterPtr writer, const xmlChar * name) 3137{ 3138 int count; 3139 int sum; 3140 xmlLinkPtr lk; 3141 xmlTextWriterStackEntry *p; 3142 3143 if (writer == NULL || name == NULL || *name == '\0') 3144 return -1; 3145 3146 sum = 0; 3147 lk = xmlListFront(writer->nodes); 3148 if (lk == 0) { 3149 return -1; 3150 } 3151 3152 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 3153 if (p != 0) { 3154 switch (p->state) { 3155 case XML_TEXTWRITER_DTD: 3156 count = xmlOutputBufferWriteString(writer->out, " ["); 3157 if (count < 0) 3158 return -1; 3159 sum += count; 3160 if (writer->indent) { 3161 count = xmlOutputBufferWriteString(writer->out, "\n"); 3162 if (count < 0) 3163 return -1; 3164 sum += count; 3165 } 3166 p->state = XML_TEXTWRITER_DTD_TEXT; 3167 /* fallthrough */ 3168 case XML_TEXTWRITER_DTD_TEXT: 3169 case XML_TEXTWRITER_NONE: 3170 break; 3171 default: 3172 return -1; 3173 } 3174 } 3175 3176 p = (xmlTextWriterStackEntry *) 3177 xmlMalloc(sizeof(xmlTextWriterStackEntry)); 3178 if (p == 0) { 3179 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 3180 "xmlTextWriterStartDTDElement : out of memory!\n"); 3181 return -1; 3182 } 3183 3184 p->name = xmlStrdup(name); 3185 if (p->name == 0) { 3186 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 3187 "xmlTextWriterStartDTDElement : out of memory!\n"); 3188 xmlFree(p); 3189 return -1; 3190 } 3191 p->state = XML_TEXTWRITER_DTD_ELEM; 3192 3193 xmlListPushFront(writer->nodes, p); 3194 3195 if (writer->indent) { 3196 count = xmlTextWriterWriteIndent(writer); 3197 if (count < 0) 3198 return -1; 3199 sum += count; 3200 } 3201 3202 count = xmlOutputBufferWriteString(writer->out, "<!ELEMENT "); 3203 if (count < 0) 3204 return -1; 3205 sum += count; 3206 count = xmlOutputBufferWriteString(writer->out, (const char *) name); 3207 if (count < 0) 3208 return -1; 3209 sum += count; 3210 3211 return sum; 3212} 3213 3214/** 3215 * xmlTextWriterEndDTDElement: 3216 * @writer: the xmlTextWriterPtr 3217 * 3218 * End an xml DTD element. 3219 * 3220 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3221 */ 3222int 3223xmlTextWriterEndDTDElement(xmlTextWriterPtr writer) 3224{ 3225 int count; 3226 int sum; 3227 xmlLinkPtr lk; 3228 xmlTextWriterStackEntry *p; 3229 3230 if (writer == NULL) 3231 return -1; 3232 3233 sum = 0; 3234 lk = xmlListFront(writer->nodes); 3235 if (lk == 0) 3236 return -1; 3237 3238 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 3239 if (p == 0) 3240 return -1; 3241 3242 switch (p->state) { 3243 case XML_TEXTWRITER_DTD_ELEM: 3244 case XML_TEXTWRITER_DTD_ELEM_TEXT: 3245 count = xmlOutputBufferWriteString(writer->out, ">"); 3246 if (count < 0) 3247 return -1; 3248 sum += count; 3249 break; 3250 default: 3251 return -1; 3252 } 3253 3254 if (writer->indent) { 3255 count = xmlOutputBufferWriteString(writer->out, "\n"); 3256 if (count < 0) 3257 return -1; 3258 sum += count; 3259 } 3260 3261 xmlListPopFront(writer->nodes); 3262 return sum; 3263} 3264 3265/** 3266 * xmlTextWriterWriteFormatDTDElement: 3267 * @writer: the xmlTextWriterPtr 3268 * @name: the name of the DTD element 3269 * @format: format string (see printf) 3270 * @...: extra parameters for the format 3271 * 3272 * Write a formatted DTD element. 3273 * 3274 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3275 */ 3276int XMLCDECL 3277xmlTextWriterWriteFormatDTDElement(xmlTextWriterPtr writer, 3278 const xmlChar * name, 3279 const char *format, ...) 3280{ 3281 int rc; 3282 va_list ap; 3283 3284 va_start(ap, format); 3285 3286 rc = xmlTextWriterWriteVFormatDTDElement(writer, name, format, ap); 3287 3288 va_end(ap); 3289 return rc; 3290} 3291 3292/** 3293 * xmlTextWriterWriteVFormatDTDElement: 3294 * @writer: the xmlTextWriterPtr 3295 * @name: the name of the DTD element 3296 * @format: format string (see printf) 3297 * @argptr: pointer to the first member of the variable argument list. 3298 * 3299 * Write a formatted DTD element. 3300 * 3301 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3302 */ 3303int 3304xmlTextWriterWriteVFormatDTDElement(xmlTextWriterPtr writer, 3305 const xmlChar * name, 3306 const char *format, va_list argptr) 3307{ 3308 int rc; 3309 xmlChar *buf; 3310 3311 if (writer == NULL) 3312 return -1; 3313 3314 buf = xmlTextWriterVSprintf(format, argptr); 3315 if (buf == 0) 3316 return 0; 3317 3318 rc = xmlTextWriterWriteDTDElement(writer, name, buf); 3319 3320 xmlFree(buf); 3321 return rc; 3322} 3323 3324/** 3325 * xmlTextWriterWriteDTDElement: 3326 * @writer: the xmlTextWriterPtr 3327 * @name: the name of the DTD element 3328 * @content: content of the element 3329 * 3330 * Write a DTD element. 3331 * 3332 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3333 */ 3334int 3335xmlTextWriterWriteDTDElement(xmlTextWriterPtr writer, 3336 const xmlChar * name, const xmlChar * content) 3337{ 3338 int count; 3339 int sum; 3340 3341 if (content == NULL) 3342 return -1; 3343 3344 sum = 0; 3345 count = xmlTextWriterStartDTDElement(writer, name); 3346 if (count == -1) 3347 return -1; 3348 sum += count; 3349 3350 count = xmlTextWriterWriteString(writer, content); 3351 if (count == -1) 3352 return -1; 3353 sum += count; 3354 3355 count = xmlTextWriterEndDTDElement(writer); 3356 if (count == -1) 3357 return -1; 3358 sum += count; 3359 3360 return sum; 3361} 3362 3363/** 3364 * xmlTextWriterStartDTDAttlist: 3365 * @writer: the xmlTextWriterPtr 3366 * @name: the name of the DTD ATTLIST 3367 * 3368 * Start an xml DTD ATTLIST. 3369 * 3370 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3371 */ 3372int 3373xmlTextWriterStartDTDAttlist(xmlTextWriterPtr writer, const xmlChar * name) 3374{ 3375 int count; 3376 int sum; 3377 xmlLinkPtr lk; 3378 xmlTextWriterStackEntry *p; 3379 3380 if (writer == NULL || name == NULL || *name == '\0') 3381 return -1; 3382 3383 sum = 0; 3384 lk = xmlListFront(writer->nodes); 3385 if (lk == 0) { 3386 return -1; 3387 } 3388 3389 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 3390 if (p != 0) { 3391 switch (p->state) { 3392 case XML_TEXTWRITER_DTD: 3393 count = xmlOutputBufferWriteString(writer->out, " ["); 3394 if (count < 0) 3395 return -1; 3396 sum += count; 3397 if (writer->indent) { 3398 count = xmlOutputBufferWriteString(writer->out, "\n"); 3399 if (count < 0) 3400 return -1; 3401 sum += count; 3402 } 3403 p->state = XML_TEXTWRITER_DTD_TEXT; 3404 /* fallthrough */ 3405 case XML_TEXTWRITER_DTD_TEXT: 3406 case XML_TEXTWRITER_NONE: 3407 break; 3408 default: 3409 return -1; 3410 } 3411 } 3412 3413 p = (xmlTextWriterStackEntry *) 3414 xmlMalloc(sizeof(xmlTextWriterStackEntry)); 3415 if (p == 0) { 3416 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 3417 "xmlTextWriterStartDTDAttlist : out of memory!\n"); 3418 return -1; 3419 } 3420 3421 p->name = xmlStrdup(name); 3422 if (p->name == 0) { 3423 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 3424 "xmlTextWriterStartDTDAttlist : out of memory!\n"); 3425 xmlFree(p); 3426 return -1; 3427 } 3428 p->state = XML_TEXTWRITER_DTD_ATTL; 3429 3430 xmlListPushFront(writer->nodes, p); 3431 3432 if (writer->indent) { 3433 count = xmlTextWriterWriteIndent(writer); 3434 if (count < 0) 3435 return -1; 3436 sum += count; 3437 } 3438 3439 count = xmlOutputBufferWriteString(writer->out, "<!ATTLIST "); 3440 if (count < 0) 3441 return -1; 3442 sum += count; 3443 count = xmlOutputBufferWriteString(writer->out, (const char *) name); 3444 if (count < 0) 3445 return -1; 3446 sum += count; 3447 3448 return sum; 3449} 3450 3451/** 3452 * xmlTextWriterEndDTDAttlist: 3453 * @writer: the xmlTextWriterPtr 3454 * 3455 * End an xml DTD attribute list. 3456 * 3457 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3458 */ 3459int 3460xmlTextWriterEndDTDAttlist(xmlTextWriterPtr writer) 3461{ 3462 int count; 3463 int sum; 3464 xmlLinkPtr lk; 3465 xmlTextWriterStackEntry *p; 3466 3467 if (writer == NULL) 3468 return -1; 3469 3470 sum = 0; 3471 lk = xmlListFront(writer->nodes); 3472 if (lk == 0) 3473 return -1; 3474 3475 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 3476 if (p == 0) 3477 return -1; 3478 3479 switch (p->state) { 3480 case XML_TEXTWRITER_DTD_ATTL: 3481 case XML_TEXTWRITER_DTD_ATTL_TEXT: 3482 count = xmlOutputBufferWriteString(writer->out, ">"); 3483 if (count < 0) 3484 return -1; 3485 sum += count; 3486 break; 3487 default: 3488 return -1; 3489 } 3490 3491 if (writer->indent) { 3492 count = xmlOutputBufferWriteString(writer->out, "\n"); 3493 if (count < 0) 3494 return -1; 3495 sum += count; 3496 } 3497 3498 xmlListPopFront(writer->nodes); 3499 return sum; 3500} 3501 3502/** 3503 * xmlTextWriterWriteFormatDTDAttlist: 3504 * @writer: the xmlTextWriterPtr 3505 * @name: the name of the DTD ATTLIST 3506 * @format: format string (see printf) 3507 * @...: extra parameters for the format 3508 * 3509 * Write a formatted DTD ATTLIST. 3510 * 3511 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3512 */ 3513int XMLCDECL 3514xmlTextWriterWriteFormatDTDAttlist(xmlTextWriterPtr writer, 3515 const xmlChar * name, 3516 const char *format, ...) 3517{ 3518 int rc; 3519 va_list ap; 3520 3521 va_start(ap, format); 3522 3523 rc = xmlTextWriterWriteVFormatDTDAttlist(writer, name, format, ap); 3524 3525 va_end(ap); 3526 return rc; 3527} 3528 3529/** 3530 * xmlTextWriterWriteVFormatDTDAttlist: 3531 * @writer: the xmlTextWriterPtr 3532 * @name: the name of the DTD ATTLIST 3533 * @format: format string (see printf) 3534 * @argptr: pointer to the first member of the variable argument list. 3535 * 3536 * Write a formatted DTD ATTLIST. 3537 * 3538 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3539 */ 3540int 3541xmlTextWriterWriteVFormatDTDAttlist(xmlTextWriterPtr writer, 3542 const xmlChar * name, 3543 const char *format, va_list argptr) 3544{ 3545 int rc; 3546 xmlChar *buf; 3547 3548 if (writer == NULL) 3549 return -1; 3550 3551 buf = xmlTextWriterVSprintf(format, argptr); 3552 if (buf == 0) 3553 return 0; 3554 3555 rc = xmlTextWriterWriteDTDAttlist(writer, name, buf); 3556 3557 xmlFree(buf); 3558 return rc; 3559} 3560 3561/** 3562 * xmlTextWriterWriteDTDAttlist: 3563 * @writer: the xmlTextWriterPtr 3564 * @name: the name of the DTD ATTLIST 3565 * @content: content of the ATTLIST 3566 * 3567 * Write a DTD ATTLIST. 3568 * 3569 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3570 */ 3571int 3572xmlTextWriterWriteDTDAttlist(xmlTextWriterPtr writer, 3573 const xmlChar * name, const xmlChar * content) 3574{ 3575 int count; 3576 int sum; 3577 3578 if (content == NULL) 3579 return -1; 3580 3581 sum = 0; 3582 count = xmlTextWriterStartDTDAttlist(writer, name); 3583 if (count == -1) 3584 return -1; 3585 sum += count; 3586 3587 count = xmlTextWriterWriteString(writer, content); 3588 if (count == -1) 3589 return -1; 3590 sum += count; 3591 3592 count = xmlTextWriterEndDTDAttlist(writer); 3593 if (count == -1) 3594 return -1; 3595 sum += count; 3596 3597 return sum; 3598} 3599 3600/** 3601 * xmlTextWriterStartDTDEntity: 3602 * @writer: the xmlTextWriterPtr 3603 * @pe: TRUE if this is a parameter entity, FALSE if not 3604 * @name: the name of the DTD ATTLIST 3605 * 3606 * Start an xml DTD ATTLIST. 3607 * 3608 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3609 */ 3610int 3611xmlTextWriterStartDTDEntity(xmlTextWriterPtr writer, 3612 int pe, const xmlChar * name) 3613{ 3614 int count; 3615 int sum; 3616 xmlLinkPtr lk; 3617 xmlTextWriterStackEntry *p; 3618 3619 if (writer == NULL || name == NULL || *name == '\0') 3620 return -1; 3621 3622 sum = 0; 3623 lk = xmlListFront(writer->nodes); 3624 if (lk != 0) { 3625 3626 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 3627 if (p != 0) { 3628 switch (p->state) { 3629 case XML_TEXTWRITER_DTD: 3630 count = xmlOutputBufferWriteString(writer->out, " ["); 3631 if (count < 0) 3632 return -1; 3633 sum += count; 3634 if (writer->indent) { 3635 count = 3636 xmlOutputBufferWriteString(writer->out, "\n"); 3637 if (count < 0) 3638 return -1; 3639 sum += count; 3640 } 3641 p->state = XML_TEXTWRITER_DTD_TEXT; 3642 /* fallthrough */ 3643 case XML_TEXTWRITER_DTD_TEXT: 3644 case XML_TEXTWRITER_NONE: 3645 break; 3646 default: 3647 return -1; 3648 } 3649 } 3650 } 3651 3652 p = (xmlTextWriterStackEntry *) 3653 xmlMalloc(sizeof(xmlTextWriterStackEntry)); 3654 if (p == 0) { 3655 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 3656 "xmlTextWriterStartDTDElement : out of memory!\n"); 3657 return -1; 3658 } 3659 3660 p->name = xmlStrdup(name); 3661 if (p->name == 0) { 3662 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, 3663 "xmlTextWriterStartDTDElement : out of memory!\n"); 3664 xmlFree(p); 3665 return -1; 3666 } 3667 3668 if (pe != 0) 3669 p->state = XML_TEXTWRITER_DTD_PENT; 3670 else 3671 p->state = XML_TEXTWRITER_DTD_ENTY; 3672 3673 xmlListPushFront(writer->nodes, p); 3674 3675 if (writer->indent) { 3676 count = xmlTextWriterWriteIndent(writer); 3677 if (count < 0) 3678 return -1; 3679 sum += count; 3680 } 3681 3682 count = xmlOutputBufferWriteString(writer->out, "<!ENTITY "); 3683 if (count < 0) 3684 return -1; 3685 sum += count; 3686 3687 if (pe != 0) { 3688 count = xmlOutputBufferWriteString(writer->out, "% "); 3689 if (count < 0) 3690 return -1; 3691 sum += count; 3692 } 3693 3694 count = xmlOutputBufferWriteString(writer->out, (const char *) name); 3695 if (count < 0) 3696 return -1; 3697 sum += count; 3698 3699 return sum; 3700} 3701 3702/** 3703 * xmlTextWriterEndDTDEntity: 3704 * @writer: the xmlTextWriterPtr 3705 * 3706 * End an xml DTD entity. 3707 * 3708 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3709 */ 3710int 3711xmlTextWriterEndDTDEntity(xmlTextWriterPtr writer) 3712{ 3713 int count; 3714 int sum; 3715 xmlLinkPtr lk; 3716 xmlTextWriterStackEntry *p; 3717 3718 if (writer == NULL) 3719 return -1; 3720 3721 sum = 0; 3722 lk = xmlListFront(writer->nodes); 3723 if (lk == 0) 3724 return -1; 3725 3726 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 3727 if (p == 0) 3728 return -1; 3729 3730 switch (p->state) { 3731 case XML_TEXTWRITER_DTD_ENTY_TEXT: 3732 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 3733 if (count < 0) 3734 return -1; 3735 sum += count; 3736 case XML_TEXTWRITER_DTD_ENTY: 3737 case XML_TEXTWRITER_DTD_PENT: 3738 count = xmlOutputBufferWriteString(writer->out, ">"); 3739 if (count < 0) 3740 return -1; 3741 sum += count; 3742 break; 3743 default: 3744 return -1; 3745 } 3746 3747 if (writer->indent) { 3748 count = xmlOutputBufferWriteString(writer->out, "\n"); 3749 if (count < 0) 3750 return -1; 3751 sum += count; 3752 } 3753 3754 xmlListPopFront(writer->nodes); 3755 return sum; 3756} 3757 3758/** 3759 * xmlTextWriterWriteFormatDTDInternalEntity: 3760 * @writer: the xmlTextWriterPtr 3761 * @pe: TRUE if this is a parameter entity, FALSE if not 3762 * @name: the name of the DTD entity 3763 * @format: format string (see printf) 3764 * @...: extra parameters for the format 3765 * 3766 * Write a formatted DTD internal entity. 3767 * 3768 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3769 */ 3770int XMLCDECL 3771xmlTextWriterWriteFormatDTDInternalEntity(xmlTextWriterPtr writer, 3772 int pe, 3773 const xmlChar * name, 3774 const char *format, ...) 3775{ 3776 int rc; 3777 va_list ap; 3778 3779 va_start(ap, format); 3780 3781 rc = xmlTextWriterWriteVFormatDTDInternalEntity(writer, pe, name, 3782 format, ap); 3783 3784 va_end(ap); 3785 return rc; 3786} 3787 3788/** 3789 * xmlTextWriterWriteVFormatDTDInternalEntity: 3790 * @writer: the xmlTextWriterPtr 3791 * @pe: TRUE if this is a parameter entity, FALSE if not 3792 * @name: the name of the DTD entity 3793 * @format: format string (see printf) 3794 * @argptr: pointer to the first member of the variable argument list. 3795 * 3796 * Write a formatted DTD internal entity. 3797 * 3798 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3799 */ 3800int 3801xmlTextWriterWriteVFormatDTDInternalEntity(xmlTextWriterPtr writer, 3802 int pe, 3803 const xmlChar * name, 3804 const char *format, 3805 va_list argptr) 3806{ 3807 int rc; 3808 xmlChar *buf; 3809 3810 if (writer == NULL) 3811 return -1; 3812 3813 buf = xmlTextWriterVSprintf(format, argptr); 3814 if (buf == 0) 3815 return 0; 3816 3817 rc = xmlTextWriterWriteDTDInternalEntity(writer, pe, name, buf); 3818 3819 xmlFree(buf); 3820 return rc; 3821} 3822 3823/** 3824 * xmlTextWriterWriteDTDEntity: 3825 * @writer: the xmlTextWriterPtr 3826 * @pe: TRUE if this is a parameter entity, FALSE if not 3827 * @name: the name of the DTD entity 3828 * @pubid: the public identifier, which is an alternative to the system identifier 3829 * @sysid: the system identifier, which is the URI of the DTD 3830 * @ndataid: the xml notation name. 3831 * @content: content of the entity 3832 * 3833 * Write a DTD entity. 3834 * 3835 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3836 */ 3837int 3838xmlTextWriterWriteDTDEntity(xmlTextWriterPtr writer, 3839 int pe, 3840 const xmlChar * name, 3841 const xmlChar * pubid, 3842 const xmlChar * sysid, 3843 const xmlChar * ndataid, 3844 const xmlChar * content) 3845{ 3846 if ((content == NULL) && (pubid == NULL) && (sysid == NULL)) 3847 return -1; 3848 if ((pe != 0) && (ndataid != NULL)) 3849 return -1; 3850 3851 if ((pubid == NULL) && (sysid == NULL)) 3852 return xmlTextWriterWriteDTDInternalEntity(writer, pe, name, 3853 content); 3854 3855 return xmlTextWriterWriteDTDExternalEntity(writer, pe, name, pubid, 3856 sysid, ndataid); 3857} 3858 3859/** 3860 * xmlTextWriterWriteDTDInternalEntity: 3861 * @writer: the xmlTextWriterPtr 3862 * @pe: TRUE if this is a parameter entity, FALSE if not 3863 * @name: the name of the DTD entity 3864 * @content: content of the entity 3865 * 3866 * Write a DTD internal entity. 3867 * 3868 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3869 */ 3870int 3871xmlTextWriterWriteDTDInternalEntity(xmlTextWriterPtr writer, 3872 int pe, 3873 const xmlChar * name, 3874 const xmlChar * content) 3875{ 3876 int count; 3877 int sum; 3878 3879 if ((name == NULL) || (*name == '\0') || (content == NULL)) 3880 return -1; 3881 3882 sum = 0; 3883 count = xmlTextWriterStartDTDEntity(writer, pe, name); 3884 if (count == -1) 3885 return -1; 3886 sum += count; 3887 3888 count = xmlTextWriterWriteString(writer, content); 3889 if (count == -1) 3890 return -1; 3891 sum += count; 3892 3893 count = xmlTextWriterEndDTDEntity(writer); 3894 if (count == -1) 3895 return -1; 3896 sum += count; 3897 3898 return sum; 3899} 3900 3901/** 3902 * xmlTextWriterWriteDTDExternalEntity: 3903 * @writer: the xmlTextWriterPtr 3904 * @pe: TRUE if this is a parameter entity, FALSE if not 3905 * @name: the name of the DTD entity 3906 * @pubid: the public identifier, which is an alternative to the system identifier 3907 * @sysid: the system identifier, which is the URI of the DTD 3908 * @ndataid: the xml notation name. 3909 * 3910 * Write a DTD external entity. The entity must have been started with xmlTextWriterStartDTDEntity 3911 * 3912 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3913 */ 3914int 3915xmlTextWriterWriteDTDExternalEntity(xmlTextWriterPtr writer, 3916 int pe, 3917 const xmlChar * name, 3918 const xmlChar * pubid, 3919 const xmlChar * sysid, 3920 const xmlChar * ndataid) 3921{ 3922 int count; 3923 int sum; 3924 3925 if (((pubid == NULL) && (sysid == NULL))) 3926 return -1; 3927 if ((pe != 0) && (ndataid != NULL)) 3928 return -1; 3929 3930 sum = 0; 3931 count = xmlTextWriterStartDTDEntity(writer, pe, name); 3932 if (count == -1) 3933 return -1; 3934 sum += count; 3935 3936 count = 3937 xmlTextWriterWriteDTDExternalEntityContents(writer, pubid, sysid, 3938 ndataid); 3939 if (count < 0) 3940 return -1; 3941 sum += count; 3942 3943 count = xmlTextWriterEndDTDEntity(writer); 3944 if (count == -1) 3945 return -1; 3946 sum += count; 3947 3948 return sum; 3949} 3950 3951/** 3952 * xmlTextWriterWriteDTDExternalEntityContents: 3953 * @writer: the xmlTextWriterPtr 3954 * @pubid: the public identifier, which is an alternative to the system identifier 3955 * @sysid: the system identifier, which is the URI of the DTD 3956 * @ndataid: the xml notation name. 3957 * 3958 * Write the contents of a DTD external entity. 3959 * 3960 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 3961 */ 3962int 3963xmlTextWriterWriteDTDExternalEntityContents(xmlTextWriterPtr writer, 3964 const xmlChar * pubid, 3965 const xmlChar * sysid, 3966 const xmlChar * ndataid) 3967{ 3968 int count; 3969 int sum; 3970 xmlLinkPtr lk; 3971 xmlTextWriterStackEntry *p; 3972 3973 if (writer == NULL) { 3974 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 3975 "xmlTextWriterWriteDTDExternalEntityContents: xmlTextWriterPtr invalid!\n"); 3976 return -1; 3977 } 3978 3979 sum = 0; 3980 lk = xmlListFront(writer->nodes); 3981 if (lk == 0) { 3982 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 3983 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n"); 3984 return -1; 3985 } 3986 3987 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 3988 if (p == 0) 3989 return -1; 3990 3991 switch (p->state) { 3992 case XML_TEXTWRITER_DTD_ENTY: 3993 break; 3994 case XML_TEXTWRITER_DTD_PENT: 3995 if (ndataid != NULL) { 3996 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 3997 "xmlTextWriterWriteDTDExternalEntityContents: notation not allowed with parameter entities!\n"); 3998 return -1; 3999 } 4000 break; 4001 default: 4002 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 4003 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n"); 4004 return -1; 4005 } 4006 4007 if (pubid != 0) { 4008 if (sysid == 0) { 4009 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, 4010 "xmlTextWriterWriteDTDExternalEntityContents: system identifier needed!\n"); 4011 return -1; 4012 } 4013 4014 count = xmlOutputBufferWriteString(writer->out, " PUBLIC "); 4015 if (count < 0) 4016 return -1; 4017 sum += count; 4018 4019 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 4020 if (count < 0) 4021 return -1; 4022 sum += count; 4023 4024 count = 4025 xmlOutputBufferWriteString(writer->out, (const char *) pubid); 4026 if (count < 0) 4027 return -1; 4028 sum += count; 4029 4030 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 4031 if (count < 0) 4032 return -1; 4033 sum += count; 4034 } 4035 4036 if (sysid != 0) { 4037 if (pubid == 0) { 4038 count = xmlOutputBufferWriteString(writer->out, " SYSTEM"); 4039 if (count < 0) 4040 return -1; 4041 sum += count; 4042 } 4043 4044 count = xmlOutputBufferWriteString(writer->out, " "); 4045 if (count < 0) 4046 return -1; 4047 sum += count; 4048 4049 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 4050 if (count < 0) 4051 return -1; 4052 sum += count; 4053 4054 count = 4055 xmlOutputBufferWriteString(writer->out, (const char *) sysid); 4056 if (count < 0) 4057 return -1; 4058 sum += count; 4059 4060 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 4061 if (count < 0) 4062 return -1; 4063 sum += count; 4064 } 4065 4066 if (ndataid != NULL) { 4067 count = xmlOutputBufferWriteString(writer->out, " NDATA "); 4068 if (count < 0) 4069 return -1; 4070 sum += count; 4071 4072 count = 4073 xmlOutputBufferWriteString(writer->out, 4074 (const char *) ndataid); 4075 if (count < 0) 4076 return -1; 4077 sum += count; 4078 } 4079 4080 return sum; 4081} 4082 4083/** 4084 * xmlTextWriterWriteDTDNotation: 4085 * @writer: the xmlTextWriterPtr 4086 * @name: the name of the xml notation 4087 * @pubid: the public identifier, which is an alternative to the system identifier 4088 * @sysid: the system identifier, which is the URI of the DTD 4089 * 4090 * Write a DTD entity. 4091 * 4092 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 4093 */ 4094int 4095xmlTextWriterWriteDTDNotation(xmlTextWriterPtr writer, 4096 const xmlChar * name, 4097 const xmlChar * pubid, const xmlChar * sysid) 4098{ 4099 int count; 4100 int sum; 4101 xmlLinkPtr lk; 4102 xmlTextWriterStackEntry *p; 4103 4104 if (writer == NULL || name == NULL || *name == '\0') 4105 return -1; 4106 4107 sum = 0; 4108 lk = xmlListFront(writer->nodes); 4109 if (lk == 0) { 4110 return -1; 4111 } 4112 4113 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 4114 if (p != 0) { 4115 switch (p->state) { 4116 case XML_TEXTWRITER_DTD: 4117 count = xmlOutputBufferWriteString(writer->out, " ["); 4118 if (count < 0) 4119 return -1; 4120 sum += count; 4121 if (writer->indent) { 4122 count = xmlOutputBufferWriteString(writer->out, "\n"); 4123 if (count < 0) 4124 return -1; 4125 sum += count; 4126 } 4127 p->state = XML_TEXTWRITER_DTD_TEXT; 4128 /* fallthrough */ 4129 case XML_TEXTWRITER_DTD_TEXT: 4130 break; 4131 default: 4132 return -1; 4133 } 4134 } 4135 4136 if (writer->indent) { 4137 count = xmlTextWriterWriteIndent(writer); 4138 if (count < 0) 4139 return -1; 4140 sum += count; 4141 } 4142 4143 count = xmlOutputBufferWriteString(writer->out, "<!NOTATION "); 4144 if (count < 0) 4145 return -1; 4146 sum += count; 4147 count = xmlOutputBufferWriteString(writer->out, (const char *) name); 4148 if (count < 0) 4149 return -1; 4150 sum += count; 4151 4152 if (pubid != 0) { 4153 count = xmlOutputBufferWriteString(writer->out, " PUBLIC "); 4154 if (count < 0) 4155 return -1; 4156 sum += count; 4157 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 4158 if (count < 0) 4159 return -1; 4160 sum += count; 4161 count = 4162 xmlOutputBufferWriteString(writer->out, (const char *) pubid); 4163 if (count < 0) 4164 return -1; 4165 sum += count; 4166 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 4167 if (count < 0) 4168 return -1; 4169 sum += count; 4170 } 4171 4172 if (sysid != 0) { 4173 if (pubid == 0) { 4174 count = xmlOutputBufferWriteString(writer->out, " SYSTEM"); 4175 if (count < 0) 4176 return -1; 4177 sum += count; 4178 } 4179 count = xmlOutputBufferWriteString(writer->out, " "); 4180 if (count < 0) 4181 return -1; 4182 sum += count; 4183 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 4184 if (count < 0) 4185 return -1; 4186 sum += count; 4187 count = 4188 xmlOutputBufferWriteString(writer->out, (const char *) sysid); 4189 if (count < 0) 4190 return -1; 4191 sum += count; 4192 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); 4193 if (count < 0) 4194 return -1; 4195 sum += count; 4196 } 4197 4198 count = xmlOutputBufferWriteString(writer->out, ">"); 4199 if (count < 0) 4200 return -1; 4201 sum += count; 4202 4203 return sum; 4204} 4205 4206/** 4207 * xmlTextWriterFlush: 4208 * @writer: the xmlTextWriterPtr 4209 * 4210 * Flush the output buffer. 4211 * 4212 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error 4213 */ 4214int 4215xmlTextWriterFlush(xmlTextWriterPtr writer) 4216{ 4217 int count; 4218 4219 if (writer == NULL) 4220 return -1; 4221 4222 if (writer->out == NULL) 4223 count = 0; 4224 else 4225 count = xmlOutputBufferFlush(writer->out); 4226 4227 return count; 4228} 4229 4230/** 4231 * misc 4232 */ 4233 4234/** 4235 * xmlFreeTextWriterStackEntry: 4236 * @lk: the xmlLinkPtr 4237 * 4238 * Free callback for the xmlList. 4239 */ 4240static void 4241xmlFreeTextWriterStackEntry(xmlLinkPtr lk) 4242{ 4243 xmlTextWriterStackEntry *p; 4244 4245 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); 4246 if (p == 0) 4247 return; 4248 4249 if (p->name != 0) 4250 xmlFree(p->name); 4251 xmlFree(p); 4252} 4253 4254/** 4255 * xmlCmpTextWriterStackEntry: 4256 * @data0: the first data 4257 * @data1: the second data 4258 * 4259 * Compare callback for the xmlList. 4260 * 4261 * Returns -1, 0, 1 4262 */ 4263static int 4264xmlCmpTextWriterStackEntry(const void *data0, const void *data1) 4265{ 4266 xmlTextWriterStackEntry *p0; 4267 xmlTextWriterStackEntry *p1; 4268 4269 if (data0 == data1) 4270 return 0; 4271 4272 if (data0 == 0) 4273 return -1; 4274 4275 if (data1 == 0) 4276 return 1; 4277 4278 p0 = (xmlTextWriterStackEntry *) data0; 4279 p1 = (xmlTextWriterStackEntry *) data1; 4280 4281 return xmlStrcmp(p0->name, p1->name); 4282} 4283 4284/** 4285 * misc 4286 */ 4287 4288/** 4289 * xmlTextWriterOutputNSDecl: 4290 * @writer: the xmlTextWriterPtr 4291 * 4292 * Output the current namespace declarations. 4293 */ 4294static int 4295xmlTextWriterOutputNSDecl(xmlTextWriterPtr writer) 4296{ 4297 xmlLinkPtr lk; 4298 xmlTextWriterNsStackEntry *np; 4299 int count; 4300 int sum; 4301 4302 sum = 0; 4303 while (!xmlListEmpty(writer->nsstack)) { 4304 xmlChar *namespaceURI = NULL; 4305 xmlChar *prefix = NULL; 4306 4307 lk = xmlListFront(writer->nsstack); 4308 np = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk); 4309 4310 if (np != 0) { 4311 namespaceURI = xmlStrdup(np->uri); 4312 prefix = xmlStrdup(np->prefix); 4313 } 4314 4315 xmlListPopFront(writer->nsstack); 4316 4317 if (np != 0) { 4318 count = xmlTextWriterWriteAttribute(writer, prefix, namespaceURI); 4319 xmlFree(namespaceURI); 4320 xmlFree(prefix); 4321 4322 if (count < 0) { 4323 xmlListDelete(writer->nsstack); 4324 writer->nsstack = NULL; 4325 return -1; 4326 } 4327 sum += count; 4328 } 4329 } 4330 return sum; 4331} 4332 4333/** 4334 * xmlFreeTextWriterNsStackEntry: 4335 * @lk: the xmlLinkPtr 4336 * 4337 * Free callback for the xmlList. 4338 */ 4339static void 4340xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk) 4341{ 4342 xmlTextWriterNsStackEntry *p; 4343 4344 p = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk); 4345 if (p == 0) 4346 return; 4347 4348 if (p->prefix != 0) 4349 xmlFree(p->prefix); 4350 if (p->uri != 0) 4351 xmlFree(p->uri); 4352 4353 xmlFree(p); 4354} 4355 4356/** 4357 * xmlCmpTextWriterNsStackEntry: 4358 * @data0: the first data 4359 * @data1: the second data 4360 * 4361 * Compare callback for the xmlList. 4362 * 4363 * Returns -1, 0, 1 4364 */ 4365static int 4366xmlCmpTextWriterNsStackEntry(const void *data0, const void *data1) 4367{ 4368 xmlTextWriterNsStackEntry *p0; 4369 xmlTextWriterNsStackEntry *p1; 4370 int rc; 4371 4372 if (data0 == data1) 4373 return 0; 4374 4375 if (data0 == 0) 4376 return -1; 4377 4378 if (data1 == 0) 4379 return 1; 4380 4381 p0 = (xmlTextWriterNsStackEntry *) data0; 4382 p1 = (xmlTextWriterNsStackEntry *) data1; 4383 4384 rc = xmlStrcmp(p0->prefix, p1->prefix); 4385 4386 if ((rc != 0) || (p0->elem != p1->elem)) 4387 rc = -1; 4388 4389 return rc; 4390} 4391 4392/** 4393 * xmlTextWriterWriteDocCallback: 4394 * @context: the xmlBufferPtr 4395 * @str: the data to write 4396 * @len: the length of the data 4397 * 4398 * Write callback for the xmlOutputBuffer with target xmlBuffer 4399 * 4400 * Returns -1, 0, 1 4401 */ 4402static int 4403xmlTextWriterWriteDocCallback(void *context, const xmlChar * str, int len) 4404{ 4405 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context; 4406 int rc; 4407 4408 if ((rc = xmlParseChunk(ctxt, (const char *) str, len, 0)) != 0) { 4409 xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR, 4410 "xmlTextWriterWriteDocCallback : XML error %d !\n", 4411 rc); 4412 return -1; 4413 } 4414 4415 return len; 4416} 4417 4418/** 4419 * xmlTextWriterCloseDocCallback: 4420 * @context: the xmlBufferPtr 4421 * 4422 * Close callback for the xmlOutputBuffer with target xmlBuffer 4423 * 4424 * Returns -1, 0, 1 4425 */ 4426static int 4427xmlTextWriterCloseDocCallback(void *context) 4428{ 4429 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context; 4430 int rc; 4431 4432 if ((rc = xmlParseChunk(ctxt, NULL, 0, 1)) != 0) { 4433 xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR, 4434 "xmlTextWriterWriteDocCallback : XML error %d !\n", 4435 rc); 4436 return -1; 4437 } 4438 4439 return 0; 4440} 4441 4442/** 4443 * xmlTextWriterVSprintf: 4444 * @format: see printf 4445 * @argptr: pointer to the first member of the variable argument list. 4446 * 4447 * Utility function for formatted output 4448 * 4449 * Returns a new xmlChar buffer with the data or NULL on error. This buffer must be freed. 4450 */ 4451static xmlChar * 4452xmlTextWriterVSprintf(const char *format, va_list argptr) 4453{ 4454 int size; 4455 int count; 4456 xmlChar *buf; 4457 va_list locarg; 4458 4459 size = BUFSIZ; 4460 buf = (xmlChar *) xmlMalloc(size); 4461 if (buf == NULL) { 4462 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY, 4463 "xmlTextWriterVSprintf : out of memory!\n"); 4464 return NULL; 4465 } 4466 4467 VA_COPY(locarg, argptr); 4468 while (((count = vsnprintf((char *) buf, size, format, locarg)) < 0) 4469 || (count == size - 1) || (count == size) || (count > size)) { 4470 va_end(locarg); 4471 xmlFree(buf); 4472 size += BUFSIZ; 4473 buf = (xmlChar *) xmlMalloc(size); 4474 if (buf == NULL) { 4475 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY, 4476 "xmlTextWriterVSprintf : out of memory!\n"); 4477 return NULL; 4478 } 4479 VA_COPY(locarg, argptr); 4480 } 4481 va_end(locarg); 4482 4483 return buf; 4484} 4485 4486/** 4487 * xmlTextWriterStartDocumentCallback: 4488 * @ctx: the user data (XML parser context) 4489 * 4490 * called at the start of document processing. 4491 */ 4492static void 4493xmlTextWriterStartDocumentCallback(void *ctx) 4494{ 4495 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 4496 xmlDocPtr doc; 4497 4498 if (ctxt->html) { 4499#ifdef LIBXML_HTML_ENABLED 4500 if (ctxt->myDoc == NULL) 4501 ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL); 4502 if (ctxt->myDoc == NULL) { 4503 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 4504 ctxt->sax->error(ctxt->userData, 4505 "SAX.startDocument(): out of memory\n"); 4506 ctxt->errNo = XML_ERR_NO_MEMORY; 4507 ctxt->instate = XML_PARSER_EOF; 4508 ctxt->disableSAX = 1; 4509 return; 4510 } 4511#else 4512 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR, 4513 "libxml2 built without HTML support\n"); 4514 ctxt->errNo = XML_ERR_INTERNAL_ERROR; 4515 ctxt->instate = XML_PARSER_EOF; 4516 ctxt->disableSAX = 1; 4517 return; 4518#endif 4519 } else { 4520 doc = ctxt->myDoc; 4521 if (doc == NULL) 4522 doc = ctxt->myDoc = xmlNewDoc(ctxt->version); 4523 if (doc != NULL) { 4524 if (doc->children == NULL) { 4525 if (ctxt->encoding != NULL) 4526 doc->encoding = xmlStrdup(ctxt->encoding); 4527 else 4528 doc->encoding = NULL; 4529 doc->standalone = ctxt->standalone; 4530 } 4531 } else { 4532 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) 4533 ctxt->sax->error(ctxt->userData, 4534 "SAX.startDocument(): out of memory\n"); 4535 ctxt->errNo = XML_ERR_NO_MEMORY; 4536 ctxt->instate = XML_PARSER_EOF; 4537 ctxt->disableSAX = 1; 4538 return; 4539 } 4540 } 4541 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) && 4542 (ctxt->input != NULL) && (ctxt->input->filename != NULL)) { 4543 ctxt->myDoc->URL = 4544 xmlCanonicPath((const xmlChar *) ctxt->input->filename); 4545 if (ctxt->myDoc->URL == NULL) 4546 ctxt->myDoc->URL = 4547 xmlStrdup((const xmlChar *) ctxt->input->filename); 4548 } 4549} 4550 4551/** 4552 * xmlTextWriterSetIndent: 4553 * @writer: the xmlTextWriterPtr 4554 * @indent: do indentation? 4555 * 4556 * Set indentation output. indent = 0 do not indentation. indent > 0 do indentation. 4557 * 4558 * Returns -1 on error or 0 otherwise. 4559 */ 4560int 4561xmlTextWriterSetIndent(xmlTextWriterPtr writer, int indent) 4562{ 4563 if ((writer == NULL) || (indent < 0)) 4564 return -1; 4565 4566 writer->indent = indent; 4567 writer->doindent = 1; 4568 4569 return 0; 4570} 4571 4572/** 4573 * xmlTextWriterSetIndentString: 4574 * @writer: the xmlTextWriterPtr 4575 * @str: the xmlChar string 4576 * 4577 * Set string indentation. 4578 * 4579 * Returns -1 on error or 0 otherwise. 4580 */ 4581int 4582xmlTextWriterSetIndentString(xmlTextWriterPtr writer, const xmlChar * str) 4583{ 4584 if ((writer == NULL) || (!str)) 4585 return -1; 4586 4587 if (writer->ichar != NULL) 4588 xmlFree(writer->ichar); 4589 writer->ichar = xmlStrdup(str); 4590 4591 if (!writer->ichar) 4592 return -1; 4593 else 4594 return 0; 4595} 4596 4597/** 4598 * xmlTextWriterWriteIndent: 4599 * @writer: the xmlTextWriterPtr 4600 * 4601 * Write indent string. 4602 * 4603 * Returns -1 on error or the number of strings written. 4604 */ 4605static int 4606xmlTextWriterWriteIndent(xmlTextWriterPtr writer) 4607{ 4608 int lksize; 4609 int i; 4610 int ret; 4611 4612 lksize = xmlListSize(writer->nodes); 4613 if (lksize < 1) 4614 return (-1); /* list is empty */ 4615 for (i = 0; i < (lksize - 1); i++) { 4616 ret = xmlOutputBufferWriteString(writer->out, 4617 (const char *) writer->ichar); 4618 if (ret == -1) 4619 return (-1); 4620 } 4621 4622 return (lksize - 1); 4623} 4624 4625/** 4626 * xmlTextWriterHandleStateDependencies: 4627 * @writer: the xmlTextWriterPtr 4628 * @p: the xmlTextWriterStackEntry 4629 * 4630 * Write state dependent strings. 4631 * 4632 * Returns -1 on error or the number of characters written. 4633 */ 4634static int 4635xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer, 4636 xmlTextWriterStackEntry * p) 4637{ 4638 int count; 4639 int sum; 4640 char extra[3]; 4641 4642 if (writer == NULL) 4643 return -1; 4644 4645 if (p == NULL) 4646 return 0; 4647 4648 sum = 0; 4649 extra[0] = extra[1] = extra[2] = '\0'; 4650 if (p != 0) { 4651 sum = 0; 4652 switch (p->state) { 4653 case XML_TEXTWRITER_NAME: 4654 /* Output namespace declarations */ 4655 count = xmlTextWriterOutputNSDecl(writer); 4656 if (count < 0) 4657 return -1; 4658 sum += count; 4659 extra[0] = '>'; 4660 p->state = XML_TEXTWRITER_TEXT; 4661 break; 4662 case XML_TEXTWRITER_PI: 4663 extra[0] = ' '; 4664 p->state = XML_TEXTWRITER_PI_TEXT; 4665 break; 4666 case XML_TEXTWRITER_DTD: 4667 extra[0] = ' '; 4668 extra[1] = '['; 4669 p->state = XML_TEXTWRITER_DTD_TEXT; 4670 break; 4671 case XML_TEXTWRITER_DTD_ELEM: 4672 extra[0] = ' '; 4673 p->state = XML_TEXTWRITER_DTD_ELEM_TEXT; 4674 break; 4675 case XML_TEXTWRITER_DTD_ATTL: 4676 extra[0] = ' '; 4677 p->state = XML_TEXTWRITER_DTD_ATTL_TEXT; 4678 break; 4679 case XML_TEXTWRITER_DTD_ENTY: 4680 case XML_TEXTWRITER_DTD_PENT: 4681 extra[0] = ' '; 4682 extra[1] = writer->qchar; 4683 p->state = XML_TEXTWRITER_DTD_ENTY_TEXT; 4684 break; 4685 default: 4686 break; 4687 } 4688 } 4689 4690 if (*extra != '\0') { 4691 count = xmlOutputBufferWriteString(writer->out, extra); 4692 if (count < 0) 4693 return -1; 4694 sum += count; 4695 } 4696 4697 return sum; 4698} 4699 4700#define bottom_xmlwriter 4701#include "elfgcchack.h" 4702#endif 4703