Revert of Update the extension whitelist for application host change. (patchset ...
[chromium-blink-merge.git] / third_party / libxml / src / xmlwriter.c
blob11b15e03571e0973fcd697bdc67d0ff9cfcc824a
2 /*
3 * xmlwriter.c: XML text writer implementation
5 * For license and disclaimer see the license and disclaimer of
6 * libxml2.
8 * alfred@mickautsch.de
9 */
11 #define IN_LIBXML
12 #include "libxml.h"
13 #include <string.h>
15 #include <libxml/xmlmemory.h>
16 #include <libxml/parser.h>
17 #include <libxml/uri.h>
18 #include <libxml/HTMLtree.h>
20 #ifdef LIBXML_WRITER_ENABLED
22 #include <libxml/xmlwriter.h>
24 #define B64LINELEN 72
25 #define B64CRLF "\r\n"
28 * The following VA_COPY was coded following an example in
29 * the Samba project. It may not be sufficient for some
30 * esoteric implementations of va_list (i.e. it may need
31 * something involving a memcpy) but (hopefully) will be
32 * sufficient for libxml2.
34 #ifndef VA_COPY
35 #ifdef HAVE_VA_COPY
36 #define VA_COPY(dest, src) va_copy(dest, src)
37 #else
38 #ifdef HAVE___VA_COPY
39 #define VA_COPY(dest,src) __va_copy(dest, src)
40 #else
41 #define VA_COPY(dest,src) (dest) = (src)
42 #endif
43 #endif
44 #endif
47 * Types are kept private
49 typedef enum {
50 XML_TEXTWRITER_NONE = 0,
51 XML_TEXTWRITER_NAME,
52 XML_TEXTWRITER_ATTRIBUTE,
53 XML_TEXTWRITER_TEXT,
54 XML_TEXTWRITER_PI,
55 XML_TEXTWRITER_PI_TEXT,
56 XML_TEXTWRITER_CDATA,
57 XML_TEXTWRITER_DTD,
58 XML_TEXTWRITER_DTD_TEXT,
59 XML_TEXTWRITER_DTD_ELEM,
60 XML_TEXTWRITER_DTD_ELEM_TEXT,
61 XML_TEXTWRITER_DTD_ATTL,
62 XML_TEXTWRITER_DTD_ATTL_TEXT,
63 XML_TEXTWRITER_DTD_ENTY, /* entity */
64 XML_TEXTWRITER_DTD_ENTY_TEXT,
65 XML_TEXTWRITER_DTD_PENT, /* parameter entity */
66 XML_TEXTWRITER_COMMENT
67 } xmlTextWriterState;
69 typedef struct _xmlTextWriterStackEntry xmlTextWriterStackEntry;
71 struct _xmlTextWriterStackEntry {
72 xmlChar *name;
73 xmlTextWriterState state;
76 typedef struct _xmlTextWriterNsStackEntry xmlTextWriterNsStackEntry;
77 struct _xmlTextWriterNsStackEntry {
78 xmlChar *prefix;
79 xmlChar *uri;
80 xmlLinkPtr elem;
83 struct _xmlTextWriter {
84 xmlOutputBufferPtr out; /* output buffer */
85 xmlListPtr nodes; /* element name stack */
86 xmlListPtr nsstack; /* name spaces stack */
87 int level;
88 int indent; /* enable indent */
89 int doindent; /* internal indent flag */
90 xmlChar *ichar; /* indent character */
91 char qchar; /* character used for quoting attribute values */
92 xmlParserCtxtPtr ctxt;
93 int no_doc_free;
94 xmlDocPtr doc;
97 static void xmlFreeTextWriterStackEntry(xmlLinkPtr lk);
98 static int xmlCmpTextWriterStackEntry(const void *data0,
99 const void *data1);
100 static int xmlTextWriterOutputNSDecl(xmlTextWriterPtr writer);
101 static void xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk);
102 static int xmlCmpTextWriterNsStackEntry(const void *data0,
103 const void *data1);
104 static int xmlTextWriterWriteDocCallback(void *context,
105 const xmlChar * str, int len);
106 static int xmlTextWriterCloseDocCallback(void *context);
108 static xmlChar *xmlTextWriterVSprintf(const char *format, va_list argptr);
109 static int xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len,
110 const unsigned char *data);
111 static void xmlTextWriterStartDocumentCallback(void *ctx);
112 static int xmlTextWriterWriteIndent(xmlTextWriterPtr writer);
113 static int
114 xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer,
115 xmlTextWriterStackEntry * p);
118 * xmlWriterErrMsg:
119 * @ctxt: a writer context
120 * @error: the error number
121 * @msg: the error message
123 * Handle a writer error
125 static void
126 xmlWriterErrMsg(xmlTextWriterPtr ctxt, xmlParserErrors error,
127 const char *msg)
129 if (ctxt != NULL) {
130 __xmlRaiseError(NULL, NULL, NULL, ctxt->ctxt,
131 NULL, XML_FROM_WRITER, error, XML_ERR_FATAL,
132 NULL, 0, NULL, NULL, NULL, 0, 0, "%s", msg);
133 } else {
134 __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_WRITER, error,
135 XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0, "%s", msg);
140 * xmlWriterErrMsgInt:
141 * @ctxt: a writer context
142 * @error: the error number
143 * @msg: the error message
144 * @val: an int
146 * Handle a writer error
148 static void
149 xmlWriterErrMsgInt(xmlTextWriterPtr ctxt, xmlParserErrors error,
150 const char *msg, int val)
152 if (ctxt != NULL) {
153 __xmlRaiseError(NULL, NULL, NULL, ctxt->ctxt,
154 NULL, XML_FROM_WRITER, error, XML_ERR_FATAL,
155 NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
156 } else {
157 __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_WRITER, error,
158 XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
163 * xmlNewTextWriter:
164 * @out: an xmlOutputBufferPtr
166 * Create a new xmlNewTextWriter structure using an xmlOutputBufferPtr
167 * NOTE: the @out parameter will be deallocated when the writer is closed
168 * (if the call succeed.)
170 * Returns the new xmlTextWriterPtr or NULL in case of error
172 xmlTextWriterPtr
173 xmlNewTextWriter(xmlOutputBufferPtr out)
175 xmlTextWriterPtr ret;
177 ret = (xmlTextWriterPtr) xmlMalloc(sizeof(xmlTextWriter));
178 if (ret == NULL) {
179 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
180 "xmlNewTextWriter : out of memory!\n");
181 return NULL;
183 memset(ret, 0, (size_t) sizeof(xmlTextWriter));
185 ret->nodes = xmlListCreate((xmlListDeallocator)
186 xmlFreeTextWriterStackEntry,
187 (xmlListDataCompare)
188 xmlCmpTextWriterStackEntry);
189 if (ret->nodes == NULL) {
190 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
191 "xmlNewTextWriter : out of memory!\n");
192 xmlFree(ret);
193 return NULL;
196 ret->nsstack = xmlListCreate((xmlListDeallocator)
197 xmlFreeTextWriterNsStackEntry,
198 (xmlListDataCompare)
199 xmlCmpTextWriterNsStackEntry);
200 if (ret->nsstack == NULL) {
201 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
202 "xmlNewTextWriter : out of memory!\n");
203 xmlListDelete(ret->nodes);
204 xmlFree(ret);
205 return NULL;
208 ret->out = out;
209 ret->ichar = xmlStrdup(BAD_CAST " ");
210 ret->qchar = '"';
212 if (!ret->ichar) {
213 xmlListDelete(ret->nodes);
214 xmlListDelete(ret->nsstack);
215 xmlFree(ret);
216 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
217 "xmlNewTextWriter : out of memory!\n");
218 return NULL;
221 ret->doc = xmlNewDoc(NULL);
223 ret->no_doc_free = 0;
225 return ret;
229 * xmlNewTextWriterFilename:
230 * @uri: the URI of the resource for the output
231 * @compression: compress the output?
233 * Create a new xmlNewTextWriter structure with @uri as output
235 * Returns the new xmlTextWriterPtr or NULL in case of error
237 xmlTextWriterPtr
238 xmlNewTextWriterFilename(const char *uri, int compression)
240 xmlTextWriterPtr ret;
241 xmlOutputBufferPtr out;
243 out = xmlOutputBufferCreateFilename(uri, NULL, compression);
244 if (out == NULL) {
245 xmlWriterErrMsg(NULL, XML_IO_EIO,
246 "xmlNewTextWriterFilename : cannot open uri\n");
247 return NULL;
250 ret = xmlNewTextWriter(out);
251 if (ret == NULL) {
252 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
253 "xmlNewTextWriterFilename : out of memory!\n");
254 xmlOutputBufferClose(out);
255 return NULL;
258 ret->indent = 0;
259 ret->doindent = 0;
260 return ret;
264 * xmlNewTextWriterMemory:
265 * @buf: xmlBufferPtr
266 * @compression: compress the output?
268 * Create a new xmlNewTextWriter structure with @buf as output
269 * TODO: handle compression
271 * Returns the new xmlTextWriterPtr or NULL in case of error
273 xmlTextWriterPtr
274 xmlNewTextWriterMemory(xmlBufferPtr buf, int compression ATTRIBUTE_UNUSED)
276 xmlTextWriterPtr ret;
277 xmlOutputBufferPtr out;
279 /*::todo handle compression */
280 out = xmlOutputBufferCreateBuffer(buf, NULL);
282 if (out == NULL) {
283 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
284 "xmlNewTextWriterMemory : out of memory!\n");
285 return NULL;
288 ret = xmlNewTextWriter(out);
289 if (ret == NULL) {
290 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
291 "xmlNewTextWriterMemory : out of memory!\n");
292 xmlOutputBufferClose(out);
293 return NULL;
296 return ret;
300 * xmlNewTextWriterPushParser:
301 * @ctxt: xmlParserCtxtPtr to hold the new XML document tree
302 * @compression: compress the output?
304 * Create a new xmlNewTextWriter structure with @ctxt as output
305 * NOTE: the @ctxt context will be freed with the resulting writer
306 * (if the call succeeds).
307 * TODO: handle compression
309 * Returns the new xmlTextWriterPtr or NULL in case of error
311 xmlTextWriterPtr
312 xmlNewTextWriterPushParser(xmlParserCtxtPtr ctxt,
313 int compression ATTRIBUTE_UNUSED)
315 xmlTextWriterPtr ret;
316 xmlOutputBufferPtr out;
318 if (ctxt == NULL) {
319 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
320 "xmlNewTextWriterPushParser : invalid context!\n");
321 return NULL;
324 out = xmlOutputBufferCreateIO((xmlOutputWriteCallback)
325 xmlTextWriterWriteDocCallback,
326 (xmlOutputCloseCallback)
327 xmlTextWriterCloseDocCallback,
328 (void *) ctxt, NULL);
329 if (out == NULL) {
330 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
331 "xmlNewTextWriterPushParser : error at xmlOutputBufferCreateIO!\n");
332 return NULL;
335 ret = xmlNewTextWriter(out);
336 if (ret == NULL) {
337 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
338 "xmlNewTextWriterPushParser : error at xmlNewTextWriter!\n");
339 xmlOutputBufferClose(out);
340 return NULL;
343 ret->ctxt = ctxt;
345 return ret;
349 * xmlNewTextWriterDoc:
350 * @doc: address of a xmlDocPtr to hold the new XML document tree
351 * @compression: compress the output?
353 * Create a new xmlNewTextWriter structure with @*doc as output
355 * Returns the new xmlTextWriterPtr or NULL in case of error
357 xmlTextWriterPtr
358 xmlNewTextWriterDoc(xmlDocPtr * doc, int compression)
360 xmlTextWriterPtr ret;
361 xmlSAXHandler saxHandler;
362 xmlParserCtxtPtr ctxt;
364 memset(&saxHandler, '\0', sizeof(saxHandler));
365 xmlSAX2InitDefaultSAXHandler(&saxHandler, 1);
366 saxHandler.startDocument = xmlTextWriterStartDocumentCallback;
367 saxHandler.startElement = xmlSAX2StartElement;
368 saxHandler.endElement = xmlSAX2EndElement;
370 ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL);
371 if (ctxt == NULL) {
372 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
373 "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n");
374 return NULL;
377 * For some reason this seems to completely break if node names
378 * are interned.
380 ctxt->dictNames = 0;
382 ctxt->myDoc = xmlNewDoc(BAD_CAST XML_DEFAULT_VERSION);
383 if (ctxt->myDoc == NULL) {
384 xmlFreeParserCtxt(ctxt);
385 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
386 "xmlNewTextWriterDoc : error at xmlNewDoc!\n");
387 return NULL;
390 ret = xmlNewTextWriterPushParser(ctxt, compression);
391 if (ret == NULL) {
392 xmlFreeDoc(ctxt->myDoc);
393 xmlFreeParserCtxt(ctxt);
394 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
395 "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
396 return NULL;
399 xmlSetDocCompressMode(ctxt->myDoc, compression);
401 if (doc != NULL) {
402 *doc = ctxt->myDoc;
403 ret->no_doc_free = 1;
406 return ret;
410 * xmlNewTextWriterTree:
411 * @doc: xmlDocPtr
412 * @node: xmlNodePtr or NULL for doc->children
413 * @compression: compress the output?
415 * Create a new xmlNewTextWriter structure with @doc as output
416 * starting at @node
418 * Returns the new xmlTextWriterPtr or NULL in case of error
420 xmlTextWriterPtr
421 xmlNewTextWriterTree(xmlDocPtr doc, xmlNodePtr node, int compression)
423 xmlTextWriterPtr ret;
424 xmlSAXHandler saxHandler;
425 xmlParserCtxtPtr ctxt;
427 if (doc == NULL) {
428 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
429 "xmlNewTextWriterTree : invalid document tree!\n");
430 return NULL;
433 memset(&saxHandler, '\0', sizeof(saxHandler));
434 xmlSAX2InitDefaultSAXHandler(&saxHandler, 1);
435 saxHandler.startDocument = xmlTextWriterStartDocumentCallback;
436 saxHandler.startElement = xmlSAX2StartElement;
437 saxHandler.endElement = xmlSAX2EndElement;
439 ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL);
440 if (ctxt == NULL) {
441 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
442 "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n");
443 return NULL;
446 * For some reason this seems to completely break if node names
447 * are interned.
449 ctxt->dictNames = 0;
451 ret = xmlNewTextWriterPushParser(ctxt, compression);
452 if (ret == NULL) {
453 xmlFreeParserCtxt(ctxt);
454 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
455 "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
456 return NULL;
459 ctxt->myDoc = doc;
460 ctxt->node = node;
461 ret->no_doc_free = 1;
463 xmlSetDocCompressMode(doc, compression);
465 return ret;
469 * xmlFreeTextWriter:
470 * @writer: the xmlTextWriterPtr
472 * Deallocate all the resources associated to the writer
474 void
475 xmlFreeTextWriter(xmlTextWriterPtr writer)
477 if (writer == NULL)
478 return;
480 if (writer->out != NULL)
481 xmlOutputBufferClose(writer->out);
483 if (writer->nodes != NULL)
484 xmlListDelete(writer->nodes);
486 if (writer->nsstack != NULL)
487 xmlListDelete(writer->nsstack);
489 if (writer->ctxt != NULL) {
490 if ((writer->ctxt->myDoc != NULL) && (writer->no_doc_free == 0)) {
491 xmlFreeDoc(writer->ctxt->myDoc);
492 writer->ctxt->myDoc = NULL;
494 xmlFreeParserCtxt(writer->ctxt);
497 if (writer->doc != NULL)
498 xmlFreeDoc(writer->doc);
500 if (writer->ichar != NULL)
501 xmlFree(writer->ichar);
502 xmlFree(writer);
506 * xmlTextWriterStartDocument:
507 * @writer: the xmlTextWriterPtr
508 * @version: the xml version ("1.0") or NULL for default ("1.0")
509 * @encoding: the encoding or NULL for default
510 * @standalone: "yes" or "no" or NULL for default
512 * Start a new xml document
514 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
517 xmlTextWriterStartDocument(xmlTextWriterPtr writer, const char *version,
518 const char *encoding, const char *standalone)
520 int count;
521 int sum;
522 xmlLinkPtr lk;
523 xmlCharEncodingHandlerPtr encoder;
525 if ((writer == NULL) || (writer->out == NULL)) {
526 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
527 "xmlTextWriterStartDocument : invalid writer!\n");
528 return -1;
531 lk = xmlListFront(writer->nodes);
532 if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) {
533 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
534 "xmlTextWriterStartDocument : not allowed in this context!\n");
535 return -1;
538 encoder = NULL;
539 if (encoding != NULL) {
540 encoder = xmlFindCharEncodingHandler(encoding);
541 if (encoder == NULL) {
542 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
543 "xmlTextWriterStartDocument : out of memory!\n");
544 return -1;
548 writer->out->encoder = encoder;
549 if (encoder != NULL) {
550 if (writer->out->conv == NULL) {
551 writer->out->conv = xmlBufferCreateSize(4000);
553 xmlCharEncOutFunc(encoder, writer->out->conv, NULL);
554 if ((writer->doc != NULL) && (writer->doc->encoding == NULL))
555 writer->doc->encoding = xmlStrdup((xmlChar *)writer->out->encoder->name);
556 } else
557 writer->out->conv = NULL;
559 sum = 0;
560 count = xmlOutputBufferWriteString(writer->out, "<?xml version=");
561 if (count < 0)
562 return -1;
563 sum += count;
564 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
565 if (count < 0)
566 return -1;
567 sum += count;
568 if (version != 0)
569 count = xmlOutputBufferWriteString(writer->out, version);
570 else
571 count = xmlOutputBufferWriteString(writer->out, "1.0");
572 if (count < 0)
573 return -1;
574 sum += count;
575 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
576 if (count < 0)
577 return -1;
578 sum += count;
579 if (writer->out->encoder != 0) {
580 count = xmlOutputBufferWriteString(writer->out, " encoding=");
581 if (count < 0)
582 return -1;
583 sum += count;
584 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
585 if (count < 0)
586 return -1;
587 sum += count;
588 count =
589 xmlOutputBufferWriteString(writer->out,
590 writer->out->encoder->name);
591 if (count < 0)
592 return -1;
593 sum += count;
594 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
595 if (count < 0)
596 return -1;
597 sum += count;
600 if (standalone != 0) {
601 count = xmlOutputBufferWriteString(writer->out, " standalone=");
602 if (count < 0)
603 return -1;
604 sum += count;
605 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
606 if (count < 0)
607 return -1;
608 sum += count;
609 count = xmlOutputBufferWriteString(writer->out, standalone);
610 if (count < 0)
611 return -1;
612 sum += count;
613 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
614 if (count < 0)
615 return -1;
616 sum += count;
619 count = xmlOutputBufferWriteString(writer->out, "?>\n");
620 if (count < 0)
621 return -1;
622 sum += count;
624 return sum;
628 * xmlTextWriterEndDocument:
629 * @writer: the xmlTextWriterPtr
631 * End an xml document. All open elements are closed, and
632 * the content is flushed to the output.
634 * Returns the bytes written or -1 in case of error
637 xmlTextWriterEndDocument(xmlTextWriterPtr writer)
639 int count;
640 int sum;
641 xmlLinkPtr lk;
642 xmlTextWriterStackEntry *p;
644 if (writer == NULL) {
645 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
646 "xmlTextWriterEndDocument : invalid writer!\n");
647 return -1;
650 sum = 0;
651 while ((lk = xmlListFront(writer->nodes)) != NULL) {
652 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
653 if (p == 0)
654 break;
655 switch (p->state) {
656 case XML_TEXTWRITER_NAME:
657 case XML_TEXTWRITER_ATTRIBUTE:
658 case XML_TEXTWRITER_TEXT:
659 count = xmlTextWriterEndElement(writer);
660 if (count < 0)
661 return -1;
662 sum += count;
663 break;
664 case XML_TEXTWRITER_PI:
665 case XML_TEXTWRITER_PI_TEXT:
666 count = xmlTextWriterEndPI(writer);
667 if (count < 0)
668 return -1;
669 sum += count;
670 break;
671 case XML_TEXTWRITER_CDATA:
672 count = xmlTextWriterEndCDATA(writer);
673 if (count < 0)
674 return -1;
675 sum += count;
676 break;
677 case XML_TEXTWRITER_DTD:
678 case XML_TEXTWRITER_DTD_TEXT:
679 case XML_TEXTWRITER_DTD_ELEM:
680 case XML_TEXTWRITER_DTD_ELEM_TEXT:
681 case XML_TEXTWRITER_DTD_ATTL:
682 case XML_TEXTWRITER_DTD_ATTL_TEXT:
683 case XML_TEXTWRITER_DTD_ENTY:
684 case XML_TEXTWRITER_DTD_ENTY_TEXT:
685 case XML_TEXTWRITER_DTD_PENT:
686 count = xmlTextWriterEndDTD(writer);
687 if (count < 0)
688 return -1;
689 sum += count;
690 break;
691 case XML_TEXTWRITER_COMMENT:
692 count = xmlTextWriterEndComment(writer);
693 if (count < 0)
694 return -1;
695 sum += count;
696 break;
697 default:
698 break;
702 if (!writer->indent) {
703 count = xmlOutputBufferWriteString(writer->out, "\n");
704 if (count < 0)
705 return -1;
706 sum += count;
709 sum += xmlTextWriterFlush(writer);
711 return sum;
715 * xmlTextWriterStartComment:
716 * @writer: the xmlTextWriterPtr
718 * Start an xml comment.
720 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
723 xmlTextWriterStartComment(xmlTextWriterPtr writer)
725 int count;
726 int sum;
727 xmlLinkPtr lk;
728 xmlTextWriterStackEntry *p;
730 if (writer == NULL) {
731 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
732 "xmlTextWriterStartComment : invalid writer!\n");
733 return -1;
736 sum = 0;
737 lk = xmlListFront(writer->nodes);
738 if (lk != 0) {
739 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
740 if (p != 0) {
741 switch (p->state) {
742 case XML_TEXTWRITER_TEXT:
743 case XML_TEXTWRITER_NONE:
744 break;
745 case XML_TEXTWRITER_NAME:
746 /* Output namespace declarations */
747 count = xmlTextWriterOutputNSDecl(writer);
748 if (count < 0)
749 return -1;
750 sum += count;
751 count = xmlOutputBufferWriteString(writer->out, ">");
752 if (count < 0)
753 return -1;
754 sum += count;
755 if (writer->indent) {
756 count =
757 xmlOutputBufferWriteString(writer->out, "\n");
758 if (count < 0)
759 return -1;
760 sum += count;
762 p->state = XML_TEXTWRITER_TEXT;
763 break;
764 default:
765 return -1;
770 p = (xmlTextWriterStackEntry *)
771 xmlMalloc(sizeof(xmlTextWriterStackEntry));
772 if (p == 0) {
773 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
774 "xmlTextWriterStartElement : out of memory!\n");
775 return -1;
778 p->name = NULL;
779 p->state = XML_TEXTWRITER_COMMENT;
781 xmlListPushFront(writer->nodes, p);
783 if (writer->indent) {
784 count = xmlTextWriterWriteIndent(writer);
785 if (count < 0)
786 return -1;
787 sum += count;
790 count = xmlOutputBufferWriteString(writer->out, "<!--");
791 if (count < 0)
792 return -1;
793 sum += count;
795 return sum;
799 * xmlTextWriterEndComment:
800 * @writer: the xmlTextWriterPtr
802 * End the current xml coment.
804 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
807 xmlTextWriterEndComment(xmlTextWriterPtr writer)
809 int count;
810 int sum;
811 xmlLinkPtr lk;
812 xmlTextWriterStackEntry *p;
814 if (writer == NULL) {
815 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
816 "xmlTextWriterEndComment : invalid writer!\n");
817 return -1;
820 lk = xmlListFront(writer->nodes);
821 if (lk == 0) {
822 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
823 "xmlTextWriterEndComment : not allowed in this context!\n");
824 return -1;
827 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
828 if (p == 0)
829 return -1;
831 sum = 0;
832 switch (p->state) {
833 case XML_TEXTWRITER_COMMENT:
834 count = xmlOutputBufferWriteString(writer->out, "-->");
835 if (count < 0)
836 return -1;
837 sum += count;
838 break;
839 default:
840 return -1;
843 if (writer->indent) {
844 count = xmlOutputBufferWriteString(writer->out, "\n");
845 if (count < 0)
846 return -1;
847 sum += count;
850 xmlListPopFront(writer->nodes);
851 return sum;
855 * xmlTextWriterWriteFormatComment:
856 * @writer: the xmlTextWriterPtr
857 * @format: format string (see printf)
858 * @...: extra parameters for the format
860 * Write an xml comment.
862 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
864 int XMLCDECL
865 xmlTextWriterWriteFormatComment(xmlTextWriterPtr writer,
866 const char *format, ...)
868 int rc;
869 va_list ap;
871 va_start(ap, format);
873 rc = xmlTextWriterWriteVFormatComment(writer, format, ap);
875 va_end(ap);
876 return rc;
880 * xmlTextWriterWriteVFormatComment:
881 * @writer: the xmlTextWriterPtr
882 * @format: format string (see printf)
883 * @argptr: pointer to the first member of the variable argument list.
885 * Write an xml comment.
887 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
890 xmlTextWriterWriteVFormatComment(xmlTextWriterPtr writer,
891 const char *format, va_list argptr)
893 int rc;
894 xmlChar *buf;
896 if (writer == NULL) {
897 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
898 "xmlTextWriterWriteVFormatComment : invalid writer!\n");
899 return -1;
902 buf = xmlTextWriterVSprintf(format, argptr);
903 if (buf == NULL)
904 return -1;
906 rc = xmlTextWriterWriteComment(writer, buf);
908 xmlFree(buf);
909 return rc;
913 * xmlTextWriterWriteComment:
914 * @writer: the xmlTextWriterPtr
915 * @content: comment string
917 * Write an xml comment.
919 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
922 xmlTextWriterWriteComment(xmlTextWriterPtr writer, const xmlChar * content)
924 int count;
925 int sum;
927 sum = 0;
928 count = xmlTextWriterStartComment(writer);
929 if (count < 0)
930 return -1;
931 sum += count;
932 count = xmlTextWriterWriteString(writer, content);
933 if (count < 0)
934 return -1;
935 sum += count;
936 count = xmlTextWriterEndComment(writer);
937 if (count < 0)
938 return -1;
939 sum += count;
941 return sum;
945 * xmlTextWriterStartElement:
946 * @writer: the xmlTextWriterPtr
947 * @name: element name
949 * Start an xml element.
951 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
954 xmlTextWriterStartElement(xmlTextWriterPtr writer, const xmlChar * name)
956 int count;
957 int sum;
958 xmlLinkPtr lk;
959 xmlTextWriterStackEntry *p;
961 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
962 return -1;
964 sum = 0;
965 lk = xmlListFront(writer->nodes);
966 if (lk != 0) {
967 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
968 if (p != 0) {
969 switch (p->state) {
970 case XML_TEXTWRITER_PI:
971 case XML_TEXTWRITER_PI_TEXT:
972 return -1;
973 case XML_TEXTWRITER_NONE:
974 break;
975 case XML_TEXTWRITER_ATTRIBUTE:
976 count = xmlTextWriterEndAttribute(writer);
977 if (count < 0)
978 return -1;
979 sum += count;
980 /* fallthrough */
981 case XML_TEXTWRITER_NAME:
982 /* Output namespace declarations */
983 count = xmlTextWriterOutputNSDecl(writer);
984 if (count < 0)
985 return -1;
986 sum += count;
987 count = xmlOutputBufferWriteString(writer->out, ">");
988 if (count < 0)
989 return -1;
990 sum += count;
991 if (writer->indent)
992 count =
993 xmlOutputBufferWriteString(writer->out, "\n");
994 p->state = XML_TEXTWRITER_TEXT;
995 break;
996 default:
997 break;
1002 p = (xmlTextWriterStackEntry *)
1003 xmlMalloc(sizeof(xmlTextWriterStackEntry));
1004 if (p == 0) {
1005 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
1006 "xmlTextWriterStartElement : out of memory!\n");
1007 return -1;
1010 p->name = xmlStrdup(name);
1011 if (p->name == 0) {
1012 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
1013 "xmlTextWriterStartElement : out of memory!\n");
1014 xmlFree(p);
1015 return -1;
1017 p->state = XML_TEXTWRITER_NAME;
1019 xmlListPushFront(writer->nodes, p);
1021 if (writer->indent) {
1022 count = xmlTextWriterWriteIndent(writer);
1023 sum += count;
1026 count = xmlOutputBufferWriteString(writer->out, "<");
1027 if (count < 0)
1028 return -1;
1029 sum += count;
1030 count =
1031 xmlOutputBufferWriteString(writer->out, (const char *) p->name);
1032 if (count < 0)
1033 return -1;
1034 sum += count;
1036 return sum;
1040 * xmlTextWriterStartElementNS:
1041 * @writer: the xmlTextWriterPtr
1042 * @prefix: namespace prefix or NULL
1043 * @name: element local name
1044 * @namespaceURI: namespace URI or NULL
1046 * Start an xml element with namespace support.
1048 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1051 xmlTextWriterStartElementNS(xmlTextWriterPtr writer,
1052 const xmlChar * prefix, const xmlChar * name,
1053 const xmlChar * namespaceURI)
1055 int count;
1056 int sum;
1057 xmlChar *buf;
1059 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1060 return -1;
1062 buf = NULL;
1063 if (prefix != 0) {
1064 buf = xmlStrdup(prefix);
1065 buf = xmlStrcat(buf, BAD_CAST ":");
1067 buf = xmlStrcat(buf, name);
1069 sum = 0;
1070 count = xmlTextWriterStartElement(writer, buf);
1071 xmlFree(buf);
1072 if (count < 0)
1073 return -1;
1074 sum += count;
1076 if (namespaceURI != 0) {
1077 xmlTextWriterNsStackEntry *p = (xmlTextWriterNsStackEntry *)
1078 xmlMalloc(sizeof(xmlTextWriterNsStackEntry));
1079 if (p == 0) {
1080 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
1081 "xmlTextWriterStartElementNS : out of memory!\n");
1082 return -1;
1085 buf = xmlStrdup(BAD_CAST "xmlns");
1086 if (prefix != 0) {
1087 buf = xmlStrcat(buf, BAD_CAST ":");
1088 buf = xmlStrcat(buf, prefix);
1091 p->prefix = buf;
1092 p->uri = xmlStrdup(namespaceURI);
1093 if (p->uri == 0) {
1094 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
1095 "xmlTextWriterStartElementNS : out of memory!\n");
1096 xmlFree(p);
1097 return -1;
1099 p->elem = xmlListFront(writer->nodes);
1101 xmlListPushFront(writer->nsstack, p);
1104 return sum;
1108 * xmlTextWriterEndElement:
1109 * @writer: the xmlTextWriterPtr
1111 * End the current xml element.
1113 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1116 xmlTextWriterEndElement(xmlTextWriterPtr writer)
1118 int count;
1119 int sum;
1120 xmlLinkPtr lk;
1121 xmlTextWriterStackEntry *p;
1123 if (writer == NULL)
1124 return -1;
1126 lk = xmlListFront(writer->nodes);
1127 if (lk == 0) {
1128 xmlListDelete(writer->nsstack);
1129 writer->nsstack = NULL;
1130 return -1;
1133 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1134 if (p == 0) {
1135 xmlListDelete(writer->nsstack);
1136 writer->nsstack = NULL;
1137 return -1;
1140 sum = 0;
1141 switch (p->state) {
1142 case XML_TEXTWRITER_ATTRIBUTE:
1143 count = xmlTextWriterEndAttribute(writer);
1144 if (count < 0) {
1145 xmlListDelete(writer->nsstack);
1146 writer->nsstack = NULL;
1147 return -1;
1149 sum += count;
1150 /* fallthrough */
1151 case XML_TEXTWRITER_NAME:
1152 /* Output namespace declarations */
1153 count = xmlTextWriterOutputNSDecl(writer);
1154 if (count < 0)
1155 return -1;
1156 sum += count;
1158 if (writer->indent) /* next element needs indent */
1159 writer->doindent = 1;
1160 count = xmlOutputBufferWriteString(writer->out, "/>");
1161 if (count < 0)
1162 return -1;
1163 sum += count;
1164 break;
1165 case XML_TEXTWRITER_TEXT:
1166 if ((writer->indent) && (writer->doindent)) {
1167 count = xmlTextWriterWriteIndent(writer);
1168 sum += count;
1169 writer->doindent = 1;
1170 } else
1171 writer->doindent = 1;
1172 count = xmlOutputBufferWriteString(writer->out, "</");
1173 if (count < 0)
1174 return -1;
1175 sum += count;
1176 count = xmlOutputBufferWriteString(writer->out,
1177 (const char *) p->name);
1178 if (count < 0)
1179 return -1;
1180 sum += count;
1181 count = xmlOutputBufferWriteString(writer->out, ">");
1182 if (count < 0)
1183 return -1;
1184 sum += count;
1185 break;
1186 default:
1187 return -1;
1190 if (writer->indent) {
1191 count = xmlOutputBufferWriteString(writer->out, "\n");
1192 sum += count;
1195 xmlListPopFront(writer->nodes);
1196 return sum;
1200 * xmlTextWriterFullEndElement:
1201 * @writer: the xmlTextWriterPtr
1203 * End the current xml element. Writes an end tag even if the element is empty
1205 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1208 xmlTextWriterFullEndElement(xmlTextWriterPtr writer)
1210 int count;
1211 int sum;
1212 xmlLinkPtr lk;
1213 xmlTextWriterStackEntry *p;
1215 if (writer == NULL)
1216 return -1;
1218 lk = xmlListFront(writer->nodes);
1219 if (lk == 0)
1220 return -1;
1222 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1223 if (p == 0)
1224 return -1;
1226 sum = 0;
1227 switch (p->state) {
1228 case XML_TEXTWRITER_ATTRIBUTE:
1229 count = xmlTextWriterEndAttribute(writer);
1230 if (count < 0)
1231 return -1;
1232 sum += count;
1233 /* fallthrough */
1234 case XML_TEXTWRITER_NAME:
1235 /* Output namespace declarations */
1236 count = xmlTextWriterOutputNSDecl(writer);
1237 if (count < 0)
1238 return -1;
1239 sum += count;
1241 count = xmlOutputBufferWriteString(writer->out, ">");
1242 if (count < 0)
1243 return -1;
1244 sum += count;
1245 if (writer->indent)
1246 writer->doindent = 0;
1247 /* fallthrough */
1248 case XML_TEXTWRITER_TEXT:
1249 if ((writer->indent) && (writer->doindent)) {
1250 count = xmlTextWriterWriteIndent(writer);
1251 sum += count;
1252 writer->doindent = 1;
1253 } else
1254 writer->doindent = 1;
1255 count = xmlOutputBufferWriteString(writer->out, "</");
1256 if (count < 0)
1257 return -1;
1258 sum += count;
1259 count = xmlOutputBufferWriteString(writer->out,
1260 (const char *) p->name);
1261 if (count < 0)
1262 return -1;
1263 sum += count;
1264 count = xmlOutputBufferWriteString(writer->out, ">");
1265 if (count < 0)
1266 return -1;
1267 sum += count;
1268 break;
1269 default:
1270 return -1;
1273 if (writer->indent) {
1274 count = xmlOutputBufferWriteString(writer->out, "\n");
1275 sum += count;
1278 xmlListPopFront(writer->nodes);
1279 return sum;
1283 * xmlTextWriterWriteFormatRaw:
1284 * @writer: the xmlTextWriterPtr
1285 * @format: format string (see printf)
1286 * @...: extra parameters for the format
1288 * Write a formatted raw xml text.
1290 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1292 int XMLCDECL
1293 xmlTextWriterWriteFormatRaw(xmlTextWriterPtr writer, const char *format,
1294 ...)
1296 int rc;
1297 va_list ap;
1299 va_start(ap, format);
1301 rc = xmlTextWriterWriteVFormatRaw(writer, format, ap);
1303 va_end(ap);
1304 return rc;
1308 * xmlTextWriterWriteVFormatRaw:
1309 * @writer: the xmlTextWriterPtr
1310 * @format: format string (see printf)
1311 * @argptr: pointer to the first member of the variable argument list.
1313 * Write a formatted raw xml text.
1315 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1318 xmlTextWriterWriteVFormatRaw(xmlTextWriterPtr writer, const char *format,
1319 va_list argptr)
1321 int rc;
1322 xmlChar *buf;
1324 if (writer == NULL)
1325 return -1;
1327 buf = xmlTextWriterVSprintf(format, argptr);
1328 if (buf == NULL)
1329 return -1;
1331 rc = xmlTextWriterWriteRaw(writer, buf);
1333 xmlFree(buf);
1334 return rc;
1338 * xmlTextWriterWriteRawLen:
1339 * @writer: the xmlTextWriterPtr
1340 * @content: text string
1341 * @len: length of the text string
1343 * Write an xml text.
1344 * TODO: what about entities and special chars??
1346 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1349 xmlTextWriterWriteRawLen(xmlTextWriterPtr writer, const xmlChar * content,
1350 int len)
1352 int count;
1353 int sum;
1354 xmlLinkPtr lk;
1355 xmlTextWriterStackEntry *p;
1357 if (writer == NULL) {
1358 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
1359 "xmlTextWriterWriteRawLen : invalid writer!\n");
1360 return -1;
1363 if ((content == NULL) || (len < 0)) {
1364 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
1365 "xmlTextWriterWriteRawLen : invalid content!\n");
1366 return -1;
1369 sum = 0;
1370 lk = xmlListFront(writer->nodes);
1371 if (lk != 0) {
1372 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1373 count = xmlTextWriterHandleStateDependencies(writer, p);
1374 if (count < 0)
1375 return -1;
1376 sum += count;
1379 if (writer->indent)
1380 writer->doindent = 0;
1382 if (content != NULL) {
1383 count =
1384 xmlOutputBufferWrite(writer->out, len, (const char *) content);
1385 if (count < 0)
1386 return -1;
1387 sum += count;
1390 return sum;
1394 * xmlTextWriterWriteRaw:
1395 * @writer: the xmlTextWriterPtr
1396 * @content: text string
1398 * Write a raw xml text.
1400 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1403 xmlTextWriterWriteRaw(xmlTextWriterPtr writer, const xmlChar * content)
1405 return xmlTextWriterWriteRawLen(writer, content, xmlStrlen(content));
1409 * xmlTextWriterWriteFormatString:
1410 * @writer: the xmlTextWriterPtr
1411 * @format: format string (see printf)
1412 * @...: extra parameters for the format
1414 * Write a formatted xml text.
1416 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1418 int XMLCDECL
1419 xmlTextWriterWriteFormatString(xmlTextWriterPtr writer, const char *format,
1420 ...)
1422 int rc;
1423 va_list ap;
1425 if ((writer == NULL) || (format == NULL))
1426 return -1;
1428 va_start(ap, format);
1430 rc = xmlTextWriterWriteVFormatString(writer, format, ap);
1432 va_end(ap);
1433 return rc;
1437 * xmlTextWriterWriteVFormatString:
1438 * @writer: the xmlTextWriterPtr
1439 * @format: format string (see printf)
1440 * @argptr: pointer to the first member of the variable argument list.
1442 * Write a formatted xml text.
1444 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1447 xmlTextWriterWriteVFormatString(xmlTextWriterPtr writer,
1448 const char *format, va_list argptr)
1450 int rc;
1451 xmlChar *buf;
1453 if ((writer == NULL) || (format == NULL))
1454 return -1;
1456 buf = xmlTextWriterVSprintf(format, argptr);
1457 if (buf == NULL)
1458 return -1;
1460 rc = xmlTextWriterWriteString(writer, buf);
1462 xmlFree(buf);
1463 return rc;
1467 * xmlTextWriterWriteString:
1468 * @writer: the xmlTextWriterPtr
1469 * @content: text string
1471 * Write an xml text.
1473 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1476 xmlTextWriterWriteString(xmlTextWriterPtr writer, const xmlChar * content)
1478 int count;
1479 int sum;
1480 xmlLinkPtr lk;
1481 xmlTextWriterStackEntry *p;
1482 xmlChar *buf;
1484 if ((writer == NULL) || (content == NULL))
1485 return -1;
1487 sum = 0;
1488 buf = (xmlChar *) content;
1489 lk = xmlListFront(writer->nodes);
1490 if (lk != 0) {
1491 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1492 if (p != 0) {
1493 switch (p->state) {
1494 case XML_TEXTWRITER_NAME:
1495 case XML_TEXTWRITER_TEXT:
1496 #if 0
1497 buf = NULL;
1498 xmlOutputBufferWriteEscape(writer->out, content, NULL);
1499 #endif
1500 buf = xmlEncodeSpecialChars(NULL, content);
1501 break;
1502 case XML_TEXTWRITER_ATTRIBUTE:
1503 buf = NULL;
1504 xmlAttrSerializeTxtContent(writer->out->buffer, writer->doc,
1505 NULL, content);
1506 break;
1507 default:
1508 break;
1513 if (buf != NULL) {
1514 count = xmlTextWriterWriteRaw(writer, buf);
1516 if (buf != content) /* buf was allocated by us, so free it */
1517 xmlFree(buf);
1519 if (count < 0)
1520 return -1;
1521 sum += count;
1524 return sum;
1528 * xmlOutputBufferWriteBase64:
1529 * @out: the xmlOutputBufferPtr
1530 * @data: binary data
1531 * @len: the number of bytes to encode
1533 * Write base64 encoded data to an xmlOutputBuffer.
1534 * Adapted from John Walker's base64.c (http://www.fourmilab.ch/).
1536 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1538 static int
1539 xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len,
1540 const unsigned char *data)
1542 static unsigned char dtable[64] =
1543 {'A','B','C','D','E','F','G','H','I','J','K','L','M',
1544 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
1545 'a','b','c','d','e','f','g','h','i','j','k','l','m',
1546 'n','o','p','q','r','s','t','u','v','w','x','y','z',
1547 '0','1','2','3','4','5','6','7','8','9','+','/'};
1549 int i;
1550 int linelen;
1551 int count;
1552 int sum;
1554 if ((out == NULL) || (len < 0) || (data == NULL))
1555 return(-1);
1557 linelen = 0;
1558 sum = 0;
1560 i = 0;
1561 while (1) {
1562 unsigned char igroup[3];
1563 unsigned char ogroup[4];
1564 int c;
1565 int n;
1567 igroup[0] = igroup[1] = igroup[2] = 0;
1568 for (n = 0; n < 3 && i < len; n++, i++) {
1569 c = data[i];
1570 igroup[n] = (unsigned char) c;
1573 if (n > 0) {
1574 ogroup[0] = dtable[igroup[0] >> 2];
1575 ogroup[1] = dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)];
1576 ogroup[2] =
1577 dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)];
1578 ogroup[3] = dtable[igroup[2] & 0x3F];
1580 if (n < 3) {
1581 ogroup[3] = '=';
1582 if (n < 2) {
1583 ogroup[2] = '=';
1587 if (linelen >= B64LINELEN) {
1588 count = xmlOutputBufferWrite(out, 2, B64CRLF);
1589 if (count == -1)
1590 return -1;
1591 sum += count;
1592 linelen = 0;
1594 count = xmlOutputBufferWrite(out, 4, (const char *) ogroup);
1595 if (count == -1)
1596 return -1;
1597 sum += count;
1599 linelen += 4;
1602 if (i >= len)
1603 break;
1606 return sum;
1610 * xmlTextWriterWriteBase64:
1611 * @writer: the xmlTextWriterPtr
1612 * @data: binary data
1613 * @start: the position within the data of the first byte to encode
1614 * @len: the number of bytes to encode
1616 * Write an base64 encoded xml text.
1618 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1621 xmlTextWriterWriteBase64(xmlTextWriterPtr writer, const char *data,
1622 int start, int len)
1624 int count;
1625 int sum;
1626 xmlLinkPtr lk;
1627 xmlTextWriterStackEntry *p;
1629 if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0))
1630 return -1;
1632 sum = 0;
1633 lk = xmlListFront(writer->nodes);
1634 if (lk != 0) {
1635 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1636 if (p != 0) {
1637 count = xmlTextWriterHandleStateDependencies(writer, p);
1638 if (count < 0)
1639 return -1;
1640 sum += count;
1644 if (writer->indent)
1645 writer->doindent = 0;
1647 count =
1648 xmlOutputBufferWriteBase64(writer->out, len,
1649 (unsigned char *) data + start);
1650 if (count < 0)
1651 return -1;
1652 sum += count;
1654 return sum;
1658 * xmlOutputBufferWriteBinHex:
1659 * @out: the xmlOutputBufferPtr
1660 * @data: binary data
1661 * @len: the number of bytes to encode
1663 * Write hqx encoded data to an xmlOutputBuffer.
1664 * ::todo
1666 * Returns the bytes written (may be 0 because of buffering)
1667 * or -1 in case of error
1669 static int
1670 xmlOutputBufferWriteBinHex(xmlOutputBufferPtr out,
1671 int len, const unsigned char *data)
1673 int count;
1674 int sum;
1675 static char hex[16] =
1676 {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
1677 int i;
1679 if ((out == NULL) || (data == NULL) || (len < 0)) {
1680 return -1;
1683 sum = 0;
1684 for (i = 0; i < len; i++) {
1685 count =
1686 xmlOutputBufferWrite(out, 1,
1687 (const char *) &hex[data[i] >> 4]);
1688 if (count == -1)
1689 return -1;
1690 sum += count;
1691 count =
1692 xmlOutputBufferWrite(out, 1,
1693 (const char *) &hex[data[i] & 0xF]);
1694 if (count == -1)
1695 return -1;
1696 sum += count;
1699 return sum;
1703 * xmlTextWriterWriteBinHex:
1704 * @writer: the xmlTextWriterPtr
1705 * @data: binary data
1706 * @start: the position within the data of the first byte to encode
1707 * @len: the number of bytes to encode
1709 * Write a BinHex encoded xml text.
1711 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1714 xmlTextWriterWriteBinHex(xmlTextWriterPtr writer, const char *data,
1715 int start, int len)
1717 int count;
1718 int sum;
1719 xmlLinkPtr lk;
1720 xmlTextWriterStackEntry *p;
1722 if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0))
1723 return -1;
1725 sum = 0;
1726 lk = xmlListFront(writer->nodes);
1727 if (lk != 0) {
1728 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1729 if (p != 0) {
1730 count = xmlTextWriterHandleStateDependencies(writer, p);
1731 if (count < 0)
1732 return -1;
1733 sum += count;
1737 if (writer->indent)
1738 writer->doindent = 0;
1740 count =
1741 xmlOutputBufferWriteBinHex(writer->out, len,
1742 (unsigned char *) data + start);
1743 if (count < 0)
1744 return -1;
1745 sum += count;
1747 return sum;
1751 * xmlTextWriterStartAttribute:
1752 * @writer: the xmlTextWriterPtr
1753 * @name: element name
1755 * Start an xml attribute.
1757 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1760 xmlTextWriterStartAttribute(xmlTextWriterPtr writer, const xmlChar * name)
1762 int count;
1763 int sum;
1764 xmlLinkPtr lk;
1765 xmlTextWriterStackEntry *p;
1767 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1768 return -1;
1770 sum = 0;
1771 lk = xmlListFront(writer->nodes);
1772 if (lk == 0)
1773 return -1;
1775 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1776 if (p == 0)
1777 return -1;
1779 switch (p->state) {
1780 case XML_TEXTWRITER_ATTRIBUTE:
1781 count = xmlTextWriterEndAttribute(writer);
1782 if (count < 0)
1783 return -1;
1784 sum += count;
1785 /* fallthrough */
1786 case XML_TEXTWRITER_NAME:
1787 count = xmlOutputBufferWriteString(writer->out, " ");
1788 if (count < 0)
1789 return -1;
1790 sum += count;
1791 count =
1792 xmlOutputBufferWriteString(writer->out,
1793 (const char *) name);
1794 if (count < 0)
1795 return -1;
1796 sum += count;
1797 count = xmlOutputBufferWriteString(writer->out, "=");
1798 if (count < 0)
1799 return -1;
1800 sum += count;
1801 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1802 if (count < 0)
1803 return -1;
1804 sum += count;
1805 p->state = XML_TEXTWRITER_ATTRIBUTE;
1806 break;
1807 default:
1808 return -1;
1811 return sum;
1815 * xmlTextWriterStartAttributeNS:
1816 * @writer: the xmlTextWriterPtr
1817 * @prefix: namespace prefix or NULL
1818 * @name: element local name
1819 * @namespaceURI: namespace URI or NULL
1821 * Start an xml attribute with namespace support.
1823 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1826 xmlTextWriterStartAttributeNS(xmlTextWriterPtr writer,
1827 const xmlChar * prefix, const xmlChar * name,
1828 const xmlChar * namespaceURI)
1830 int count;
1831 int sum;
1832 xmlChar *buf;
1833 xmlTextWriterNsStackEntry *p;
1835 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1836 return -1;
1838 /* Handle namespace first in case of error */
1839 if (namespaceURI != 0) {
1840 xmlTextWriterNsStackEntry nsentry, *curns;
1842 buf = xmlStrdup(BAD_CAST "xmlns");
1843 if (prefix != 0) {
1844 buf = xmlStrcat(buf, BAD_CAST ":");
1845 buf = xmlStrcat(buf, prefix);
1848 nsentry.prefix = buf;
1849 nsentry.uri = (xmlChar *)namespaceURI;
1850 nsentry.elem = xmlListFront(writer->nodes);
1852 curns = (xmlTextWriterNsStackEntry *)xmlListSearch(writer->nsstack,
1853 (void *)&nsentry);
1854 if ((curns != NULL)) {
1855 xmlFree(buf);
1856 if (xmlStrcmp(curns->uri, namespaceURI) == 0) {
1857 /* Namespace already defined on element skip */
1858 buf = NULL;
1859 } else {
1860 /* Prefix mismatch so error out */
1861 return -1;
1865 /* Do not add namespace decl to list - it is already there */
1866 if (buf != NULL) {
1867 p = (xmlTextWriterNsStackEntry *)
1868 xmlMalloc(sizeof(xmlTextWriterNsStackEntry));
1869 if (p == 0) {
1870 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
1871 "xmlTextWriterStartAttributeNS : out of memory!\n");
1872 return -1;
1875 p->prefix = buf;
1876 p->uri = xmlStrdup(namespaceURI);
1877 if (p->uri == 0) {
1878 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
1879 "xmlTextWriterStartAttributeNS : out of memory!\n");
1880 xmlFree(p);
1881 return -1;
1883 p->elem = xmlListFront(writer->nodes);
1885 xmlListPushFront(writer->nsstack, p);
1889 buf = NULL;
1890 if (prefix != 0) {
1891 buf = xmlStrdup(prefix);
1892 buf = xmlStrcat(buf, BAD_CAST ":");
1894 buf = xmlStrcat(buf, name);
1896 sum = 0;
1897 count = xmlTextWriterStartAttribute(writer, buf);
1898 xmlFree(buf);
1899 if (count < 0)
1900 return -1;
1901 sum += count;
1903 return sum;
1907 * xmlTextWriterEndAttribute:
1908 * @writer: the xmlTextWriterPtr
1910 * End the current xml element.
1912 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1915 xmlTextWriterEndAttribute(xmlTextWriterPtr writer)
1917 int count;
1918 int sum;
1919 xmlLinkPtr lk;
1920 xmlTextWriterStackEntry *p;
1922 if (writer == NULL)
1923 return -1;
1925 lk = xmlListFront(writer->nodes);
1926 if (lk == 0) {
1927 return -1;
1930 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1931 if (p == 0) {
1932 return -1;
1935 sum = 0;
1936 switch (p->state) {
1937 case XML_TEXTWRITER_ATTRIBUTE:
1938 p->state = XML_TEXTWRITER_NAME;
1940 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1941 if (count < 0) {
1942 return -1;
1944 sum += count;
1945 break;
1946 default:
1947 return -1;
1950 return sum;
1954 * xmlTextWriterWriteFormatAttribute:
1955 * @writer: the xmlTextWriterPtr
1956 * @name: attribute name
1957 * @format: format string (see printf)
1958 * @...: extra parameters for the format
1960 * Write a formatted xml attribute.
1962 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1964 int XMLCDECL
1965 xmlTextWriterWriteFormatAttribute(xmlTextWriterPtr writer,
1966 const xmlChar * name, const char *format,
1967 ...)
1969 int rc;
1970 va_list ap;
1972 va_start(ap, format);
1974 rc = xmlTextWriterWriteVFormatAttribute(writer, name, format, ap);
1976 va_end(ap);
1977 return rc;
1981 * xmlTextWriterWriteVFormatAttribute:
1982 * @writer: the xmlTextWriterPtr
1983 * @name: attribute name
1984 * @format: format string (see printf)
1985 * @argptr: pointer to the first member of the variable argument list.
1987 * Write a formatted xml attribute.
1989 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1992 xmlTextWriterWriteVFormatAttribute(xmlTextWriterPtr writer,
1993 const xmlChar * name,
1994 const char *format, va_list argptr)
1996 int rc;
1997 xmlChar *buf;
1999 if (writer == NULL)
2000 return -1;
2002 buf = xmlTextWriterVSprintf(format, argptr);
2003 if (buf == NULL)
2004 return -1;
2006 rc = xmlTextWriterWriteAttribute(writer, name, buf);
2008 xmlFree(buf);
2009 return rc;
2013 * xmlTextWriterWriteAttribute:
2014 * @writer: the xmlTextWriterPtr
2015 * @name: attribute name
2016 * @content: attribute content
2018 * Write an xml attribute.
2020 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2023 xmlTextWriterWriteAttribute(xmlTextWriterPtr writer, const xmlChar * name,
2024 const xmlChar * content)
2026 int count;
2027 int sum;
2029 sum = 0;
2030 count = xmlTextWriterStartAttribute(writer, name);
2031 if (count < 0)
2032 return -1;
2033 sum += count;
2034 count = xmlTextWriterWriteString(writer, content);
2035 if (count < 0)
2036 return -1;
2037 sum += count;
2038 count = xmlTextWriterEndAttribute(writer);
2039 if (count < 0)
2040 return -1;
2041 sum += count;
2043 return sum;
2047 * xmlTextWriterWriteFormatAttributeNS:
2048 * @writer: the xmlTextWriterPtr
2049 * @prefix: namespace prefix
2050 * @name: attribute local name
2051 * @namespaceURI: namespace URI
2052 * @format: format string (see printf)
2053 * @...: extra parameters for the format
2055 * Write a formatted xml attribute.with namespace support
2057 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2059 int XMLCDECL
2060 xmlTextWriterWriteFormatAttributeNS(xmlTextWriterPtr writer,
2061 const xmlChar * prefix,
2062 const xmlChar * name,
2063 const xmlChar * namespaceURI,
2064 const char *format, ...)
2066 int rc;
2067 va_list ap;
2069 va_start(ap, format);
2071 rc = xmlTextWriterWriteVFormatAttributeNS(writer, prefix, name,
2072 namespaceURI, format, ap);
2074 va_end(ap);
2075 return rc;
2079 * xmlTextWriterWriteVFormatAttributeNS:
2080 * @writer: the xmlTextWriterPtr
2081 * @prefix: namespace prefix
2082 * @name: attribute local name
2083 * @namespaceURI: namespace URI
2084 * @format: format string (see printf)
2085 * @argptr: pointer to the first member of the variable argument list.
2087 * Write a formatted xml attribute.with namespace support
2089 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2092 xmlTextWriterWriteVFormatAttributeNS(xmlTextWriterPtr writer,
2093 const xmlChar * prefix,
2094 const xmlChar * name,
2095 const xmlChar * namespaceURI,
2096 const char *format, va_list argptr)
2098 int rc;
2099 xmlChar *buf;
2101 if (writer == NULL)
2102 return -1;
2104 buf = xmlTextWriterVSprintf(format, argptr);
2105 if (buf == NULL)
2106 return -1;
2108 rc = xmlTextWriterWriteAttributeNS(writer, prefix, name, namespaceURI,
2109 buf);
2111 xmlFree(buf);
2112 return rc;
2116 * xmlTextWriterWriteAttributeNS:
2117 * @writer: the xmlTextWriterPtr
2118 * @prefix: namespace prefix
2119 * @name: attribute local name
2120 * @namespaceURI: namespace URI
2121 * @content: attribute content
2123 * Write an xml attribute.
2125 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2128 xmlTextWriterWriteAttributeNS(xmlTextWriterPtr writer,
2129 const xmlChar * prefix, const xmlChar * name,
2130 const xmlChar * namespaceURI,
2131 const xmlChar * content)
2133 int count;
2134 int sum;
2136 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
2137 return -1;
2139 sum = 0;
2140 count = xmlTextWriterStartAttributeNS(writer, prefix, name, namespaceURI);
2141 if (count < 0)
2142 return -1;
2143 sum += count;
2144 count = xmlTextWriterWriteString(writer, content);
2145 if (count < 0)
2146 return -1;
2147 sum += count;
2148 count = xmlTextWriterEndAttribute(writer);
2149 if (count < 0)
2150 return -1;
2151 sum += count;
2153 return sum;
2157 * xmlTextWriterWriteFormatElement:
2158 * @writer: the xmlTextWriterPtr
2159 * @name: element name
2160 * @format: format string (see printf)
2161 * @...: extra parameters for the format
2163 * Write a formatted xml element.
2165 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2167 int XMLCDECL
2168 xmlTextWriterWriteFormatElement(xmlTextWriterPtr writer,
2169 const xmlChar * name, const char *format,
2170 ...)
2172 int rc;
2173 va_list ap;
2175 va_start(ap, format);
2177 rc = xmlTextWriterWriteVFormatElement(writer, name, format, ap);
2179 va_end(ap);
2180 return rc;
2184 * xmlTextWriterWriteVFormatElement:
2185 * @writer: the xmlTextWriterPtr
2186 * @name: element name
2187 * @format: format string (see printf)
2188 * @argptr: pointer to the first member of the variable argument list.
2190 * Write a formatted xml element.
2192 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2195 xmlTextWriterWriteVFormatElement(xmlTextWriterPtr writer,
2196 const xmlChar * name, const char *format,
2197 va_list argptr)
2199 int rc;
2200 xmlChar *buf;
2202 if (writer == NULL)
2203 return -1;
2205 buf = xmlTextWriterVSprintf(format, argptr);
2206 if (buf == NULL)
2207 return -1;
2209 rc = xmlTextWriterWriteElement(writer, name, buf);
2211 xmlFree(buf);
2212 return rc;
2216 * xmlTextWriterWriteElement:
2217 * @writer: the xmlTextWriterPtr
2218 * @name: element name
2219 * @content: element content
2221 * Write an xml element.
2223 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2226 xmlTextWriterWriteElement(xmlTextWriterPtr writer, const xmlChar * name,
2227 const xmlChar * content)
2229 int count;
2230 int sum;
2232 sum = 0;
2233 count = xmlTextWriterStartElement(writer, name);
2234 if (count == -1)
2235 return -1;
2236 sum += count;
2237 count = xmlTextWriterWriteString(writer, content);
2238 if (count == -1)
2239 return -1;
2240 sum += count;
2241 count = xmlTextWriterEndElement(writer);
2242 if (count == -1)
2243 return -1;
2244 sum += count;
2246 return sum;
2250 * xmlTextWriterWriteFormatElementNS:
2251 * @writer: the xmlTextWriterPtr
2252 * @prefix: namespace prefix
2253 * @name: element local name
2254 * @namespaceURI: namespace URI
2255 * @format: format string (see printf)
2256 * @...: extra parameters for the format
2258 * Write a formatted xml element with namespace support.
2260 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2262 int XMLCDECL
2263 xmlTextWriterWriteFormatElementNS(xmlTextWriterPtr writer,
2264 const xmlChar * prefix,
2265 const xmlChar * name,
2266 const xmlChar * namespaceURI,
2267 const char *format, ...)
2269 int rc;
2270 va_list ap;
2272 va_start(ap, format);
2274 rc = xmlTextWriterWriteVFormatElementNS(writer, prefix, name,
2275 namespaceURI, format, ap);
2277 va_end(ap);
2278 return rc;
2282 * xmlTextWriterWriteVFormatElementNS:
2283 * @writer: the xmlTextWriterPtr
2284 * @prefix: namespace prefix
2285 * @name: element local name
2286 * @namespaceURI: namespace URI
2287 * @format: format string (see printf)
2288 * @argptr: pointer to the first member of the variable argument list.
2290 * Write a formatted xml element with namespace support.
2292 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2295 xmlTextWriterWriteVFormatElementNS(xmlTextWriterPtr writer,
2296 const xmlChar * prefix,
2297 const xmlChar * name,
2298 const xmlChar * namespaceURI,
2299 const char *format, va_list argptr)
2301 int rc;
2302 xmlChar *buf;
2304 if (writer == NULL)
2305 return -1;
2307 buf = xmlTextWriterVSprintf(format, argptr);
2308 if (buf == NULL)
2309 return -1;
2311 rc = xmlTextWriterWriteElementNS(writer, prefix, name, namespaceURI,
2312 buf);
2314 xmlFree(buf);
2315 return rc;
2319 * xmlTextWriterWriteElementNS:
2320 * @writer: the xmlTextWriterPtr
2321 * @prefix: namespace prefix
2322 * @name: element local name
2323 * @namespaceURI: namespace URI
2324 * @content: element content
2326 * Write an xml element with namespace support.
2328 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2331 xmlTextWriterWriteElementNS(xmlTextWriterPtr writer,
2332 const xmlChar * prefix, const xmlChar * name,
2333 const xmlChar * namespaceURI,
2334 const xmlChar * content)
2336 int count;
2337 int sum;
2339 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
2340 return -1;
2342 sum = 0;
2343 count =
2344 xmlTextWriterStartElementNS(writer, prefix, name, namespaceURI);
2345 if (count < 0)
2346 return -1;
2347 sum += count;
2348 count = xmlTextWriterWriteString(writer, content);
2349 if (count == -1)
2350 return -1;
2351 sum += count;
2352 count = xmlTextWriterEndElement(writer);
2353 if (count == -1)
2354 return -1;
2355 sum += count;
2357 return sum;
2361 * xmlTextWriterStartPI:
2362 * @writer: the xmlTextWriterPtr
2363 * @target: PI target
2365 * Start an xml PI.
2367 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2370 xmlTextWriterStartPI(xmlTextWriterPtr writer, const xmlChar * target)
2372 int count;
2373 int sum;
2374 xmlLinkPtr lk;
2375 xmlTextWriterStackEntry *p;
2377 if ((writer == NULL) || (target == NULL) || (*target == '\0'))
2378 return -1;
2380 if (xmlStrcasecmp(target, (const xmlChar *) "xml") == 0) {
2381 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
2382 "xmlTextWriterStartPI : target name [Xx][Mm][Ll] is reserved for xml standardization!\n");
2383 return -1;
2386 sum = 0;
2387 lk = xmlListFront(writer->nodes);
2388 if (lk != 0) {
2389 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2390 if (p != 0) {
2391 switch (p->state) {
2392 case XML_TEXTWRITER_ATTRIBUTE:
2393 count = xmlTextWriterEndAttribute(writer);
2394 if (count < 0)
2395 return -1;
2396 sum += count;
2397 /* fallthrough */
2398 case XML_TEXTWRITER_NAME:
2399 /* Output namespace declarations */
2400 count = xmlTextWriterOutputNSDecl(writer);
2401 if (count < 0)
2402 return -1;
2403 sum += count;
2404 count = xmlOutputBufferWriteString(writer->out, ">");
2405 if (count < 0)
2406 return -1;
2407 sum += count;
2408 p->state = XML_TEXTWRITER_TEXT;
2409 break;
2410 case XML_TEXTWRITER_NONE:
2411 case XML_TEXTWRITER_TEXT:
2412 case XML_TEXTWRITER_DTD:
2413 break;
2414 case XML_TEXTWRITER_PI:
2415 case XML_TEXTWRITER_PI_TEXT:
2416 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
2417 "xmlTextWriterStartPI : nested PI!\n");
2418 return -1;
2419 default:
2420 return -1;
2425 p = (xmlTextWriterStackEntry *)
2426 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2427 if (p == 0) {
2428 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
2429 "xmlTextWriterStartPI : out of memory!\n");
2430 return -1;
2433 p->name = xmlStrdup(target);
2434 if (p->name == 0) {
2435 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
2436 "xmlTextWriterStartPI : out of memory!\n");
2437 xmlFree(p);
2438 return -1;
2440 p->state = XML_TEXTWRITER_PI;
2442 xmlListPushFront(writer->nodes, p);
2444 count = xmlOutputBufferWriteString(writer->out, "<?");
2445 if (count < 0)
2446 return -1;
2447 sum += count;
2448 count =
2449 xmlOutputBufferWriteString(writer->out, (const char *) p->name);
2450 if (count < 0)
2451 return -1;
2452 sum += count;
2454 return sum;
2458 * xmlTextWriterEndPI:
2459 * @writer: the xmlTextWriterPtr
2461 * End the current xml PI.
2463 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2466 xmlTextWriterEndPI(xmlTextWriterPtr writer)
2468 int count;
2469 int sum;
2470 xmlLinkPtr lk;
2471 xmlTextWriterStackEntry *p;
2473 if (writer == NULL)
2474 return -1;
2476 lk = xmlListFront(writer->nodes);
2477 if (lk == 0)
2478 return 0;
2480 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2481 if (p == 0)
2482 return 0;
2484 sum = 0;
2485 switch (p->state) {
2486 case XML_TEXTWRITER_PI:
2487 case XML_TEXTWRITER_PI_TEXT:
2488 count = xmlOutputBufferWriteString(writer->out, "?>");
2489 if (count < 0)
2490 return -1;
2491 sum += count;
2492 break;
2493 default:
2494 return -1;
2497 if (writer->indent) {
2498 count = xmlOutputBufferWriteString(writer->out, "\n");
2499 if (count < 0)
2500 return -1;
2501 sum += count;
2504 xmlListPopFront(writer->nodes);
2505 return sum;
2509 * xmlTextWriterWriteFormatPI:
2510 * @writer: the xmlTextWriterPtr
2511 * @target: PI target
2512 * @format: format string (see printf)
2513 * @...: extra parameters for the format
2515 * Write a formatted PI.
2517 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2519 int XMLCDECL
2520 xmlTextWriterWriteFormatPI(xmlTextWriterPtr writer, const xmlChar * target,
2521 const char *format, ...)
2523 int rc;
2524 va_list ap;
2526 va_start(ap, format);
2528 rc = xmlTextWriterWriteVFormatPI(writer, target, format, ap);
2530 va_end(ap);
2531 return rc;
2535 * xmlTextWriterWriteVFormatPI:
2536 * @writer: the xmlTextWriterPtr
2537 * @target: PI target
2538 * @format: format string (see printf)
2539 * @argptr: pointer to the first member of the variable argument list.
2541 * Write a formatted xml PI.
2543 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2546 xmlTextWriterWriteVFormatPI(xmlTextWriterPtr writer,
2547 const xmlChar * target, const char *format,
2548 va_list argptr)
2550 int rc;
2551 xmlChar *buf;
2553 if (writer == NULL)
2554 return -1;
2556 buf = xmlTextWriterVSprintf(format, argptr);
2557 if (buf == NULL)
2558 return -1;
2560 rc = xmlTextWriterWritePI(writer, target, buf);
2562 xmlFree(buf);
2563 return rc;
2567 * xmlTextWriterWritePI:
2568 * @writer: the xmlTextWriterPtr
2569 * @target: PI target
2570 * @content: PI content
2572 * Write an xml PI.
2574 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2577 xmlTextWriterWritePI(xmlTextWriterPtr writer, const xmlChar * target,
2578 const xmlChar * content)
2580 int count;
2581 int sum;
2583 sum = 0;
2584 count = xmlTextWriterStartPI(writer, target);
2585 if (count == -1)
2586 return -1;
2587 sum += count;
2588 if (content != 0) {
2589 count = xmlTextWriterWriteString(writer, content);
2590 if (count == -1)
2591 return -1;
2592 sum += count;
2594 count = xmlTextWriterEndPI(writer);
2595 if (count == -1)
2596 return -1;
2597 sum += count;
2599 return sum;
2603 * xmlTextWriterStartCDATA:
2604 * @writer: the xmlTextWriterPtr
2606 * Start an xml CDATA section.
2608 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2611 xmlTextWriterStartCDATA(xmlTextWriterPtr writer)
2613 int count;
2614 int sum;
2615 xmlLinkPtr lk;
2616 xmlTextWriterStackEntry *p;
2618 if (writer == NULL)
2619 return -1;
2621 sum = 0;
2622 lk = xmlListFront(writer->nodes);
2623 if (lk != 0) {
2624 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2625 if (p != 0) {
2626 switch (p->state) {
2627 case XML_TEXTWRITER_NONE:
2628 case XML_TEXTWRITER_TEXT:
2629 case XML_TEXTWRITER_PI:
2630 case XML_TEXTWRITER_PI_TEXT:
2631 break;
2632 case XML_TEXTWRITER_ATTRIBUTE:
2633 count = xmlTextWriterEndAttribute(writer);
2634 if (count < 0)
2635 return -1;
2636 sum += count;
2637 /* fallthrough */
2638 case XML_TEXTWRITER_NAME:
2639 /* Output namespace declarations */
2640 count = xmlTextWriterOutputNSDecl(writer);
2641 if (count < 0)
2642 return -1;
2643 sum += count;
2644 count = xmlOutputBufferWriteString(writer->out, ">");
2645 if (count < 0)
2646 return -1;
2647 sum += count;
2648 p->state = XML_TEXTWRITER_TEXT;
2649 break;
2650 case XML_TEXTWRITER_CDATA:
2651 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
2652 "xmlTextWriterStartCDATA : CDATA not allowed in this context!\n");
2653 return -1;
2654 default:
2655 return -1;
2660 p = (xmlTextWriterStackEntry *)
2661 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2662 if (p == 0) {
2663 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
2664 "xmlTextWriterStartCDATA : out of memory!\n");
2665 return -1;
2668 p->name = NULL;
2669 p->state = XML_TEXTWRITER_CDATA;
2671 xmlListPushFront(writer->nodes, p);
2673 count = xmlOutputBufferWriteString(writer->out, "<![CDATA[");
2674 if (count < 0)
2675 return -1;
2676 sum += count;
2678 return sum;
2682 * xmlTextWriterEndCDATA:
2683 * @writer: the xmlTextWriterPtr
2685 * End an xml CDATA section.
2687 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2690 xmlTextWriterEndCDATA(xmlTextWriterPtr writer)
2692 int count;
2693 int sum;
2694 xmlLinkPtr lk;
2695 xmlTextWriterStackEntry *p;
2697 if (writer == NULL)
2698 return -1;
2700 lk = xmlListFront(writer->nodes);
2701 if (lk == 0)
2702 return -1;
2704 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2705 if (p == 0)
2706 return -1;
2708 sum = 0;
2709 switch (p->state) {
2710 case XML_TEXTWRITER_CDATA:
2711 count = xmlOutputBufferWriteString(writer->out, "]]>");
2712 if (count < 0)
2713 return -1;
2714 sum += count;
2715 break;
2716 default:
2717 return -1;
2720 xmlListPopFront(writer->nodes);
2721 return sum;
2725 * xmlTextWriterWriteFormatCDATA:
2726 * @writer: the xmlTextWriterPtr
2727 * @format: format string (see printf)
2728 * @...: extra parameters for the format
2730 * Write a formatted xml CDATA.
2732 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2734 int XMLCDECL
2735 xmlTextWriterWriteFormatCDATA(xmlTextWriterPtr writer, const char *format,
2736 ...)
2738 int rc;
2739 va_list ap;
2741 va_start(ap, format);
2743 rc = xmlTextWriterWriteVFormatCDATA(writer, format, ap);
2745 va_end(ap);
2746 return rc;
2750 * xmlTextWriterWriteVFormatCDATA:
2751 * @writer: the xmlTextWriterPtr
2752 * @format: format string (see printf)
2753 * @argptr: pointer to the first member of the variable argument list.
2755 * Write a formatted xml CDATA.
2757 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2760 xmlTextWriterWriteVFormatCDATA(xmlTextWriterPtr writer, const char *format,
2761 va_list argptr)
2763 int rc;
2764 xmlChar *buf;
2766 if (writer == NULL)
2767 return -1;
2769 buf = xmlTextWriterVSprintf(format, argptr);
2770 if (buf == NULL)
2771 return -1;
2773 rc = xmlTextWriterWriteCDATA(writer, buf);
2775 xmlFree(buf);
2776 return rc;
2780 * xmlTextWriterWriteCDATA:
2781 * @writer: the xmlTextWriterPtr
2782 * @content: CDATA content
2784 * Write an xml CDATA.
2786 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2789 xmlTextWriterWriteCDATA(xmlTextWriterPtr writer, const xmlChar * content)
2791 int count;
2792 int sum;
2794 sum = 0;
2795 count = xmlTextWriterStartCDATA(writer);
2796 if (count == -1)
2797 return -1;
2798 sum += count;
2799 if (content != 0) {
2800 count = xmlTextWriterWriteString(writer, content);
2801 if (count == -1)
2802 return -1;
2803 sum += count;
2805 count = xmlTextWriterEndCDATA(writer);
2806 if (count == -1)
2807 return -1;
2808 sum += count;
2810 return sum;
2814 * xmlTextWriterStartDTD:
2815 * @writer: the xmlTextWriterPtr
2816 * @name: the name of the DTD
2817 * @pubid: the public identifier, which is an alternative to the system identifier
2818 * @sysid: the system identifier, which is the URI of the DTD
2820 * Start an xml DTD.
2822 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2825 xmlTextWriterStartDTD(xmlTextWriterPtr writer,
2826 const xmlChar * name,
2827 const xmlChar * pubid, const xmlChar * sysid)
2829 int count;
2830 int sum;
2831 xmlLinkPtr lk;
2832 xmlTextWriterStackEntry *p;
2834 if (writer == NULL || name == NULL || *name == '\0')
2835 return -1;
2837 sum = 0;
2838 lk = xmlListFront(writer->nodes);
2839 if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) {
2840 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
2841 "xmlTextWriterStartDTD : DTD allowed only in prolog!\n");
2842 return -1;
2845 p = (xmlTextWriterStackEntry *)
2846 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2847 if (p == 0) {
2848 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
2849 "xmlTextWriterStartDTD : out of memory!\n");
2850 return -1;
2853 p->name = xmlStrdup(name);
2854 if (p->name == 0) {
2855 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
2856 "xmlTextWriterStartDTD : out of memory!\n");
2857 xmlFree(p);
2858 return -1;
2860 p->state = XML_TEXTWRITER_DTD;
2862 xmlListPushFront(writer->nodes, p);
2864 count = xmlOutputBufferWriteString(writer->out, "<!DOCTYPE ");
2865 if (count < 0)
2866 return -1;
2867 sum += count;
2868 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
2869 if (count < 0)
2870 return -1;
2871 sum += count;
2873 if (pubid != 0) {
2874 if (sysid == 0) {
2875 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
2876 "xmlTextWriterStartDTD : system identifier needed!\n");
2877 return -1;
2880 if (writer->indent)
2881 count = xmlOutputBufferWrite(writer->out, 1, "\n");
2882 else
2883 count = xmlOutputBufferWrite(writer->out, 1, " ");
2884 if (count < 0)
2885 return -1;
2886 sum += count;
2888 count = xmlOutputBufferWriteString(writer->out, "PUBLIC ");
2889 if (count < 0)
2890 return -1;
2891 sum += count;
2893 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
2894 if (count < 0)
2895 return -1;
2896 sum += count;
2898 count =
2899 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
2900 if (count < 0)
2901 return -1;
2902 sum += count;
2904 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
2905 if (count < 0)
2906 return -1;
2907 sum += count;
2910 if (sysid != 0) {
2911 if (pubid == 0) {
2912 if (writer->indent)
2913 count = xmlOutputBufferWrite(writer->out, 1, "\n");
2914 else
2915 count = xmlOutputBufferWrite(writer->out, 1, " ");
2916 if (count < 0)
2917 return -1;
2918 sum += count;
2919 count = xmlOutputBufferWriteString(writer->out, "SYSTEM ");
2920 if (count < 0)
2921 return -1;
2922 sum += count;
2923 } else {
2924 if (writer->indent)
2925 count = xmlOutputBufferWriteString(writer->out, "\n ");
2926 else
2927 count = xmlOutputBufferWrite(writer->out, 1, " ");
2928 if (count < 0)
2929 return -1;
2930 sum += count;
2933 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
2934 if (count < 0)
2935 return -1;
2936 sum += count;
2938 count =
2939 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
2940 if (count < 0)
2941 return -1;
2942 sum += count;
2944 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
2945 if (count < 0)
2946 return -1;
2947 sum += count;
2950 return sum;
2954 * xmlTextWriterEndDTD:
2955 * @writer: the xmlTextWriterPtr
2957 * End an xml DTD.
2959 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2962 xmlTextWriterEndDTD(xmlTextWriterPtr writer)
2964 int loop;
2965 int count;
2966 int sum;
2967 xmlLinkPtr lk;
2968 xmlTextWriterStackEntry *p;
2970 if (writer == NULL)
2971 return -1;
2973 sum = 0;
2974 loop = 1;
2975 while (loop) {
2976 lk = xmlListFront(writer->nodes);
2977 if (lk == NULL)
2978 break;
2979 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2980 if (p == 0)
2981 break;
2982 switch (p->state) {
2983 case XML_TEXTWRITER_DTD_TEXT:
2984 count = xmlOutputBufferWriteString(writer->out, "]");
2985 if (count < 0)
2986 return -1;
2987 sum += count;
2988 /* fallthrough */
2989 case XML_TEXTWRITER_DTD:
2990 count = xmlOutputBufferWriteString(writer->out, ">");
2992 if (writer->indent) {
2993 if (count < 0)
2994 return -1;
2995 sum += count;
2996 count = xmlOutputBufferWriteString(writer->out, "\n");
2999 xmlListPopFront(writer->nodes);
3000 break;
3001 case XML_TEXTWRITER_DTD_ELEM:
3002 case XML_TEXTWRITER_DTD_ELEM_TEXT:
3003 count = xmlTextWriterEndDTDElement(writer);
3004 break;
3005 case XML_TEXTWRITER_DTD_ATTL:
3006 case XML_TEXTWRITER_DTD_ATTL_TEXT:
3007 count = xmlTextWriterEndDTDAttlist(writer);
3008 break;
3009 case XML_TEXTWRITER_DTD_ENTY:
3010 case XML_TEXTWRITER_DTD_PENT:
3011 case XML_TEXTWRITER_DTD_ENTY_TEXT:
3012 count = xmlTextWriterEndDTDEntity(writer);
3013 break;
3014 case XML_TEXTWRITER_COMMENT:
3015 count = xmlTextWriterEndComment(writer);
3016 break;
3017 default:
3018 loop = 0;
3019 continue;
3022 if (count < 0)
3023 return -1;
3024 sum += count;
3027 return sum;
3031 * xmlTextWriterWriteFormatDTD:
3032 * @writer: the xmlTextWriterPtr
3033 * @name: the name of the DTD
3034 * @pubid: the public identifier, which is an alternative to the system identifier
3035 * @sysid: the system identifier, which is the URI of the DTD
3036 * @format: format string (see printf)
3037 * @...: extra parameters for the format
3039 * Write a DTD with a formatted markup declarations part.
3041 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3043 int XMLCDECL
3044 xmlTextWriterWriteFormatDTD(xmlTextWriterPtr writer,
3045 const xmlChar * name,
3046 const xmlChar * pubid,
3047 const xmlChar * sysid, const char *format, ...)
3049 int rc;
3050 va_list ap;
3052 va_start(ap, format);
3054 rc = xmlTextWriterWriteVFormatDTD(writer, name, pubid, sysid, format,
3055 ap);
3057 va_end(ap);
3058 return rc;
3062 * xmlTextWriterWriteVFormatDTD:
3063 * @writer: the xmlTextWriterPtr
3064 * @name: the name of the DTD
3065 * @pubid: the public identifier, which is an alternative to the system identifier
3066 * @sysid: the system identifier, which is the URI of the DTD
3067 * @format: format string (see printf)
3068 * @argptr: pointer to the first member of the variable argument list.
3070 * Write a DTD with a formatted markup declarations part.
3072 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3075 xmlTextWriterWriteVFormatDTD(xmlTextWriterPtr writer,
3076 const xmlChar * name,
3077 const xmlChar * pubid,
3078 const xmlChar * sysid,
3079 const char *format, va_list argptr)
3081 int rc;
3082 xmlChar *buf;
3084 if (writer == NULL)
3085 return -1;
3087 buf = xmlTextWriterVSprintf(format, argptr);
3088 if (buf == NULL)
3089 return -1;
3091 rc = xmlTextWriterWriteDTD(writer, name, pubid, sysid, buf);
3093 xmlFree(buf);
3094 return rc;
3098 * xmlTextWriterWriteDTD:
3099 * @writer: the xmlTextWriterPtr
3100 * @name: the name of the DTD
3101 * @pubid: the public identifier, which is an alternative to the system identifier
3102 * @sysid: the system identifier, which is the URI of the DTD
3103 * @subset: string content of the DTD
3105 * Write a DTD.
3107 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3110 xmlTextWriterWriteDTD(xmlTextWriterPtr writer,
3111 const xmlChar * name,
3112 const xmlChar * pubid,
3113 const xmlChar * sysid, const xmlChar * subset)
3115 int count;
3116 int sum;
3118 sum = 0;
3119 count = xmlTextWriterStartDTD(writer, name, pubid, sysid);
3120 if (count == -1)
3121 return -1;
3122 sum += count;
3123 if (subset != 0) {
3124 count = xmlTextWriterWriteString(writer, subset);
3125 if (count == -1)
3126 return -1;
3127 sum += count;
3129 count = xmlTextWriterEndDTD(writer);
3130 if (count == -1)
3131 return -1;
3132 sum += count;
3134 return sum;
3138 * xmlTextWriterStartDTDElement:
3139 * @writer: the xmlTextWriterPtr
3140 * @name: the name of the DTD element
3142 * Start an xml DTD element.
3144 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3147 xmlTextWriterStartDTDElement(xmlTextWriterPtr writer, const xmlChar * name)
3149 int count;
3150 int sum;
3151 xmlLinkPtr lk;
3152 xmlTextWriterStackEntry *p;
3154 if (writer == NULL || name == NULL || *name == '\0')
3155 return -1;
3157 sum = 0;
3158 lk = xmlListFront(writer->nodes);
3159 if (lk == 0) {
3160 return -1;
3163 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3164 if (p != 0) {
3165 switch (p->state) {
3166 case XML_TEXTWRITER_DTD:
3167 count = xmlOutputBufferWriteString(writer->out, " [");
3168 if (count < 0)
3169 return -1;
3170 sum += count;
3171 if (writer->indent) {
3172 count = xmlOutputBufferWriteString(writer->out, "\n");
3173 if (count < 0)
3174 return -1;
3175 sum += count;
3177 p->state = XML_TEXTWRITER_DTD_TEXT;
3178 /* fallthrough */
3179 case XML_TEXTWRITER_DTD_TEXT:
3180 case XML_TEXTWRITER_NONE:
3181 break;
3182 default:
3183 return -1;
3187 p = (xmlTextWriterStackEntry *)
3188 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3189 if (p == 0) {
3190 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
3191 "xmlTextWriterStartDTDElement : out of memory!\n");
3192 return -1;
3195 p->name = xmlStrdup(name);
3196 if (p->name == 0) {
3197 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
3198 "xmlTextWriterStartDTDElement : out of memory!\n");
3199 xmlFree(p);
3200 return -1;
3202 p->state = XML_TEXTWRITER_DTD_ELEM;
3204 xmlListPushFront(writer->nodes, p);
3206 if (writer->indent) {
3207 count = xmlTextWriterWriteIndent(writer);
3208 if (count < 0)
3209 return -1;
3210 sum += count;
3213 count = xmlOutputBufferWriteString(writer->out, "<!ELEMENT ");
3214 if (count < 0)
3215 return -1;
3216 sum += count;
3217 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
3218 if (count < 0)
3219 return -1;
3220 sum += count;
3222 return sum;
3226 * xmlTextWriterEndDTDElement:
3227 * @writer: the xmlTextWriterPtr
3229 * End an xml DTD element.
3231 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3234 xmlTextWriterEndDTDElement(xmlTextWriterPtr writer)
3236 int count;
3237 int sum;
3238 xmlLinkPtr lk;
3239 xmlTextWriterStackEntry *p;
3241 if (writer == NULL)
3242 return -1;
3244 sum = 0;
3245 lk = xmlListFront(writer->nodes);
3246 if (lk == 0)
3247 return -1;
3249 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3250 if (p == 0)
3251 return -1;
3253 switch (p->state) {
3254 case XML_TEXTWRITER_DTD_ELEM:
3255 case XML_TEXTWRITER_DTD_ELEM_TEXT:
3256 count = xmlOutputBufferWriteString(writer->out, ">");
3257 if (count < 0)
3258 return -1;
3259 sum += count;
3260 break;
3261 default:
3262 return -1;
3265 if (writer->indent) {
3266 count = xmlOutputBufferWriteString(writer->out, "\n");
3267 if (count < 0)
3268 return -1;
3269 sum += count;
3272 xmlListPopFront(writer->nodes);
3273 return sum;
3277 * xmlTextWriterWriteFormatDTDElement:
3278 * @writer: the xmlTextWriterPtr
3279 * @name: the name of the DTD element
3280 * @format: format string (see printf)
3281 * @...: extra parameters for the format
3283 * Write a formatted DTD element.
3285 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3287 int XMLCDECL
3288 xmlTextWriterWriteFormatDTDElement(xmlTextWriterPtr writer,
3289 const xmlChar * name,
3290 const char *format, ...)
3292 int rc;
3293 va_list ap;
3295 va_start(ap, format);
3297 rc = xmlTextWriterWriteVFormatDTDElement(writer, name, format, ap);
3299 va_end(ap);
3300 return rc;
3304 * xmlTextWriterWriteVFormatDTDElement:
3305 * @writer: the xmlTextWriterPtr
3306 * @name: the name of the DTD element
3307 * @format: format string (see printf)
3308 * @argptr: pointer to the first member of the variable argument list.
3310 * Write a formatted DTD element.
3312 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3315 xmlTextWriterWriteVFormatDTDElement(xmlTextWriterPtr writer,
3316 const xmlChar * name,
3317 const char *format, va_list argptr)
3319 int rc;
3320 xmlChar *buf;
3322 if (writer == NULL)
3323 return -1;
3325 buf = xmlTextWriterVSprintf(format, argptr);
3326 if (buf == NULL)
3327 return -1;
3329 rc = xmlTextWriterWriteDTDElement(writer, name, buf);
3331 xmlFree(buf);
3332 return rc;
3336 * xmlTextWriterWriteDTDElement:
3337 * @writer: the xmlTextWriterPtr
3338 * @name: the name of the DTD element
3339 * @content: content of the element
3341 * Write a DTD element.
3343 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3346 xmlTextWriterWriteDTDElement(xmlTextWriterPtr writer,
3347 const xmlChar * name, const xmlChar * content)
3349 int count;
3350 int sum;
3352 if (content == NULL)
3353 return -1;
3355 sum = 0;
3356 count = xmlTextWriterStartDTDElement(writer, name);
3357 if (count == -1)
3358 return -1;
3359 sum += count;
3361 count = xmlTextWriterWriteString(writer, content);
3362 if (count == -1)
3363 return -1;
3364 sum += count;
3366 count = xmlTextWriterEndDTDElement(writer);
3367 if (count == -1)
3368 return -1;
3369 sum += count;
3371 return sum;
3375 * xmlTextWriterStartDTDAttlist:
3376 * @writer: the xmlTextWriterPtr
3377 * @name: the name of the DTD ATTLIST
3379 * Start an xml DTD ATTLIST.
3381 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3384 xmlTextWriterStartDTDAttlist(xmlTextWriterPtr writer, const xmlChar * name)
3386 int count;
3387 int sum;
3388 xmlLinkPtr lk;
3389 xmlTextWriterStackEntry *p;
3391 if (writer == NULL || name == NULL || *name == '\0')
3392 return -1;
3394 sum = 0;
3395 lk = xmlListFront(writer->nodes);
3396 if (lk == 0) {
3397 return -1;
3400 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3401 if (p != 0) {
3402 switch (p->state) {
3403 case XML_TEXTWRITER_DTD:
3404 count = xmlOutputBufferWriteString(writer->out, " [");
3405 if (count < 0)
3406 return -1;
3407 sum += count;
3408 if (writer->indent) {
3409 count = xmlOutputBufferWriteString(writer->out, "\n");
3410 if (count < 0)
3411 return -1;
3412 sum += count;
3414 p->state = XML_TEXTWRITER_DTD_TEXT;
3415 /* fallthrough */
3416 case XML_TEXTWRITER_DTD_TEXT:
3417 case XML_TEXTWRITER_NONE:
3418 break;
3419 default:
3420 return -1;
3424 p = (xmlTextWriterStackEntry *)
3425 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3426 if (p == 0) {
3427 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
3428 "xmlTextWriterStartDTDAttlist : out of memory!\n");
3429 return -1;
3432 p->name = xmlStrdup(name);
3433 if (p->name == 0) {
3434 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
3435 "xmlTextWriterStartDTDAttlist : out of memory!\n");
3436 xmlFree(p);
3437 return -1;
3439 p->state = XML_TEXTWRITER_DTD_ATTL;
3441 xmlListPushFront(writer->nodes, p);
3443 if (writer->indent) {
3444 count = xmlTextWriterWriteIndent(writer);
3445 if (count < 0)
3446 return -1;
3447 sum += count;
3450 count = xmlOutputBufferWriteString(writer->out, "<!ATTLIST ");
3451 if (count < 0)
3452 return -1;
3453 sum += count;
3454 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
3455 if (count < 0)
3456 return -1;
3457 sum += count;
3459 return sum;
3463 * xmlTextWriterEndDTDAttlist:
3464 * @writer: the xmlTextWriterPtr
3466 * End an xml DTD attribute list.
3468 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3471 xmlTextWriterEndDTDAttlist(xmlTextWriterPtr writer)
3473 int count;
3474 int sum;
3475 xmlLinkPtr lk;
3476 xmlTextWriterStackEntry *p;
3478 if (writer == NULL)
3479 return -1;
3481 sum = 0;
3482 lk = xmlListFront(writer->nodes);
3483 if (lk == 0)
3484 return -1;
3486 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3487 if (p == 0)
3488 return -1;
3490 switch (p->state) {
3491 case XML_TEXTWRITER_DTD_ATTL:
3492 case XML_TEXTWRITER_DTD_ATTL_TEXT:
3493 count = xmlOutputBufferWriteString(writer->out, ">");
3494 if (count < 0)
3495 return -1;
3496 sum += count;
3497 break;
3498 default:
3499 return -1;
3502 if (writer->indent) {
3503 count = xmlOutputBufferWriteString(writer->out, "\n");
3504 if (count < 0)
3505 return -1;
3506 sum += count;
3509 xmlListPopFront(writer->nodes);
3510 return sum;
3514 * xmlTextWriterWriteFormatDTDAttlist:
3515 * @writer: the xmlTextWriterPtr
3516 * @name: the name of the DTD ATTLIST
3517 * @format: format string (see printf)
3518 * @...: extra parameters for the format
3520 * Write a formatted DTD ATTLIST.
3522 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3524 int XMLCDECL
3525 xmlTextWriterWriteFormatDTDAttlist(xmlTextWriterPtr writer,
3526 const xmlChar * name,
3527 const char *format, ...)
3529 int rc;
3530 va_list ap;
3532 va_start(ap, format);
3534 rc = xmlTextWriterWriteVFormatDTDAttlist(writer, name, format, ap);
3536 va_end(ap);
3537 return rc;
3541 * xmlTextWriterWriteVFormatDTDAttlist:
3542 * @writer: the xmlTextWriterPtr
3543 * @name: the name of the DTD ATTLIST
3544 * @format: format string (see printf)
3545 * @argptr: pointer to the first member of the variable argument list.
3547 * Write a formatted DTD ATTLIST.
3549 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3552 xmlTextWriterWriteVFormatDTDAttlist(xmlTextWriterPtr writer,
3553 const xmlChar * name,
3554 const char *format, va_list argptr)
3556 int rc;
3557 xmlChar *buf;
3559 if (writer == NULL)
3560 return -1;
3562 buf = xmlTextWriterVSprintf(format, argptr);
3563 if (buf == NULL)
3564 return -1;
3566 rc = xmlTextWriterWriteDTDAttlist(writer, name, buf);
3568 xmlFree(buf);
3569 return rc;
3573 * xmlTextWriterWriteDTDAttlist:
3574 * @writer: the xmlTextWriterPtr
3575 * @name: the name of the DTD ATTLIST
3576 * @content: content of the ATTLIST
3578 * Write a DTD ATTLIST.
3580 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3583 xmlTextWriterWriteDTDAttlist(xmlTextWriterPtr writer,
3584 const xmlChar * name, const xmlChar * content)
3586 int count;
3587 int sum;
3589 if (content == NULL)
3590 return -1;
3592 sum = 0;
3593 count = xmlTextWriterStartDTDAttlist(writer, name);
3594 if (count == -1)
3595 return -1;
3596 sum += count;
3598 count = xmlTextWriterWriteString(writer, content);
3599 if (count == -1)
3600 return -1;
3601 sum += count;
3603 count = xmlTextWriterEndDTDAttlist(writer);
3604 if (count == -1)
3605 return -1;
3606 sum += count;
3608 return sum;
3612 * xmlTextWriterStartDTDEntity:
3613 * @writer: the xmlTextWriterPtr
3614 * @pe: TRUE if this is a parameter entity, FALSE if not
3615 * @name: the name of the DTD ATTLIST
3617 * Start an xml DTD ATTLIST.
3619 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3622 xmlTextWriterStartDTDEntity(xmlTextWriterPtr writer,
3623 int pe, const xmlChar * name)
3625 int count;
3626 int sum;
3627 xmlLinkPtr lk;
3628 xmlTextWriterStackEntry *p;
3630 if (writer == NULL || name == NULL || *name == '\0')
3631 return -1;
3633 sum = 0;
3634 lk = xmlListFront(writer->nodes);
3635 if (lk != 0) {
3637 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3638 if (p != 0) {
3639 switch (p->state) {
3640 case XML_TEXTWRITER_DTD:
3641 count = xmlOutputBufferWriteString(writer->out, " [");
3642 if (count < 0)
3643 return -1;
3644 sum += count;
3645 if (writer->indent) {
3646 count =
3647 xmlOutputBufferWriteString(writer->out, "\n");
3648 if (count < 0)
3649 return -1;
3650 sum += count;
3652 p->state = XML_TEXTWRITER_DTD_TEXT;
3653 /* fallthrough */
3654 case XML_TEXTWRITER_DTD_TEXT:
3655 case XML_TEXTWRITER_NONE:
3656 break;
3657 default:
3658 return -1;
3663 p = (xmlTextWriterStackEntry *)
3664 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3665 if (p == 0) {
3666 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
3667 "xmlTextWriterStartDTDElement : out of memory!\n");
3668 return -1;
3671 p->name = xmlStrdup(name);
3672 if (p->name == 0) {
3673 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
3674 "xmlTextWriterStartDTDElement : out of memory!\n");
3675 xmlFree(p);
3676 return -1;
3679 if (pe != 0)
3680 p->state = XML_TEXTWRITER_DTD_PENT;
3681 else
3682 p->state = XML_TEXTWRITER_DTD_ENTY;
3684 xmlListPushFront(writer->nodes, p);
3686 if (writer->indent) {
3687 count = xmlTextWriterWriteIndent(writer);
3688 if (count < 0)
3689 return -1;
3690 sum += count;
3693 count = xmlOutputBufferWriteString(writer->out, "<!ENTITY ");
3694 if (count < 0)
3695 return -1;
3696 sum += count;
3698 if (pe != 0) {
3699 count = xmlOutputBufferWriteString(writer->out, "% ");
3700 if (count < 0)
3701 return -1;
3702 sum += count;
3705 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
3706 if (count < 0)
3707 return -1;
3708 sum += count;
3710 return sum;
3714 * xmlTextWriterEndDTDEntity:
3715 * @writer: the xmlTextWriterPtr
3717 * End an xml DTD entity.
3719 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3722 xmlTextWriterEndDTDEntity(xmlTextWriterPtr writer)
3724 int count;
3725 int sum;
3726 xmlLinkPtr lk;
3727 xmlTextWriterStackEntry *p;
3729 if (writer == NULL)
3730 return -1;
3732 sum = 0;
3733 lk = xmlListFront(writer->nodes);
3734 if (lk == 0)
3735 return -1;
3737 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3738 if (p == 0)
3739 return -1;
3741 switch (p->state) {
3742 case XML_TEXTWRITER_DTD_ENTY_TEXT:
3743 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3744 if (count < 0)
3745 return -1;
3746 sum += count;
3747 case XML_TEXTWRITER_DTD_ENTY:
3748 case XML_TEXTWRITER_DTD_PENT:
3749 count = xmlOutputBufferWriteString(writer->out, ">");
3750 if (count < 0)
3751 return -1;
3752 sum += count;
3753 break;
3754 default:
3755 return -1;
3758 if (writer->indent) {
3759 count = xmlOutputBufferWriteString(writer->out, "\n");
3760 if (count < 0)
3761 return -1;
3762 sum += count;
3765 xmlListPopFront(writer->nodes);
3766 return sum;
3770 * xmlTextWriterWriteFormatDTDInternalEntity:
3771 * @writer: the xmlTextWriterPtr
3772 * @pe: TRUE if this is a parameter entity, FALSE if not
3773 * @name: the name of the DTD entity
3774 * @format: format string (see printf)
3775 * @...: extra parameters for the format
3777 * Write a formatted DTD internal entity.
3779 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3781 int XMLCDECL
3782 xmlTextWriterWriteFormatDTDInternalEntity(xmlTextWriterPtr writer,
3783 int pe,
3784 const xmlChar * name,
3785 const char *format, ...)
3787 int rc;
3788 va_list ap;
3790 va_start(ap, format);
3792 rc = xmlTextWriterWriteVFormatDTDInternalEntity(writer, pe, name,
3793 format, ap);
3795 va_end(ap);
3796 return rc;
3800 * xmlTextWriterWriteVFormatDTDInternalEntity:
3801 * @writer: the xmlTextWriterPtr
3802 * @pe: TRUE if this is a parameter entity, FALSE if not
3803 * @name: the name of the DTD entity
3804 * @format: format string (see printf)
3805 * @argptr: pointer to the first member of the variable argument list.
3807 * Write a formatted DTD internal entity.
3809 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3812 xmlTextWriterWriteVFormatDTDInternalEntity(xmlTextWriterPtr writer,
3813 int pe,
3814 const xmlChar * name,
3815 const char *format,
3816 va_list argptr)
3818 int rc;
3819 xmlChar *buf;
3821 if (writer == NULL)
3822 return -1;
3824 buf = xmlTextWriterVSprintf(format, argptr);
3825 if (buf == NULL)
3826 return -1;
3828 rc = xmlTextWriterWriteDTDInternalEntity(writer, pe, name, buf);
3830 xmlFree(buf);
3831 return rc;
3835 * xmlTextWriterWriteDTDEntity:
3836 * @writer: the xmlTextWriterPtr
3837 * @pe: TRUE if this is a parameter entity, FALSE if not
3838 * @name: the name of the DTD entity
3839 * @pubid: the public identifier, which is an alternative to the system identifier
3840 * @sysid: the system identifier, which is the URI of the DTD
3841 * @ndataid: the xml notation name.
3842 * @content: content of the entity
3844 * Write a DTD entity.
3846 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3849 xmlTextWriterWriteDTDEntity(xmlTextWriterPtr writer,
3850 int pe,
3851 const xmlChar * name,
3852 const xmlChar * pubid,
3853 const xmlChar * sysid,
3854 const xmlChar * ndataid,
3855 const xmlChar * content)
3857 if ((content == NULL) && (pubid == NULL) && (sysid == NULL))
3858 return -1;
3859 if ((pe != 0) && (ndataid != NULL))
3860 return -1;
3862 if ((pubid == NULL) && (sysid == NULL))
3863 return xmlTextWriterWriteDTDInternalEntity(writer, pe, name,
3864 content);
3866 return xmlTextWriterWriteDTDExternalEntity(writer, pe, name, pubid,
3867 sysid, ndataid);
3871 * xmlTextWriterWriteDTDInternalEntity:
3872 * @writer: the xmlTextWriterPtr
3873 * @pe: TRUE if this is a parameter entity, FALSE if not
3874 * @name: the name of the DTD entity
3875 * @content: content of the entity
3877 * Write a DTD internal entity.
3879 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3882 xmlTextWriterWriteDTDInternalEntity(xmlTextWriterPtr writer,
3883 int pe,
3884 const xmlChar * name,
3885 const xmlChar * content)
3887 int count;
3888 int sum;
3890 if ((name == NULL) || (*name == '\0') || (content == NULL))
3891 return -1;
3893 sum = 0;
3894 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3895 if (count == -1)
3896 return -1;
3897 sum += count;
3899 count = xmlTextWriterWriteString(writer, content);
3900 if (count == -1)
3901 return -1;
3902 sum += count;
3904 count = xmlTextWriterEndDTDEntity(writer);
3905 if (count == -1)
3906 return -1;
3907 sum += count;
3909 return sum;
3913 * xmlTextWriterWriteDTDExternalEntity:
3914 * @writer: the xmlTextWriterPtr
3915 * @pe: TRUE if this is a parameter entity, FALSE if not
3916 * @name: the name of the DTD entity
3917 * @pubid: the public identifier, which is an alternative to the system identifier
3918 * @sysid: the system identifier, which is the URI of the DTD
3919 * @ndataid: the xml notation name.
3921 * Write a DTD external entity. The entity must have been started with xmlTextWriterStartDTDEntity
3923 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3926 xmlTextWriterWriteDTDExternalEntity(xmlTextWriterPtr writer,
3927 int pe,
3928 const xmlChar * name,
3929 const xmlChar * pubid,
3930 const xmlChar * sysid,
3931 const xmlChar * ndataid)
3933 int count;
3934 int sum;
3936 if (((pubid == NULL) && (sysid == NULL)))
3937 return -1;
3938 if ((pe != 0) && (ndataid != NULL))
3939 return -1;
3941 sum = 0;
3942 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3943 if (count == -1)
3944 return -1;
3945 sum += count;
3947 count =
3948 xmlTextWriterWriteDTDExternalEntityContents(writer, pubid, sysid,
3949 ndataid);
3950 if (count < 0)
3951 return -1;
3952 sum += count;
3954 count = xmlTextWriterEndDTDEntity(writer);
3955 if (count == -1)
3956 return -1;
3957 sum += count;
3959 return sum;
3963 * xmlTextWriterWriteDTDExternalEntityContents:
3964 * @writer: the xmlTextWriterPtr
3965 * @pubid: the public identifier, which is an alternative to the system identifier
3966 * @sysid: the system identifier, which is the URI of the DTD
3967 * @ndataid: the xml notation name.
3969 * Write the contents of a DTD external entity.
3971 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3974 xmlTextWriterWriteDTDExternalEntityContents(xmlTextWriterPtr writer,
3975 const xmlChar * pubid,
3976 const xmlChar * sysid,
3977 const xmlChar * ndataid)
3979 int count;
3980 int sum;
3981 xmlLinkPtr lk;
3982 xmlTextWriterStackEntry *p;
3984 if (writer == NULL) {
3985 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
3986 "xmlTextWriterWriteDTDExternalEntityContents: xmlTextWriterPtr invalid!\n");
3987 return -1;
3990 sum = 0;
3991 lk = xmlListFront(writer->nodes);
3992 if (lk == 0) {
3993 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
3994 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
3995 return -1;
3998 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3999 if (p == 0)
4000 return -1;
4002 switch (p->state) {
4003 case XML_TEXTWRITER_DTD_ENTY:
4004 break;
4005 case XML_TEXTWRITER_DTD_PENT:
4006 if (ndataid != NULL) {
4007 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
4008 "xmlTextWriterWriteDTDExternalEntityContents: notation not allowed with parameter entities!\n");
4009 return -1;
4011 break;
4012 default:
4013 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
4014 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
4015 return -1;
4018 if (pubid != 0) {
4019 if (sysid == 0) {
4020 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
4021 "xmlTextWriterWriteDTDExternalEntityContents: system identifier needed!\n");
4022 return -1;
4025 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
4026 if (count < 0)
4027 return -1;
4028 sum += count;
4030 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4031 if (count < 0)
4032 return -1;
4033 sum += count;
4035 count =
4036 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
4037 if (count < 0)
4038 return -1;
4039 sum += count;
4041 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4042 if (count < 0)
4043 return -1;
4044 sum += count;
4047 if (sysid != 0) {
4048 if (pubid == 0) {
4049 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
4050 if (count < 0)
4051 return -1;
4052 sum += count;
4055 count = xmlOutputBufferWriteString(writer->out, " ");
4056 if (count < 0)
4057 return -1;
4058 sum += count;
4060 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4061 if (count < 0)
4062 return -1;
4063 sum += count;
4065 count =
4066 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
4067 if (count < 0)
4068 return -1;
4069 sum += count;
4071 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4072 if (count < 0)
4073 return -1;
4074 sum += count;
4077 if (ndataid != NULL) {
4078 count = xmlOutputBufferWriteString(writer->out, " NDATA ");
4079 if (count < 0)
4080 return -1;
4081 sum += count;
4083 count =
4084 xmlOutputBufferWriteString(writer->out,
4085 (const char *) ndataid);
4086 if (count < 0)
4087 return -1;
4088 sum += count;
4091 return sum;
4095 * xmlTextWriterWriteDTDNotation:
4096 * @writer: the xmlTextWriterPtr
4097 * @name: the name of the xml notation
4098 * @pubid: the public identifier, which is an alternative to the system identifier
4099 * @sysid: the system identifier, which is the URI of the DTD
4101 * Write a DTD entity.
4103 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
4106 xmlTextWriterWriteDTDNotation(xmlTextWriterPtr writer,
4107 const xmlChar * name,
4108 const xmlChar * pubid, const xmlChar * sysid)
4110 int count;
4111 int sum;
4112 xmlLinkPtr lk;
4113 xmlTextWriterStackEntry *p;
4115 if (writer == NULL || name == NULL || *name == '\0')
4116 return -1;
4118 sum = 0;
4119 lk = xmlListFront(writer->nodes);
4120 if (lk == 0) {
4121 return -1;
4124 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
4125 if (p != 0) {
4126 switch (p->state) {
4127 case XML_TEXTWRITER_DTD:
4128 count = xmlOutputBufferWriteString(writer->out, " [");
4129 if (count < 0)
4130 return -1;
4131 sum += count;
4132 if (writer->indent) {
4133 count = xmlOutputBufferWriteString(writer->out, "\n");
4134 if (count < 0)
4135 return -1;
4136 sum += count;
4138 p->state = XML_TEXTWRITER_DTD_TEXT;
4139 /* fallthrough */
4140 case XML_TEXTWRITER_DTD_TEXT:
4141 break;
4142 default:
4143 return -1;
4147 if (writer->indent) {
4148 count = xmlTextWriterWriteIndent(writer);
4149 if (count < 0)
4150 return -1;
4151 sum += count;
4154 count = xmlOutputBufferWriteString(writer->out, "<!NOTATION ");
4155 if (count < 0)
4156 return -1;
4157 sum += count;
4158 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
4159 if (count < 0)
4160 return -1;
4161 sum += count;
4163 if (pubid != 0) {
4164 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
4165 if (count < 0)
4166 return -1;
4167 sum += count;
4168 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4169 if (count < 0)
4170 return -1;
4171 sum += count;
4172 count =
4173 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
4174 if (count < 0)
4175 return -1;
4176 sum += count;
4177 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4178 if (count < 0)
4179 return -1;
4180 sum += count;
4183 if (sysid != 0) {
4184 if (pubid == 0) {
4185 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
4186 if (count < 0)
4187 return -1;
4188 sum += count;
4190 count = xmlOutputBufferWriteString(writer->out, " ");
4191 if (count < 0)
4192 return -1;
4193 sum += count;
4194 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4195 if (count < 0)
4196 return -1;
4197 sum += count;
4198 count =
4199 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
4200 if (count < 0)
4201 return -1;
4202 sum += count;
4203 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4204 if (count < 0)
4205 return -1;
4206 sum += count;
4209 count = xmlOutputBufferWriteString(writer->out, ">");
4210 if (count < 0)
4211 return -1;
4212 sum += count;
4214 return sum;
4218 * xmlTextWriterFlush:
4219 * @writer: the xmlTextWriterPtr
4221 * Flush the output buffer.
4223 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
4226 xmlTextWriterFlush(xmlTextWriterPtr writer)
4228 int count;
4230 if (writer == NULL)
4231 return -1;
4233 if (writer->out == NULL)
4234 count = 0;
4235 else
4236 count = xmlOutputBufferFlush(writer->out);
4238 return count;
4242 * misc
4246 * xmlFreeTextWriterStackEntry:
4247 * @lk: the xmlLinkPtr
4249 * Free callback for the xmlList.
4251 static void
4252 xmlFreeTextWriterStackEntry(xmlLinkPtr lk)
4254 xmlTextWriterStackEntry *p;
4256 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
4257 if (p == 0)
4258 return;
4260 if (p->name != 0)
4261 xmlFree(p->name);
4262 xmlFree(p);
4266 * xmlCmpTextWriterStackEntry:
4267 * @data0: the first data
4268 * @data1: the second data
4270 * Compare callback for the xmlList.
4272 * Returns -1, 0, 1
4274 static int
4275 xmlCmpTextWriterStackEntry(const void *data0, const void *data1)
4277 xmlTextWriterStackEntry *p0;
4278 xmlTextWriterStackEntry *p1;
4280 if (data0 == data1)
4281 return 0;
4283 if (data0 == 0)
4284 return -1;
4286 if (data1 == 0)
4287 return 1;
4289 p0 = (xmlTextWriterStackEntry *) data0;
4290 p1 = (xmlTextWriterStackEntry *) data1;
4292 return xmlStrcmp(p0->name, p1->name);
4296 * misc
4300 * xmlTextWriterOutputNSDecl:
4301 * @writer: the xmlTextWriterPtr
4303 * Output the current namespace declarations.
4305 static int
4306 xmlTextWriterOutputNSDecl(xmlTextWriterPtr writer)
4308 xmlLinkPtr lk;
4309 xmlTextWriterNsStackEntry *np;
4310 int count;
4311 int sum;
4313 sum = 0;
4314 while (!xmlListEmpty(writer->nsstack)) {
4315 xmlChar *namespaceURI = NULL;
4316 xmlChar *prefix = NULL;
4318 lk = xmlListFront(writer->nsstack);
4319 np = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
4321 if (np != 0) {
4322 namespaceURI = xmlStrdup(np->uri);
4323 prefix = xmlStrdup(np->prefix);
4326 xmlListPopFront(writer->nsstack);
4328 if (np != 0) {
4329 count = xmlTextWriterWriteAttribute(writer, prefix, namespaceURI);
4330 xmlFree(namespaceURI);
4331 xmlFree(prefix);
4333 if (count < 0) {
4334 xmlListDelete(writer->nsstack);
4335 writer->nsstack = NULL;
4336 return -1;
4338 sum += count;
4341 return sum;
4345 * xmlFreeTextWriterNsStackEntry:
4346 * @lk: the xmlLinkPtr
4348 * Free callback for the xmlList.
4350 static void
4351 xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk)
4353 xmlTextWriterNsStackEntry *p;
4355 p = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
4356 if (p == 0)
4357 return;
4359 if (p->prefix != 0)
4360 xmlFree(p->prefix);
4361 if (p->uri != 0)
4362 xmlFree(p->uri);
4364 xmlFree(p);
4368 * xmlCmpTextWriterNsStackEntry:
4369 * @data0: the first data
4370 * @data1: the second data
4372 * Compare callback for the xmlList.
4374 * Returns -1, 0, 1
4376 static int
4377 xmlCmpTextWriterNsStackEntry(const void *data0, const void *data1)
4379 xmlTextWriterNsStackEntry *p0;
4380 xmlTextWriterNsStackEntry *p1;
4381 int rc;
4383 if (data0 == data1)
4384 return 0;
4386 if (data0 == 0)
4387 return -1;
4389 if (data1 == 0)
4390 return 1;
4392 p0 = (xmlTextWriterNsStackEntry *) data0;
4393 p1 = (xmlTextWriterNsStackEntry *) data1;
4395 rc = xmlStrcmp(p0->prefix, p1->prefix);
4397 if ((rc != 0) || (p0->elem != p1->elem))
4398 rc = -1;
4400 return rc;
4404 * xmlTextWriterWriteDocCallback:
4405 * @context: the xmlBufferPtr
4406 * @str: the data to write
4407 * @len: the length of the data
4409 * Write callback for the xmlOutputBuffer with target xmlBuffer
4411 * Returns -1, 0, 1
4413 static int
4414 xmlTextWriterWriteDocCallback(void *context, const xmlChar * str, int len)
4416 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
4417 int rc;
4419 if ((rc = xmlParseChunk(ctxt, (const char *) str, len, 0)) != 0) {
4420 xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR,
4421 "xmlTextWriterWriteDocCallback : XML error %d !\n",
4422 rc);
4423 return -1;
4426 return len;
4430 * xmlTextWriterCloseDocCallback:
4431 * @context: the xmlBufferPtr
4433 * Close callback for the xmlOutputBuffer with target xmlBuffer
4435 * Returns -1, 0, 1
4437 static int
4438 xmlTextWriterCloseDocCallback(void *context)
4440 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
4441 int rc;
4443 if ((rc = xmlParseChunk(ctxt, NULL, 0, 1)) != 0) {
4444 xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR,
4445 "xmlTextWriterWriteDocCallback : XML error %d !\n",
4446 rc);
4447 return -1;
4450 return 0;
4454 * xmlTextWriterVSprintf:
4455 * @format: see printf
4456 * @argptr: pointer to the first member of the variable argument list.
4458 * Utility function for formatted output
4460 * Returns a new xmlChar buffer with the data or NULL on error. This buffer must be freed.
4462 static xmlChar *
4463 xmlTextWriterVSprintf(const char *format, va_list argptr)
4465 int size;
4466 int count;
4467 xmlChar *buf;
4468 va_list locarg;
4470 size = BUFSIZ;
4471 buf = (xmlChar *) xmlMalloc(size);
4472 if (buf == NULL) {
4473 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
4474 "xmlTextWriterVSprintf : out of memory!\n");
4475 return NULL;
4478 VA_COPY(locarg, argptr);
4479 while (((count = vsnprintf((char *) buf, size, format, locarg)) < 0)
4480 || (count == size - 1) || (count == size) || (count > size)) {
4481 va_end(locarg);
4482 xmlFree(buf);
4483 size += BUFSIZ;
4484 buf = (xmlChar *) xmlMalloc(size);
4485 if (buf == NULL) {
4486 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
4487 "xmlTextWriterVSprintf : out of memory!\n");
4488 return NULL;
4490 VA_COPY(locarg, argptr);
4492 va_end(locarg);
4494 return buf;
4498 * xmlTextWriterStartDocumentCallback:
4499 * @ctx: the user data (XML parser context)
4501 * called at the start of document processing.
4503 static void
4504 xmlTextWriterStartDocumentCallback(void *ctx)
4506 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
4507 xmlDocPtr doc;
4509 if (ctxt->html) {
4510 #ifdef LIBXML_HTML_ENABLED
4511 if (ctxt->myDoc == NULL)
4512 ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
4513 if (ctxt->myDoc == NULL) {
4514 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
4515 ctxt->sax->error(ctxt->userData,
4516 "SAX.startDocument(): out of memory\n");
4517 ctxt->errNo = XML_ERR_NO_MEMORY;
4518 ctxt->instate = XML_PARSER_EOF;
4519 ctxt->disableSAX = 1;
4520 return;
4522 #else
4523 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
4524 "libxml2 built without HTML support\n");
4525 ctxt->errNo = XML_ERR_INTERNAL_ERROR;
4526 ctxt->instate = XML_PARSER_EOF;
4527 ctxt->disableSAX = 1;
4528 return;
4529 #endif
4530 } else {
4531 doc = ctxt->myDoc;
4532 if (doc == NULL)
4533 doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
4534 if (doc != NULL) {
4535 if (doc->children == NULL) {
4536 if (ctxt->encoding != NULL)
4537 doc->encoding = xmlStrdup(ctxt->encoding);
4538 else
4539 doc->encoding = NULL;
4540 doc->standalone = ctxt->standalone;
4542 } else {
4543 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
4544 ctxt->sax->error(ctxt->userData,
4545 "SAX.startDocument(): out of memory\n");
4546 ctxt->errNo = XML_ERR_NO_MEMORY;
4547 ctxt->instate = XML_PARSER_EOF;
4548 ctxt->disableSAX = 1;
4549 return;
4552 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
4553 (ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
4554 ctxt->myDoc->URL =
4555 xmlCanonicPath((const xmlChar *) ctxt->input->filename);
4556 if (ctxt->myDoc->URL == NULL)
4557 ctxt->myDoc->URL =
4558 xmlStrdup((const xmlChar *) ctxt->input->filename);
4563 * xmlTextWriterSetIndent:
4564 * @writer: the xmlTextWriterPtr
4565 * @indent: do indentation?
4567 * Set indentation output. indent = 0 do not indentation. indent > 0 do indentation.
4569 * Returns -1 on error or 0 otherwise.
4572 xmlTextWriterSetIndent(xmlTextWriterPtr writer, int indent)
4574 if ((writer == NULL) || (indent < 0))
4575 return -1;
4577 writer->indent = indent;
4578 writer->doindent = 1;
4580 return 0;
4584 * xmlTextWriterSetIndentString:
4585 * @writer: the xmlTextWriterPtr
4586 * @str: the xmlChar string
4588 * Set string indentation.
4590 * Returns -1 on error or 0 otherwise.
4593 xmlTextWriterSetIndentString(xmlTextWriterPtr writer, const xmlChar * str)
4595 if ((writer == NULL) || (!str))
4596 return -1;
4598 if (writer->ichar != NULL)
4599 xmlFree(writer->ichar);
4600 writer->ichar = xmlStrdup(str);
4602 if (!writer->ichar)
4603 return -1;
4604 else
4605 return 0;
4609 * xmlTextWriterWriteIndent:
4610 * @writer: the xmlTextWriterPtr
4612 * Write indent string.
4614 * Returns -1 on error or the number of strings written.
4616 static int
4617 xmlTextWriterWriteIndent(xmlTextWriterPtr writer)
4619 int lksize;
4620 int i;
4621 int ret;
4623 lksize = xmlListSize(writer->nodes);
4624 if (lksize < 1)
4625 return (-1); /* list is empty */
4626 for (i = 0; i < (lksize - 1); i++) {
4627 ret = xmlOutputBufferWriteString(writer->out,
4628 (const char *) writer->ichar);
4629 if (ret == -1)
4630 return (-1);
4633 return (lksize - 1);
4637 * xmlTextWriterHandleStateDependencies:
4638 * @writer: the xmlTextWriterPtr
4639 * @p: the xmlTextWriterStackEntry
4641 * Write state dependent strings.
4643 * Returns -1 on error or the number of characters written.
4645 static int
4646 xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer,
4647 xmlTextWriterStackEntry * p)
4649 int count;
4650 int sum;
4651 char extra[3];
4653 if (writer == NULL)
4654 return -1;
4656 if (p == NULL)
4657 return 0;
4659 sum = 0;
4660 extra[0] = extra[1] = extra[2] = '\0';
4661 if (p != 0) {
4662 sum = 0;
4663 switch (p->state) {
4664 case XML_TEXTWRITER_NAME:
4665 /* Output namespace declarations */
4666 count = xmlTextWriterOutputNSDecl(writer);
4667 if (count < 0)
4668 return -1;
4669 sum += count;
4670 extra[0] = '>';
4671 p->state = XML_TEXTWRITER_TEXT;
4672 break;
4673 case XML_TEXTWRITER_PI:
4674 extra[0] = ' ';
4675 p->state = XML_TEXTWRITER_PI_TEXT;
4676 break;
4677 case XML_TEXTWRITER_DTD:
4678 extra[0] = ' ';
4679 extra[1] = '[';
4680 p->state = XML_TEXTWRITER_DTD_TEXT;
4681 break;
4682 case XML_TEXTWRITER_DTD_ELEM:
4683 extra[0] = ' ';
4684 p->state = XML_TEXTWRITER_DTD_ELEM_TEXT;
4685 break;
4686 case XML_TEXTWRITER_DTD_ATTL:
4687 extra[0] = ' ';
4688 p->state = XML_TEXTWRITER_DTD_ATTL_TEXT;
4689 break;
4690 case XML_TEXTWRITER_DTD_ENTY:
4691 case XML_TEXTWRITER_DTD_PENT:
4692 extra[0] = ' ';
4693 extra[1] = writer->qchar;
4694 p->state = XML_TEXTWRITER_DTD_ENTY_TEXT;
4695 break;
4696 default:
4697 break;
4701 if (*extra != '\0') {
4702 count = xmlOutputBufferWriteString(writer->out, extra);
4703 if (count < 0)
4704 return -1;
4705 sum += count;
4708 return sum;
4711 #define bottom_xmlwriter
4712 #include "elfgcchack.h"
4713 #endif