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