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